/* * Copyright (c) MuleSoft, Inc. All rights reserved. http://www.mulesoft.com * The software in this package is published under the terms of the CPAL v1.0 * license, a copy of which has been included with this distribution in the * LICENSE.txt file. */ package org.mule.runtime.core.api; import org.mule.runtime.api.exception.MuleException; import org.mule.runtime.api.message.Error; import org.mule.runtime.api.message.Message; import org.mule.runtime.api.metadata.DataType; import org.mule.runtime.api.metadata.TypedValue; import org.mule.runtime.core.api.connector.ReplyToHandler; import org.mule.runtime.core.api.construct.FlowConstruct; import org.mule.runtime.core.api.context.notification.FlowCallStack; import org.mule.runtime.core.api.security.SecurityContext; import org.mule.runtime.core.api.source.MessageSource; import org.mule.runtime.core.api.transformer.TransformerException; import org.mule.runtime.core.config.DefaultMuleConfiguration; import org.mule.runtime.core.message.DefaultEventBuilder; import org.mule.runtime.core.message.GroupCorrelation; import org.mule.runtime.core.processor.chain.ModuleOperationMessageProcessorChainBuilder; import java.io.Serializable; import java.nio.charset.Charset; import java.util.Map; import java.util.NoSuchElementException; import java.util.Optional; import java.util.Set; /** * Represents any data event occurring in the Mule environment. All data sent or received within the mule environment will be * passed between components as an Event. * <p> * Holds a Message payload and provides helper methods for obtaining the data in a format that the receiving Mule component * understands. The event can also maintain any number of properties that can be set and retrieved by Mule components. * * @see Message */ public interface Event extends Serializable { class CurrentEventHolder { private static final ThreadLocal<Event> currentEvent = new ThreadLocal<>(); } /** * @return the context applicable to all events created from the same root {@link Event} from a {@link MessageSource}. */ EventContext getContext(); /** * Returns the correlation metadata of this message. See {@link GroupCorrelation}. * * @return the correlation metadata of this message. */ GroupCorrelation getGroupCorrelation(); /** * The returned value will depend on the {@link MessageSource} that created this event, and the flow that is executing the * event. * * @return the correlation id to use for this event. */ String getCorrelationId(); /** * Returns the variable registered under the given {@code key} * * @param key the name or key of the variable. This must be non-null. * @param <T> the type of the variable value. * @return a {@link TypedValue} containing the variable's value and {@link DataType} * @throws java.util.NoSuchElementException if the flow variable does not exist. */ <T> TypedValue<T> getVariable(String key); /** * Returns an immutable {@link Set} of variable names. * * @return the set of names */ Set<String> getVariableNames(); /** * Returns the complete set of properties in the current event * * @return a {@link Map} containing the properties' name as key and the {@link TypedValue} as value */ Map<String, TypedValue<Object>> getProperties(); /** * Returns the complete set of parameters in the current event * * @return a {@link Map} containing the parameters' name as key and the {@link TypedValue} as value */ Map<String, TypedValue<Object>> getParameters(); /** * Returns the message payload for this event * * @return the message payload for this event */ Message getMessage(); /** * When a mule component throws an error then an {@code Error} object gets generated with all the data associated to the error. * * This field will only contain a value within the error handler defined to handle errors. After the error handler is executed * the event error field will be cleared. If another flow is called from within the error handler the flow will still have * access to the error field. * * To avoid losing the error field after the error handler the user can define a variable pointing to the error field. * * @return an optional of the error associated with the event. Will be empty if there's no error associated with the event. */ Optional<Error> getError(); /** * Returns the contents of the message as a byte array. * * @param muleContext the Mule node. * @return the contents of the message as a byte array * @throws MuleException if the message cannot be converted into an array of bytes * @deprecated TODO MULE-10013 Move message serialization logic from within the message to an external service */ @Deprecated byte[] getMessageAsBytes(MuleContext muleContext) throws MuleException; /** * Transforms the message into the requested format. The transformer used is the one configured on the endpoint through which * this event was received. * * @param outputType The requested output type. * @param muleContext the Mule node. * @return the message transformed into it's recognized or expected format. * @throws TransformerException if a failure occurs in the transformer * @see org.mule.runtime.core.api.transformer.Transformer if the transform fails or the outputtype is null * @deprecated TODO MULE-10013 Move message serialization logic from within the message to an external service */ @Deprecated <T> T transformMessage(Class<T> outputType, MuleContext muleContext) throws TransformerException; /** * Transforms the message into the requested format. The transformer used is the one configured on the endpoint through which * this event was received. * * @param outputType The requested output type. * @param muleContext the Mule node. * @return the message transformed into it's recognized or expected format. * @throws TransformerException if a failure occurs in the transformer * @see org.mule.runtime.core.api.transformer.Transformer if the transform fails or the outputtype is null * @deprecated TODO MULE-10013 Move message serialization logic from within the message to an external service */ @Deprecated Object transformMessage(DataType outputType, MuleContext muleContext) throws TransformerException; /** * Returns the message transformed into it's recognized or expected format and then into a String. The transformer used is the * one configured on the endpoint through which this event was received. If necessary this will use the encoding set on the * event. * * @param muleContext the Mule node. * @return the message transformed into it's recognized or expected format as a Strings. * @throws TransformerException if a failure occurs in the transformer * @see org.mule.runtime.core.api.transformer.Transformer * @deprecated TODO MULE-10013 Move message serialization logic from within the message to an external service */ @Deprecated String transformMessageToString(MuleContext muleContext) throws TransformerException; /** * Returns the message contents as a string If necessary this will use the encoding set on the event * * @param muleContext the Mule node. * @return the message contents as a string * @throws MuleException if the message cannot be converted into a string * @deprecated TODO MULE-10013 Move message serialization logic from within the message to an external service */ @Deprecated String getMessageAsString(MuleContext muleContext) throws MuleException; /** * Returns the message contents as a string * * @param encoding the encoding to use when converting the message to string * @param muleContext the Mule node. * @return the message contents as a string * @throws MuleException if the message cannot be converted into a string * @deprecated TODO MULE-10013 Move message serialization logic from within the message to an external service */ @Deprecated String getMessageAsString(Charset encoding, MuleContext muleContext) throws MuleException; /** * Retrieves the service session for the current event * * @return the service session for the event * @deprecated Transport infrastructure is deprecated. */ @Deprecated MuleSession getSession(); /** * Retrieves the service for the current event * * @return the service for the event * @deprecated TODO MULE-10013 remove this */ @Deprecated FlowConstruct getFlowConstruct(); /** * Returns the muleContext for the Mule node that this event was received in * * @return the muleContext for the Mule node that this event was received in * @deprecated TODO MULE-10013 remove this */ @Deprecated MuleContext getMuleContext(); /** * Return the replyToHandler (if any) that will be used to perform async reply * * @deprecated TODO MULE-10739 Move ReplyToHandler to compatibility module. */ @Deprecated ReplyToHandler getReplyToHandler(); /** * Return the destination (if any) that will be passed to the reply-to handler. * * @deprecated TODO MULE-10739 Move ReplyToHandler to compatibility module. */ @Deprecated Object getReplyToDestination(); /** * Indicates if notifications should be fired when processing this message. * * @return true if notifications are enabled, false otherwise */ boolean isNotificationsEnabled(); /** * Events have a stack of executed flows (same as a call stack), so that at any given instant an application developer can * determine where this event came from. * <p> * This will only be enabled if {@link DefaultMuleConfiguration#isFlowTrace()} is {@code true}. If {@code false}, the stack will * always be empty. * * @return the flow stack associated to this event. * * @since 3.8.0 */ FlowCallStack getFlowCallStack(); /** * The security context for this session. If not null outbound, inbound and/or method invocations will be authenticated using * this context * * @return the context for this session or null if the request is not secure. */ SecurityContext getSecurityContext(); /** * @return the correlation id to use for this event. * @deprecated TODO MULE-10706 Mule 4: remove this */ @Deprecated String getLegacyCorrelationId(); /** * Create new {@link Builder}. * * @param context the context to create event instance with. * @return new builder instance. */ static Builder builder(EventContext context) { return new DefaultEventBuilder(context); } /** * Create new {@link Builder} based on an existing {@link Event} instance. The existing {@link EventContext} is conserved. * * @param event existing event to use as a template to create builder instance * @return new builder instance. */ static Builder builder(Event event) { return new DefaultEventBuilder(event); } /** * Create new {@link Builder} based on an existing {@link Event} instance and and {@link EventContext}. A new * {@link EventContext} is used instead of the existing instance referenced by the existing {@link Event}. This builder should * only be used in some specific scenarios like {@code flow-ref} where a new Flow executing the same {@link Event} needs a new * context. * * @param event existing event to use as a template to create builder instance * @param context the context to create event instance with. * @return new builder instance. */ static Builder builder(EventContext context, Event event) { return new DefaultEventBuilder(context, event); } interface Builder { /** * Set the {@link Message} to construct {@link Event} with. * * @param message the message instance. * @return the builder instance */ Builder message(Message message); /** * Set a map of variables. Any existing variables added to the builder will be removed. * * @param variables variables to be set. * @return the builder instance */ Builder variables(Map<String, Object> variables); /** * Add a variable. * * @param key the key of the variable to add. * @param value the value of the variable to add. {@code null} values are supported. * @return the builder instance. */ Builder addVariable(String key, Object value); /** * Add a variable. * * @param key the key of the variable to add. * @param value the value of the variable to add. {@code null} values are supported. * @param mediaType additional metadata about the {@code value} type. * @return the builder instance */ Builder addVariable(String key, Object value, DataType mediaType); /** * Remove a variable. * * @param key the variable key. * @return the builder instance */ Builder removeVariable(String key); /** * Set a map of properties to be consumed within a {@link ModuleOperationMessageProcessorChainBuilder.ModuleOperationProcessorChain}. * <p/> * For every module's <operation/> being consumed in a Mule Application, when being macro expanded, these properties will be * feed to it in a new and isolated {@link Event}, so that we can guarantee that for each invocation there's a real * variable scoping for them. * * @param properties properties to be set. * @return the builder instance * @see #parameters(Map) */ Builder properties(Map<String, Object> properties); /** * Set a map of parameters to be consumed within a {@link ModuleOperationMessageProcessorChainBuilder.ModuleOperationProcessorChain}. * <p/> * For every module's <operation/> being consumed in a Mule Application, when being macro expanded, these parameters will be * feed to it in a new and isolated {@link Event}, so that we can guarantee that for each invocation there's a real * variable scoping for them. * * @param parameters parameters to be set. * @return the builder instance * @see #properties(Map) */ Builder parameters(Map<String, Object> parameters); /** * Set correlationId overriding the correlationId from {@link EventContext#getCorrelationId()} that came from the source * system or that was configured in the connector source. This is only used to support transports and should not be used * otherwise. * * @param correlationId to override existing correlationId * @return the builder instance * @deprecated Transport infrastructure is deprecated. */ @Deprecated Builder correlationId(String correlationId); /** * Sets the group correlation information to the produced event. * * @param groupCorrelation the object containing the group correlation information to set on the produced event * @return the builder instance */ Builder groupCorrelation(GroupCorrelation groupCorrelation); /** * Sets an error related to the produced event. * * @param error the error associated with the produced event * @return the builder instance */ Builder error(Error error); /** * * @param replyToHandler * @return the builder instance * @deprecated TODO MULE-10739 Move ReplyToHandler to compatibility module. */ @Deprecated Builder replyToHandler(ReplyToHandler replyToHandler); /** * * @param replyToDestination * @return the builder instance * @deprecated TODO MULE-10739 Move ReplyToHandler to compatibility module. */ @Deprecated Builder replyToDestination(Object replyToDestination); /** * * @param flow * @return the builder instance * @deprecated TODO MULE-10013 remove this */ @Deprecated Builder flow(FlowConstruct flow); /** * Disables the firing of notifications when processing the produced event. * * @deprecated Transport infrastructure is deprecated. */ @Deprecated Builder disableNotifications(); /** * @param session * @return the builder instance * @deprecated Transport infrastructure is deprecated. */ @Deprecated Builder session(MuleSession session); /** * Build a new {@link Event} based on the state configured in the {@link Builder}. * * @return new {@link Event} instance. */ Event build(); } /** * Helper method to get the value of a given variable in a null-safe manner such that {@code null} is returned for non-existent * variables rather than a {@link NoSuchElementException} exception being thrown. * * @param key the key of the variable to retrieve. * @param event the event from which to retrieve a variable with the given key. * @param <T> the variable type * @return the value of the variables if it exists otherwise {@code null}. * @see Event#getVariable(String) */ static <T> T getVariableValueOrNull(String key, Event event) { if (event.getVariableNames().contains(key)) { return (T) event.getVariable(key).getValue(); } else { return null; } } /** * Return the event associated with the currently executing thread. * * @return event for currently executing thread. */ static Event getCurrentEvent() { return CurrentEventHolder.currentEvent.get(); } /** * Set the event to be associated with the currently executing thread. * * @param event event for currently executing thread. */ static void setCurrentEvent(Event event) { CurrentEventHolder.currentEvent.set(event); } }