20 Creating Oracle Mediator Routing Rules

This chapter describes Oracle Mediator routing rules and how to specify routing rules for a Mediator service component. Routing rules include transformation, filtering, validation, mapping, and routing logic.

This chapter includes the following sections:

The following chapter provide additional information about defining routing rules for specific scenarios:

20.1 Introduction to Routing Rules

Routing rules are mediation logic or execution logic that you define to achieve the requisite mediation. Mediator lets you route data between service consumers and service providers. As the data flows from service to service, it must be transformed. These two tasks, routing and transformation, are the core responsibilities of Mediator. You can use routing rules to specify how a message processed by a Mediator reaches its next destination. Routing rules specify where a Mediator sends the message, how it sends the message, and what changes should be made to the message structure before sending it to the target service.

A routing rule can be triggered either by a service operation or an event subscription. The service operation can be synchronous, asynchronous, or one-way. Routing rules can be of the following two types:

  • Static Routing Rules

    Static rules do not change depending on the invocation context and are applied consistently.

  • Dynamic Routing Rules

    Dynamic rules let you externalize the routing logic to an Oracle Rules Dictionary, which in turn enables dynamic modification of the routing logic.

For more information about creating routing rules, see Section 20.3.2, "How to Create Static Routing Rules" and Section 20.3.3, "How to Create Dynamic Routing Rules." For information about standard message exchange patterns and how they are handled by Mediator, see Chapter 24, "Understanding Message Exchange Patterns of an Oracle Mediator."

20.1.1 Static Routing Rules

A static routing rule is not expected to change depending on the invocation context. In this case, the routing can be an echo, a routing to another service, or a publishing of an event.

When you define static rules, you can specify the following types of information:

20.1.1.1 Types of Static Rules

You can define the following types of static rules for a Mediator:

  • Filter Expression

    You can define a filter expression that is applied to the message content (payload or headers). When you define a filter, the contents are analyzed before any service is invoked. For example, you might apply a filter expression that specifies that a service be invoked only if the message includes a customer ID, or if the value for that customer ID matches a certain pattern. For information about specifying filter expressions, see Section 20.3.2.8, "How to Specify an Expression for Filtering Messages".

  • Transformations

    Mediator can transform message data before forwarding the message to a service. You can define transformations to set a value on the target payload by mapping data or by assigning values.

    The XSLT Mapper lets you define transformations that apply to the whole message body to convert messages from one XML schema to another. The Assign Values function works on individual fields. Using this dialog, you can assign values from the message (for example, payload and headers), from a constant, or from various system properties, such as the properties of an adapter present in the data path. For information about defining transformations, see Section 20.3.2.9, "How to Create Transformations" and Section 20.3.2.10, "How to Assign Values".

  • Accessing Header Variables from Expressions

    Mediator can detect any SOAP headers that are used in building the expression for the current routing rule operation. For information about accessing headers, see Section 20.3.2.12, "How to Access Headers for Filters and Assignments" and Section 20.3.2.12.2, "Manual Expression Building for Accessing Properties for Filters and Assignments".

  • Schematron-Based Validations

    You can specify the Schematron files that Mediator should use to validate different parts of an inbound message. For information about performing Schematron-based validations, see Section 20.3.2.13, "How to Use Semantic Validation".

  • Java Callouts

    Custom Java class callouts let you use regular expressions with Java code, when regular expressions alone do not suffice. For information about using Java callouts, see Section 20.3.2.15, "How to Use Java Callouts".

  • User-defined Extension Functions

    These are your own set of functions that can be used by the XSLT Mapper. For information about using user-defined extension functions, see "To add user-defined extension functions:".

20.1.1.2 Static Routing Rule Components

Static routing rules define the following components:

  • Request Handler: Defines how Mediator handles incoming requests.

  • Reply Handler: Defines how the synchronous response from the called service is handled by Mediator.

  • Fault Handler: Defines how the named or declared faults from the called service are handled by Mediator.

  • Callback Handler: Defines how the asynchronous response and callback from the called service are handled by Mediator.

  • Timeout Handler in Callback: Defines how long Mediator waits for the asynchronous response and callback before performing timeout handling for the particular asynchronous request.

  • Event Publishing and Service Invocation: Calls other services or publishes an event depending on the configuration of the handlers.

20.1.2 Dynamic Routing Rules

A dynamic routing rule lets you externalize the routing logic to an Oracle Rules Dictionary, which in turn enables dynamic modification of the routing logic in a routing rule. This feature depends on a decision service and Oracle Rules to obtain the routing logic at runtime.

Dynamic routing separates the control logic, which determines the path taken by the process, from the execution of the process. In the dynamic routing scenario, a decision matrix determines the type of Level-2 service to be chosen for each routing. The factors that affect the decision on the type of Level-2 service are channel, customer type, and so on. The solution allows this decision matrix to be modified externally by business analysts without changing the routing. The decision matrix must be evaluated to determine the outbound service.

Dynamic routing rules are described in more detail in Section 20.3.3, "How to Create Dynamic Routing Rules."

20.1.3 Sequential and Parallel Execution

Routing rules can be executed sequentially or in parallel. This section describes the basic principles of both types of execution. If an operation or event has both sequential and parallel routing rules, first sequential routing rules are evaluated and actions are performed, and then parallel routings are queued for parallel execution.

Note:

If a Mediator service component with a request-response interface has only parallel routing rules, the Mediator service component does not send a response back to the caller. Though you can create this type of Mediator service component, the caller of the Mediator service component does not receive a response at runtime.

20.1.3.1 Basic Principles of Sequential Routing Rules

Mediator processes sequential routing rules based on the following principles:

  • Mediator evaluates routings and performs the resulting actions sequentially. Sequential routings are evaluated in the same thread and transaction as the caller.

  • Mediator always enlists itself into the global transaction propagated through the thread that is processing the incoming message. For example, if an inbound JCA adapter invokes a Mediator, the Mediator enlists itself with the transaction that the JCA adapter has initiated.

  • Mediator propagates the transaction through the same thread as the target components while executing the sequential routing rules.

  • Mediator never commits or rolls back transactions propagated by external entities.

  • Mediator manages the transaction only if the thread-invoking Mediator does not already have an active transaction. For example, if Mediator is invoked from inbound SOAP services, Mediator starts a transaction and commits or rolls back the transaction depending on success and failure.

20.1.3.2 Basic Principles of Parallel Routing Rules

Mediator processes routing rules in parallel based on the following principles:

  • Mediator queues and evaluates routings in parallel in different threads.

    The messages of each Mediator service component are retrieved in a weighted, round-robin fashion to ensure that all Mediator service components receive parallel processing cycles. This is true even if one or more Mediator service components produce a higher number of messages compared to other components. The weight used is the message priority set when designing a Mediator service component. Higher numbers of parallel processing cycles are allocated to the components that have higher message priority.

    You can set the Priority field in the Mediator Editor to indicate the priority of a Mediator service component. Priorities can range from zero to nine, with nine being the highest priority. The default priority is four.

    Note:

    The Priority property is applicable only to parallel routing rules.

  • Mediator initiates a new transaction for processing each parallel rule. The initiated transaction ends with an enqueue to the Mediator parallel message dehydration store.

    For example, if a Mediator service component has one parallel routing rule, one message is enqueued on the Mediator parallel message dehydration store. The parallel message dispatcher to the store then initiates a transaction, reads the message from the database store, and invokes the target component or service of this routing rule. The transaction initiated by the listener thread is a completely new transaction and is propagated to the target components.

    Note:

    Dehydrating of messages means storing the incoming messages in a database for parallel routing rules so they can be processed later by worker threads.

  • Mediator commits or rolls back transactions because it is the initiator of these transactions.

20.2 Resequencing Rules

Mediator includes a resequencer, which rearranges streams of related but out-of-sequence messages into their sequential order based on the type of resequencer used and the rules you define. When incoming messages arrive in a random order, the resequencer orders the messages based on sequential or chronological information, and then sends the messages to the target services in the correct order based on the resequencing configuration.

For more information about resequencing messages, see Chapter 23, "Resequencing in Oracle Mediator."

20.3 Defining Routing Rules

Routing rules can only be defined for a Mediator with a defined interface. For more information on how to define an interface, see Section 19.6.1, "How to Define an Interface for a Mediator."

20.3.1 How To Access the Routing Rules Section

You define the routing rules in the Routing Rules section of the Mediator Editor.

To access the routing rules section:

You can access the Routing Rules section of the Mediator Editor using one of the following methods:

  • From the SOA Composite Editor:

    1. Double-click the icon that represents the Mediator for which you want to specify the routing rules.

    2. If the Routing Rules section is not visible, click the Plus (+) icon next to Routing Rules.

  • From the Application Navigator:

    1. In the Application Navigator, expand the SOA project and then expand the SOA Content folder.

    2. In the SOA Content folder, double-click the name of the Mediator file in which you want to specify the routing rules.

      The Mediator file has an MPLAN extension.

    3. If the Routing Rules section is not visible, click the Plus (+) icon next to Routing Rules.

Figure 20-1 shows the Routing Rules section of the Mediator Editor.

Figure 20-1 Mediator Editor- Routing Rules Section

Description of Figure 20-1 follows
Description of "Figure 20-1 Mediator Editor- Routing Rules Section"

Figure 20-2 lists and describes the icons in the Routing Rules section.

Figure 20-2 Routing Rule Section Icons

Description of Figure 20-2 follows
Description of "Figure 20-2 Routing Rule Section Icons"

20.3.2 How to Create Static Routing Rules

  • The following topics provide information and instructions for defining static routing rules for Mediator, including specifying the services and events, defining handlers, transformations, expressions, filters, and so on.

20.3.2.1 How to Specify Mediator Services or Events

After creating a Mediator component, you associate it with inbound service operations or event subscriptions and with outbound targets. Targets are outbound service operations or event publishing. A target specifies the next service or event to which a Mediator sends messages and also specifies which service operation to invoke. You can specify a service or an event as a target type.

You can also echo source messages back to the initial caller after any transformation, validations, assignments, or sequencing operations are performed. An echo can only be specified if the Mediator component has a synchronous or asynchronous interface. Whether the echo is synchronous or asynchronous depends on the WSDL file of the caller. The echo option is only available for inbound service operations and is not available for event subscriptions.

The purpose of the echo option is to expose all the Mediator functionality as a callable service without having to route it to any other service. For example, you can call a Mediator to perform a transformation, a validation, or an assignment, and then echo the Mediator back to your application without routing it anywhere else.

You can specify multiple routings for an inbound operation or event. Each routing is mapped to one target service invocation or event. Therefore, to specify multiple service invocations or raise multiple events, you must specify one routing rule for each target. For example, you can invoke an operation based on a message payload from the following operations defined in a service:

  • insert

  • update

  • updateid

  • delete

To do this action, you must create four routing rules, one for each operation. Later, when you specify a filter expression for each rule, you can specify which target and operation is applied to each message instance based on the message payload, as shown in Figure 20-3.

Figure 20-3 Multiple Routings for an Inbound Operation

Description of Figure 20-3 follows
Description of "Figure 20-3 Multiple Routings for an Inbound Operation"

To invoke a service: 

To perform this step, the target service must be defined in a WSDL document or a Java interface.

  1. In the Routing Rules section, click Add next to the operation for which you are defining routing rules, and then select static routing rule.

    The Target Type dialog appears, as shown in Figure 20-4.

    Figure 20-4 Target Type Dialog

    Description of Figure 20-4 follows
    Description of "Figure 20-4 Target Type Dialog"

  2. Click Service.

    The Target Services dialog appears, as shown in Figure 20-5.

    Figure 20-5 Target Services Dialog

    Description of Figure 20-5 follows
    Description of "Figure 20-5 Target Services Dialog"

  3. In the Target Services dialog, navigate to and then select an operation provided by a service.

    Note:

    You can select a service defined by a WSDL file or a Java interface. A service can consist of multiple operations, as shown in Figure 20-5.

  4. Click OK.

  5. If you selected a target service defined by a Java interface, the Interface Required dialog appears. Click Yes to create the required WSDL file, and then click OK on the confirmation dialog.

    A new Static Routing section appears where you can define the routing rule.

  6. Configure the routing rule as described the remaining sections of this chapter.

To trigger an event: 

  1. In the Routing Rules section, click Add next to the operation for which you are defining routing rules, and then select static routing rule.

    The Target Type dialog appears, as shown in Figure 20-4.

  2. Click Event.

    The Event Chooser dialog appears.

  3. To the right of the Event Definition field, click Search.

    The SOA Resource Browser dialog appears.

  4. Select an event (.edl) file and click OK.

    The Event field is populated with the events defined in the selected file, as shown in Figure 20-6.

    Figure 20-6 Event Chooser Dialog

    Description of Figure 20-6 follows
    Description of "Figure 20-6 Event Chooser Dialog"

    Note:

    Instead of browsing for an existing event definition file, you can create a new file by clicking Create new event definition (edl) file and completing the fields in the Create Event Definition File dialog.

  5. Select an event.

  6. Click OK.

    A new Static Routing section appears where you can define the routing rule.

  7. Configure the routing rule as described the remaining sections of this chapter.

To echo a service: 

  1. In the Routing Rules section, click Add next to the operation for which you are defining routing rules, and then select static routing rule.

    The Target Type dialog is displayed, as shown in Figure 20-7.

    Figure 20-7 Target Type Dialog

    Description of Figure 20-7 follows
    Description of "Figure 20-7 Target Type Dialog"

  2. Click Echo.

    Note:

    The Echo button only appears on the Target Type dialog if the interface is synchronous or asynchronous.

    Figure 20-8 shows a routing rule with a synchronous echo. An asynchronous echo has an icon with a dotted line on the return.

    Figure 20-8 Sample Mediator Supporting Echo Operation

    Description of Figure 20-8 follows
    Description of "Figure 20-8 Sample Mediator Supporting Echo Operation"

20.3.2.2 What You May Need to Know About Echoing a Service

The echo option has the following limitations:

  • Echoing a service is supported only with Mediator interfaces having the following types of WSDL files:

    • Request/reply

    • Request/reply/fault

    • Request/callback

    Note:

    The echo option is not available for Mediator interfaces having request/reply/fault/callback WSDL files or for one-way WSDL files.

  • The echo option is available for synchronous operations like request/reply and request/reply/fault.

    Note:

    The echo option is only available for synchronous operations when the routing rule is sequential because parallel routing rules are not supported for Mediators with synchronous operations.

  • For synchronous operations with a conditional filter, the echo option does not return a response to the caller when the filter condition is set to false. Instead, it returns a null response.

  • The echo option is available for asynchronous operations only if the Mediator interface has a callback operation. In this case, the echo is run on a separate thread.

    Note:

    The asynchronous echo option is available only when the routing rule is parallel. If you use the echo option, then sequential routing rules are not supported for Mediators with asynchronous operations.

20.3.2.3 How to Specify Sequential or Parallel Execution

A routing rule can be executed either in parallel or sequentially. To specify an execution type for a routing rule, select the Sequential or Parallel execution type in the Routing Rules section.

20.3.2.4 How to Configure Response Messages

In the Mediator routing rules, you can specify how to handle the response messages in synchronous and asynchronous interactions. For synchronous interactions, you can specify the transformations and assignments for the response and the fault message. You can forward the response and the fault message to another service or event, or you can send them back to the initial caller, if the initial caller is expecting responses and faults.

For asynchronous interactions, you can specify transformations and assignments, and a timeout period for receiving the response. The timeout period can be specified in seconds, hours, days, months, or years. By default, the timeout period is infinite. If a callback response does not come within the specified timeout period, a timeout response can be forwarded to another service, to another event, or back to the initial caller.

You cannot route a Mediator response to a two-way service. If you want to route a response to a two-way service, you should use a one-way Mediator between the first Mediator and the two-way service. The response should first be forwarded to the one-way Mediator, which in turn should call the two-way service.

Notes:

  • Zero is an unsupported value to be specified as a timeout period.

  • If the callback is received and processing of the callback fails, by default the timeout handler is invoked for processing the action specified in the timeout handler.

  • Typically, the caller receives the callback after waiting for 100 milliseconds. However, if you have a bridge Mediator with a sequential routing rule and a connection to a synchronous interface service, then due to the complex flow of the program with all sequential routing rules, the caller may take longer to get ready to receive the callback. You can work around this issue by changing the routing rule of the bridge Mediator to parallel.

To specify a timeout period for asynchronous processing: 

The following steps are performed in the Routing Rules section of the Mediator Editor.

  1. Next to the <<Target Operation>> field by the Timeout in field in the Callback section, click the Browse for target service operation icon.

    The Target Type dialog appears.

  2. Select Service, Event, or Initial Caller.

    If you selected Service or Event, the Target Service or the Event Chooser appears depending on your selection.

  3. Select an event or service.

  4. Click OK

  5. In the Timeout in field, enter the number of units for the timeout period, and then select the unit of time from the dropdown list.

    The timeout response is forwarded to the specified service or event.

Note:

If the number of routing rules is larger and the time taken to execute the routing rules exceeds the transaction timeout, you must set the transaction timeout to a value that is greater than the time taken to execute all the routing rules.

20.3.2.5 How to Handle Premature Callbacks

Callback messages might arrive before the initiating transaction is completed. In this case, correlation in Mediator fails. If you have an issue with premature callbacks, you can use the oracle.tip.mediator.callback.correlationWaitDuratino_in_seconds property to set a time period in seconds for which the callback thread waits before retrying the callback.

You define the property in the composite.xml file in the component element that defines the Mediator component. In the example shown below, the wait time before retrying is 15 seconds.

<component name="Mediator1">
    <implementation.mediator src="Mediator1.mplan"/>
    <property name="oracle.tip.mediator.callback.correlationWaitDuration_in_
    seconds">15</property> 
</component>

20.3.2.6 How to Handle Multiple Callbacks

A single Mediator cannot handle multiple callbacks. If you have a composite application with a Mediator that receives multiple callbacks, the behavior of the composite application is undetermined. For example, in the scenario shown in Figure 20-9, AsyncMediator forwards the callback response from AsyncEchoMediator1 and AsyncEchoMediator2 to FileInMediator. In such a flow, the AsyncMediator might return the callback from both AsyncEchoMediator1 and AsyncEchoMediator2, or from either one of them. The exact behavior is random and unpredictable.

Figure 20-9 Sample Mediator Handling Multiple Callback

Description of Figure 20-9 follows
Description of "Figure 20-9 Sample Mediator Handling Multiple Callback"

20.3.2.7 How to Handle Faults

If you create a new routing rule in which the target service operation has one or more faults, you still see a single fault routing section in the Mediator Editor. If the source Mediator service component supports one or more faults, then the fault is routed back to the caller by default. You can choose the source and target fault names to be routed. You can also use the service browser to route the fault to another target.

To define an additional fault routing: 

The following steps are performed in the Routing Rules section of the Mediator Editor.

  1. In the Faults section, click the Add another fault routing button shown in Figure 20-10.

    Figure 20-10 Adding a Second Fault

    Description of Figure 20-10 follows
    Description of "Figure 20-10 Adding a Second Fault"

    Another fault section appears in the routing rule box.

  2. Configure the target service, transformations, and assign values for the new fault.

    Figure 20-11 shows a second fault being routed to a file adapter service.

    Figure 20-11 Second Fault Added to Routing Rules

    Description of Figure 20-11 follows
    Description of "Figure 20-11 Second Fault Added to Routing Rules"

    Note:

    You can route the same fault to multiple targets using different transformations.

To remove a fault routing section: 

The following steps are performed in the Routing Rules section of the Mediator Editor.

  • Highlight the fault routing you want to remove by clicking in the target service field, and then click Delete the selected fault routing, as shown in Figure 20-12.

Figure 20-12 Deleting a Fault Routing

Description of Figure 20-12 follows
Description of "Figure 20-12 Deleting a Fault Routing"

20.3.2.8 How to Specify an Expression for Filtering Messages

The filter expression routing rule lets you filter messages based on their payload. If the filter expression for a given message instance evaluates to true, the message is delivered to the target service or event specified within the routing rule.

For example, you route your data to customers in two different countries, such as US and Canada, but you only want notices regarding the MOBILE product line to be sent to US customers and the LANDLINE product line to customers in Canada. To implement this routing, you must define a routing rule for each component and operation pair that sends messages to the target customers. In addition, you specify filter expressions for the routing rules that send messages to the customers in the US or Canada.

You can also define filter expression message properties or message headers.

Filter Expression Message Properties 

Two examples of filter expression message properties are shown in Example 20-1.

Example 20-1 Filter Expression Message Properties

$in.property.custom.Priority = '1'

$in.property.tracking.ecid = '2'

Filter Expression Message Headers 

Two examples of filter expression message headers are shown in Example 20-2.

Example 20-2 Filter Expression Message Headers

$in.header.wsse_Security/wsse:Security/Priority = '234'

$in.header.wsse_Security/wsse:Security/Priority = '234'

For the preceding filter expression message headers to work, you must add the attribute shown in Example 20-3 to the root element of the .mplan file.

Example 20-3 Attribute to Add

wsse = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-
 secext-1.0.xsd"

To specify an expression for filtering messages: 

You can use the Expression Builder to graphically create a filter expression. The Expression Builder dialog contains the components and controls that assist you in designing a filter expression.

  1. To the right of the Filter Expression field in the Routing Rules section, click the Invoke Expression Builder icon.

    The Expression Builder dialog appears, as shown in Figure 20-13.

    Figure 20-13 Expression Builder Dialog

    Description of Figure 20-13 follows
    Description of "Figure 20-13 Expression Builder Dialog"

  2. Double-click a value in the Variables field or the Functions palette to add the value to the Expression field. Using a combination of variable elements, functions, and manually entered text, you can build an expression by which you want message payloads to be filtered for a given routing rule.

    Table 20-1 describes each of the fields in the Expression Builder dialog:

    Table 20-1 Expression Builder Fields

    Field Description

    Expression

    This field contains the actual expression used to filter messages. You can enter the filter expression either manually or by using the Variable field and the Functions palette.

    Using the icons on the upper right side of this field, you can undo the last edit made, redo the last edit made, or clear the entire Expression field.

    Variables

    This field contains the message defined for a Mediator component. Oracle JDeveloper parses the Mediator WSDL file and presents the message definition in the Variables field. The input message is stored in the $in variable, and you can use the $in.properties to access the properties of an input message.

    If the input message consists of multiple parts, use $in.partname to access a part of an input message.

    Functions Palette

    This list provides a list of functions that you can include in an expression. When you select a function, a preview of how that function appears when added to the Expression field appears in the Content Preview field, and a description of the function appears in the Description field.

    Content Preview

    This field indicates how a value selected from the Variables field or Functions palette appears when it is inserted into the Expression field.

    Description

    This field describes the value selected from the Variables field or Functions Palette.


To specify a filter expression on a message payload: 

  1. To the right of the Filter Expression field in the Routing Rules section, click the Invoke Expression Builder icon.

    The Expression Builder dialog is displayed.

  2. In the Variables field, expand the message definition and select the message element on which you want to base the expression.

    For example, the CustomerId element is shown selected in Figure 20-14.

    Figure 20-14 Expression Builder Dialog – Variables Element Selected

    Description of Figure 20-14 follows
    Description of "Figure 20-14 Expression Builder Dialog – Variables Element Selected"

  3. Click Insert Into Expression.

    The expression is added in the Expression field, as shown in Figure 20-15.

    Figure 20-15 Expression Builder Dialog – Variables Element Inserted

    Description of Figure 20-15 follows
    Description of "Figure 20-15 Expression Builder Dialog – Variables Element Inserted"

  4. From the Functions list, select the function to apply to the message payload. For example, equals.

    Functions are grouped in categories that are listed when you click the down arrow in the Functions list. For example, if you click the down arrow and select Logical Functions, the list appears as shown in Figure 20-15.

  5. Click Insert Into Expression.

    The XPath expression for the selected function is inserted into the Expression field.

  6. Complete the expression.

    In this example, the Customer ID must equal1001 to evaluate to true, as shown in Figure 20-16.

    Figure 20-16 Sample Expression Builder Dialog – Value Entered

    Description of Figure 20-16 follows
    Description of "Figure 20-16 Sample Expression Builder Dialog – Value Entered"

  7. If there are any errors, you can edit the expression manually, or use the expression editing icons, which are summarized in Figure 20-17.

    Figure 20-17 Expression Editing Icons

    Description of Figure 20-17 follows
    Description of "Figure 20-17 Expression Editing Icons"

  8. Click OK.

    The expression is added to the Routing Rules section.

To modify or delete a filter expression, double-click the Add Filter Expression icon, and then modify or delete the expression in the Expression field of the Expression Builder.

20.3.2.9 How to Create Transformations

Oracle JDeveloper provides an XSLT Mapper that lets you specify a mapper file (XSL file) to transform data from one XML schema (expressed as an XSD file) to another. The XSLT Mapper enables data interchange among applications using different schemas. For example, you can map an incoming purchase order schema to an outgoing invoice schema. After you define an XSL file, you can reuse it in multiple routing rule specifications.

To create a transformation: 

  1. In the Routing Rules section, click the Select an existing mapper file or create a new one icon to the right of the Transform Using field.

    The Request Transformation Map dialog appears. You can select an existing XSL file or create a new XSL file with the XSLT Mapper to perform the required transformation.

  2. Do one of the following:

    • If the mapping file exists, select Use Existing Mapper File and then click Browse to find and select the mapper file to use.

    • To create a mapper file, select Create New Mapper File, and then enter the input information.

  3. Repeat the above steps for any synchronous reply, callback, response, or fault messages.

    In case of synchronous reply or fault message, the Reply Transformation Map dialog or the Fault Transformation Map dialog contains an Include Request in the Reply Payload option, as shown in Figure 20-18.

    Figure 20-18 Reply Transformation Map Dialog

    Description of Figure 20-18 follows
    Description of "Figure 20-18 Reply Transformation Map Dialog"

  4. To create an $initial variable that contains the original message of a synchronous interaction, select the Include Request in the Reply Payload option.

    The variable is created, as shown in Figure 20-19.

    Figure 20-19 Initial Variable in XSL File

    Description of Figure 20-19 follows
    Description of "Figure 20-19 Initial Variable in XSL File"

Note:

An initial message can also consist of multiple parts. Use $initial.partname to access a part of the initial message. If the parts of the inbound and outbound messages are identical, then no transformation is required for data interchange.

For information about the XSLT Mapper, see Chapter 40, "Creating Transformations with the XSLT Mapper."

To add user-defined extension functions: 

You can use the Expression Builder to include user-defined extension functions.

  1. Create an XPath function.

  2. Register the Jaxen XPath function with a Mediator service component in the xpath-function.xml file on the server.

  3. Start Oracle JDeveloper.

  4. Use the Expression Builder to customize the expression.

  5. Deploy the Oracle JDeveloper project to Oracle WebLogic Server.

  6. Copy the JAR file containing the user-defined extension functions to the $BEAHOME/user_projects/domains/soainfra/autodeploy/soa-infra/APP-INF/lib directory.

  7. Modify the .mplan file of the project as follows:

    • Add the function namespace you defined for the extension functions under the Mediator element.

    • Add the function names under the Expression element.

    This is shown in Figure 20-20.

    Figure 20-20 Project .mplan file – Modified to Use User-Defined Extension Functions

    Description of Figure 20-20 follows
    Description of "Figure 20-20 Project .mplan file – Modified to Use User-Defined Extension Functions"

  8. Invoke the test page with a suitable payload.

20.3.2.10 How to Assign Values

You can use the Assign Values field to propagate the headers, payload, and properties of a message from source to target. Figure 20-21 shows the Assign Values dialog that is displayed when you click the Assign Values icon in the Routing Rules section.

Figure 20-21 Assign Values Dialog

Description of Figure 20-21 follows
Description of "Figure 20-21 Assign Values Dialog"

To set the properties of the target message: 

  1. Click Add in the Assign Values dialog.

    The Assign Value dialog is displayed, as shown in Figure 20-22.

    Figure 20-22 Assign Value Dialog

    Description of Figure 20-22 follows
    Description of "Figure 20-22 Assign Value Dialog"

  2. In the From section, select any of the following options from the Type list:

    • Property: Select this option to assign a value of a property to the target message. The property list contains a list of predefined message properties. You can also enter any user-defined property name.

    • Expression: Select this option to assign a value of an expression to the target message. When you click the Invoke Expression Builder icon to the right of the Expression field, the Expression Builder dialog similar to the one shown in Figure 20-13 is displayed.

      For more information about the Expression Builder dialog, see Section 20.3.2.8, "How to Specify an Expression for Filtering Messages."

    • Constant: Select this option to assign a constant value to the target message.

  3. In the To section, select any of the following options:

    • Property: Select this option to copy the value to a message property. The Variable field of the Expression Builder dialog contains an $out variable that contains the output message. You can use $out.property to access properties of an output message.

    • Expression: Select this option to copy the value to an expression. When you click the Invoke Expression Builder icon to the right of the Expression field, the Expression Builder dialog is displayed. The Variable field of the Expression Builder dialog contains an $out variable that contains the output message. You can use $out.partname to access a complete output message or part of an output message.

    Figure 20-23 shows a sample Assign Value dialog in which a constant value is specified as an expression.

    Figure 20-23 Populated Assign Value Dialog

    Description of Figure 20-23 follows
    Description of "Figure 20-23 Populated Assign Value Dialog"

  4. Click OK in the Assign Value dialog.

  5. Click OK. The expression is added to Assign Values field of the Routing Rules section.

Notes:

  • When you assign values to a particular Mediator property during event publishing, the assigned value does not get propagated to the subscribing event.

    You can work around this issue by using transformations to include the property as part of the event body.

  • You cannot assign values to the jca.db.userName and jca.db.password properties on Oracle WebLogic Server because their data sources do not support setting the user name or password dynamically to the getConnection method.

Table 20-2 through Table 20-4 list the various possibilities of assignment on constants and properties, payloads, and headers of a message from source to target.

Table 20-2 Possibilities on Constants and Properties

Source Target Example

Property

Property

<copy expression="$in.property.jca.file.FileName" target="$out.property.jca.file.FileName"/>

Constant

Property

<copy value="ConstantNameAssigned.xml" target="$out.property.jca.file.FileName"/>


Table 20-3 Possibilities on Payload

Source Target Example

XPath Expression

Property

<copy expression="concat('ExprPropMed','-',oraext:generate-guid())" target="$out.property.jca.file.FileName" xmlns:oraext="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc"/>

XPath Expression (below part level)

Property

<copy expression="$in.body/imp1:request/ProductReq/Make" target="$out.property.jca.file.FileName" xmlns:imp1="http://xmlns.oracle.com/psft"/>

Property

XPath Expression (below part level)

<copy value="$in.property.jca.file.FileName" target="$out.request/inp1:request/ProductReq/Model" xmlns:inp1="http://xmlns.oracle.com/psft"/>

Constant

XPath Expression (below part level)

<copy value="ConstantModel" target="$out.request/inp1:request/ProductReq/Model" xmlns:inp1="http://xmlns.oracle.com/psft"/>

XPath Expression

XPath Expression

<copy expression="$in.body" target="$out.request"/>

XPath Expression (below part level)

XPath Expression (below part level)

<copy expression="$in.body/imp1:request/ProductReq/Make" target="$out.request/imp1:request/ProductReq/Model" xmlns:imp1="http://xmlns.oracle.com/psft"/>


Table 20-4 Possibilities on Header

Source Target Example

XPath Expression (below part level)

Property

<copy expression="$in.header.inp1_header/inp1:header/Name" target="$out.property.jca.file.FileName" xmlns:inp1="http://xmlns.oracle.com/psft"/>

Property

XPath Expression (below part level)

<copy value="$in.property.jca.file.FileName" target="$out.header.inp1_header/inp1:header/Name" xmlns:inp1="http://xmlns.oracle.com/psft"/>

Constant

XPath Expression (below part level)

<copy value="NewID.xml" target="$out.header.inp1_header/inp1:header/Id" xmlns:inp1="http://xmlns.oracle.com/psft"/>

Constant

XPath Expression (below part level)

<copy value="sampleusername" xmlns:wsse1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" target="$out.header.wsse1_Security/wsse1:Security/wsse1:UsernameToken/wsse1:Username"/>

XPath Expression

XPath Expression

<copy target="$out.header.inp1_header" expression="$in.header.inp1_header" xmlns:inp1="http://xmlns.oracle.com/psft"/>

XPath Expression (below part level)

XPath Expression (below part level)

<copy target="$out.header.inp1_header/inp1:header/Name" expression="$in.header.inp1_header/inp1:header/Id" xmlns:inp1="http://xmlns.oracle.com/psft"/>


20.3.2.11 What You May Need to Know About the Assign Activity

Note the following issues about the assign activity.

  • The assign activity is executed in the order that is present in the Mediator <copy> element.

  • A source XPath expression should always refer to a leaf node while the source is assigned to a target property. Otherwise, all the values of the child nodes in the source get concatenated and are assigned to the target property. Example 20-4 provides details.

    Example 20-4 XPath Expression Referring to a Leaf Node

    <copy target="$out.property.jca.file.FileName"
     expression="$in.body/imp1:request/ProductReq/Make"
     xmlns:imp1="http://xmlns.oracle.com/psft"/>
    

    Note:

    A leaf node is a node with no child nodes.

  • While assigning a constant or a property to a target XPath expression, the target XPath expression should always point to a leaf node. Otherwise, nonleaf nodes contain only a string value that may generate nonvalid XML according to the .xsd file. Example 20-5 provides details.

    Example 20-5 Target XPath Expression Pointing to a Leaf Node

    <copy target="$out.request/inp1:request/ProductReq/Make" value="NewMakeValue"
     xmlns:inp1="http://xmlns.oracle.com/psft"/>
    

    In this example, $out.request/inp1:request/ProductReq/Make refers to the leaf node.

  • If a transformation is available, then while assigning a source part to a target part, the target is overwritten because the assign activity occurs on top of the transformation. If the transformation is not available, then the assign activity creates the target. Example 20-6 provides details.

    Example 20-6 Transformation Availability and Assign Activity

    <copy target="$out.request" expression="$in.body"/>
    
    <copy target="$out.header.inp1_header" expression="$in.header.inp1_header"
      xmlns:inp1="http://xmlns.oracle.com/psft"/>
    
  • If one of the child nodes in the target payload has to be modified, then there are the following two use cases:

    • If a transformation is available, then directly assign a source expression to a target XPath expression that is pointing to that child node in the target. Example 20-7 provides details.

      Example 20-7 Direct Assignment of a Source Expression to a Target XPath Expression

      <copy value="ConstantModel"
      target="$out.request/inp1:request/ProductReq/Model"
       xmlns:inp1="http://xmlns.oracle.com/psft"/>
      
    • If a transformation is not available, then there are two steps involved. First, assign the source part to the target part, and then assign the source expression to a target XPath expression that is pointing to the child node in the target. Example 20-8 provides details.

      Example 20-8 Assignments if Transformations are Unavailable

      <copy target="$out.request" expression="$in.body"/> and <copy
       value="ConstantModel" target="$out.request/inp1:request/ProductReq/Model"
       xmlns:inp1="http://xmlns.oracle.com/psft"/>
      
  • When only one of the child nodes of the source has to be propagated into a target, then first ensure that there is no transformation invoked. Then, assign the source XPath expression to point to the required child node. Example 20-9 provides details.

    Example 20-9 One Child Node of the Source is Propagated into a Target

    <copy target="$out.request/imp1:ProductReq"
     expression="$in.body/imp1:request/ProductReq"
     xmlns:imp1="http://xmlns.oracle.com/psft"/>
    

    In this case, the source element evaluated from $in.body/imp1:request/ProductReq does not contain a complete tree structure that starts from the root element, but contains only a child node. Example 20-10 provides details.

    Example 20-10 Structure Starting from the Root Element that Contains Only a Child Node

    <ProductReq>
            <Make>MAKE</Make>
            <Model>MODEL</Model>
    </ProductReq>
    
  • If there are multiple assign activities in a Mediator and each source XPath expression points to a different child node, then there are the following two use cases:

    • If a transformation is available, then the corresponding child node in the target is updated.

    • If a transformation is not available, then the target should be a multiple part target with each part referring to the source child node.

  • With headers, if the passThroughHeader property is set, then

    • Any header manipulation in a transformation is updated in the target headers.

    • The part level assign activity overwrites the target header part.

    • The below part level node assign activity updates the corresponding node in the target.

  • If multiple source nodes (below part level) are assigned to the same target node (below part level), then the target node contains the value of the last copy element in the assign activity. Example 20-11 provides details.

    Example 20-11 Multiple Source Nodes Assigned to the Same Target Node

    <copy target="$out.request/imp1:request/ProductReq/Make"
     expression="$in.body/imp1:request/ProductReq/Model"
    xmlns:imp1="http://xmlns.oracle.com/psft"/>
    
    <copy target="$out.request/imp1:request/ProductReq/Make"
     expression="$in.body/imp1:request/Description"
    xmlns:imp1="http://xmlns.oracle.com/psft"/>
    

    In Example 20-11, the first copy element does not have any effect because the second copy element overwrites it.

  • If the XPath expression results in a list (multiple occurrences), then there are the following two use cases:

    • If the list contains a single element, then the XPath expression is propagated.

    • If the list contains multiple elements, then the XPath expression is not supported.

  • The following activities happen while assigning a source child node to a target child node:

    1. The source child node name and namespace are overwritten by the target node name and namespace, respectively.

    2. The target child node is replaced by the source child node in the parent node of the target node.

20.3.2.12 How to Access Headers for Filters and Assignments

When the Expression Builder is invoked from a Mediator, either for defining a filter or for defining an assignment source or target, the WSDL file is parsed. This automatically detects any SOAP headers for the current routing rule operation and makes them visible as variables under the in or out folder as header./ns_elementName/, as shown in Figure 20-24. Here, ns is the namespace prefix and elementName is the root element name for the header schema.

The following scenarios provide details.

Scenario 1: Namespace Prefixes wsse and ns1 Are Already Defined 

Assume the namespace prefixes wsse and ns1 are already defined in the WSDL file or the .mplan file. You can then write an XPath expression as follows:

$in.header.wsse_Security/wsse:Security/ns1:Foo/Priority

Scenario 2: Schema Without a Namespace Predefined in the WSDL File 

Assume you want to use a schema that does not have a namespace predefined in the WSDL file. The Expression Builder is then enhanced to allow you to enter {full_namespace} instead of a prefix. The Expression Builder then generates a unique prefix and the prefix definition is added to the .mplan file.

For example, enter the expression in the Expression Builder shown in Example 20-12:

Example 20-12 Expression

$in.header.{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-sec
ext-1.0.xsd}_Security/
{"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xs
d"}:
Security/{"http://www.globalcompany.com/ns/OrderBooking"}:Foo/Priority

The .mplan file contains the content shown in Example 20-13.

Example 20-13 Contents of .mplan File

xmlns:ns1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-
secext-1.0.xsd"
xmlns:ns2="http://www.globalcompany.com/ns/OrderBooking"
...
expression="$in.header.ns1_Security/ns1:Security/ns2:Foo/Priority"

Figure 20-24 Expression Builder Dialog - Automatic Header Detection

Description of Figure 20-24 follows
Description of "Figure 20-24 Expression Builder Dialog - Automatic Header Detection"

By default, SOAP headers are not passed through by Mediator. You must add the passThroughHeader endpoint property to the corresponding Mediator routing service:

<property name="passThroughHeader">true</property>

For example, to add this property, you can modify the composite.xml file, as shown in Example 20-14.

Example 20-14 passThroughHeader Property

<component name="Mediator1"> 
     <implementation.mediator src="Mediator1.mplan"/>
     <property name="passThroughHeader">true</property>
</component>

For the headers to pass through, the source and the target must have the same QName (name and namespace). If the source and the target have different QNames, then either a transformation or part-level assignment must be performed.

It is important to note that, with a passthrough Mediator (without a transformation or assign), if the source and target part QNames are not identical, then Mediator passes through the message payloads to the target service without any error. However, this can result in an error in the target service because the message payloads are not reconstructed according to the message structure of the target service.

Notes:

  • The user interface supports both SOAP 1.1 and SOAP 1.2.

  • For automatic header detection, a concrete WSDL file must be used when creating the Mediator service component.

  • Assignments execute after filters. Therefore, if you are assigning a value in a custom header, then the particular assignment is not visible to the filter.

20.3.2.12.1 Manual Expression Building for Accessing Headers for Filters and Assignments

There are use cases in which the header schemas cannot be determined from the WSDL files. For example, security headers that are appended to a message, or the headers for a Mediator that are created using an abstract WSDL file. To access these headers, you must manually enter the XPath expression into the Expression Builder.

The syntax for header expressions is shown in Example 20-15.

Example 20-15 Header Expressions Syntax

$in.header.<header root element namespace prefix>_<header root element name>/<xpath>

Therefore, for the header shown in Example 20-16.

Example 20-16 Header Syntax

<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-sec
ext-1.0.xsd">
<Priority>234</Priority>
</wsse:Security>

The filter expression is as follows:

$in.header.wsse_Security/wsse:Security/Priority = '234'

The assignment expression is as shown in Example 20-17.

Example 20-17 Assignment Expression

<copy target="$out.property.jca.jms.priority"
 expression="$in.header.wsse_Security/wsse:Security/Priority"/>

For the preceding expressions to work, you must add the attribute shown in Example 20-18 to the root element of the .mplan file.

Example 20-18 Addition of Attribute to .mplan File

wsse = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-
secext-1.0.xsd"
20.3.2.12.2 Manual Expression Building for Accessing Properties for Filters and Assignments

An example of a filter expression is as follows.

$in.property.tracking.ecid = '2'

An example of an assignment expression is as follows.

<copy target="$out.property.tracking.ecid"  value="$in.property.tracking.ecid"/>

20.3.2.13 How to Use Semantic Validation

You can specify Schematron files for validating an inbound message and its various parts. Schematron version 1.5 is the supported version.

Perform the following steps for specifying a Schematron schema to validate an inbound message and its various parts.

To use semantic validation: 

  1. To the right of the Validate Semantic field, click the Select Validation File icon.

    The Validations dialog is displayed.

  2. Click Add.

    The Add Validation dialog is displayed.

  3. From the Part list, select a message part.

  4. To the right of the File field, click Search.

    The SOA Resource Browser dialog is displayed.

  5. Select a Schematron file and click OK.

    Notes:

    • Schematron files usually have a .sch extension.

    • No error message or warning is displayed if the selected Schematron file is empty.

    The Add Validation dialog is updated, as shown in Figure 20-25.

    Figure 20-25 Add Validation Dialog

    Description of Figure 20-25 follows
    Description of "Figure 20-25 Add Validation Dialog"

  6. Click OK.

    The Validation dialog is updated, as shown in Figure 20-26.

    Figure 20-26 Validation Dialog

    Description of Figure 20-26 follows
    Description of "Figure 20-26 Validation Dialog"

  7. Click Add to specify a Schematron file for another message part or click OK.

    For more information about building a Schematron schema, see the resources available at

    http://www.schematron.com

    Note:

    In semantic validation, if you check for the length of each element name, then the element name may change for a different set of inputs. This happens when there are white spaces between nodes because the parser treats the white spaces as test nodes.

20.3.2.14 How to Work with Attachments

You can configure how Mediator handles attachments by adding properties to the project's composite.xml file. For information on working with attachments, see "Sending Attachment Streams" and "Overriding Pass Through Settings for Attachments in Oracle Mediator".

20.3.2.15 How to Use Java Callouts

Java callouts enable you to use external Java classes to manipulate messages flowing through the Mediator. Only one Java callout is supported per operation or event subscription. The callout class must implement the oracle.tip.mediator.common.api.IjavaCallout interface. Callouts are available for both static and dynamic routings. Figure 20-27 shows a sample Mediator with two operations, in which both the operations have one routing rule each and the first operation has a callout class.

Figure 20-27 Sample Mediator Supporting Java Callout

Description of Figure 20-27 follows
Description of "Figure 20-27 Sample Mediator Supporting Java Callout"

To make Java callout classes available: 

You must ensure that the Java callout class is available on the server. You can use any of the following methods for this:

  • Copy the Java class to the SCA-INF/classes folder.

  • Copy the JAR file containing the Java class to the SCA-INF/lib folder.

  • Copy the JAR file containing the Java class to the $DOMAIN_HOME/lib folder.

If you want to make the Java callout class available to multiple Mediators, copy the JAR file containing the Java class to the $DOMAIN_HOME/lib folder.

To enter the Java class for the callout: 

You can either manually enter the Java class or select a class from the Class Browser.

  • To manually enter the name of the Java callout class, start typing the class name in the Callout To field, as shown in Figure 20-28. The auto-completion feature of Oracle JDeveloper completes the address and the classes in the current project.

    Figure 20-28 Callout To Field

    Description of Figure 20-28 follows
    Description of "Figure 20-28 Callout To Field"

  • To select from a list of available classes, click the Select Java Callout Class icon.

    The standard Oracle JDeveloper class browser appears, as shown in Figure 20-29.

    Figure 20-29 Class Browser Dialog

    Description of Figure 20-29 follows
    Description of "Figure 20-29 Class Browser Dialog"

    The class browser is filtered so it only displays classes that implement the oracle.tip.mediator.common.api.IjavaCallout interface.

To set the payload root element (when using a filter expression): 

If you have a Java callout in Mediator and use a filter expression in the same Mediator, you must set the root element for the payload, as shown in Example 20-19.

Example 20-19 Setting the Root Element for the Payload

changexmldoc = XmlUtils.getXmlDocument(ChangedDoc);
String mykey = "request";
message.addPayload(mykey,changexmldoc.getDocumentElement());

To enable domain value map and cross reference functions: 

To use domain value map functions or cross reference functions in a Java callout, you must add the soa-xpath-exts.jar file to the project and import the necessary Java classes into your code.

  1. In the Oracle JDeveloper Projects Explorer, right-click the name of the project containing the Java callout.

  2. Select Project Properties.

    The Project Properties dialog appears.

  3. In the left panel, select Libraries and Classpath, as shown in Figure 20-30.

    Figure 20-30 Libraries and Classes on the Project Properties Dialog

    Description of Figure 20-30 follows
    Description of "Figure 20-30 Libraries and Classes on the Project Properties Dialog"

  4. Click Add JAR/Directory.

    The Add Archive or Directory dialog appears, as shown in Figure 20-31.

    Figure 20-31 Add Archive or Directory Dialog

    Description of Figure 20-31 follows
    Description of "Figure 20-31 Add Archive or Directory Dialog"

  5. In the explorer tree, expand the directories to select <JDEV_HOME>/jdeveloper/soa/modules/oracle.soa.fabric_11.1.1/soa-xpath-exts.jar, and then click Select.

    The JAR file appears in the Classpath Entries list.

  6. Click OK.

Notes:

When using domain value map functions, import the following into your Java class:

  • oracle.tip.dvm.LookupValue

  • oracle.tip.dvm.exception.DVMException

When using cross reference (xref) functions, import the following into your Java class:

  • oracle.tip.xref.xpath.XRefXPathFunctions

  • oracle.tip.xref.exception.XRefException

Mediator Java Callout API 

The Java callout API defines two interfaces: oracle.tip.mediator.common.api.IjavaCallout and oracle.tip.mediator.common.api.CalloutMediatorMessage.

Table 20-5 lists and describes the methods in the oracle.tip.mediator.common.api.IjavaCallout interface.

Table 20-5 Description of Methods in the IjavaCallout Interface

Method Description

initialize

This method is invoked when the callout implementation class is instantiated for the first time.

preRouting

This method is called before Mediator starts executing the cases. You can customize this method to include validations and enhancements.

preRoutingRule

This method is called before Mediator starts executing any particular case. You can customize this method to include case-specific validations and enhancements.

preCallbackRouting

This method is called before Mediator finishes executing callback handling. You can customize this method to perform callback auditing and custom fault tracking.

postRouting

This method is called after Mediator finishes executing the cases. You can customize this method to perform response auditing and custom fault tracking.

Post-processing methods are called after all sequential routing rules are executed and do not wait for parallel routing rules to complete.

postRoutingRule

This method is called after Mediator starts executing the cases. You can customize this method to perform response auditing and custom fault tracking.

postCallbackRouting

This method is called after Mediator finishes executing callback handling. You can customize this method to perform callback auditing and custom fault tracking.


Note:

If you change the message properties of a Mediator by using a Java callout in the preRoutingRule method or the preRouting method, then you must explicitly copy the changed property to the outbound message by using Mediator assignment functionality. For example, if you are changing the jca.file.FileName property in a Java callout, then you must update the Mediator assignment statement as follows:

<assign>
<copy target="$out.property.jca.file.FileName"
expression="$in.property.jca.file.FileName"/>
</assign>

Table 20-6 discusses the methods in the CalloutMediatorMessage interface.

Table 20-6 Description of Methods in the CalloutMediatorMessage Interface

Method Description

addPayload

This method sets a payload of the Mediator messages.

addProperty

This method adds a property to the Mediator messages.

addHeader

This method adds a header to the Mediator messages.

getProperty

This method retrieves Mediator message properties by providing the property name.

getProperties

This method retrieves Mediator message properties.

getId

This method retrieves the instance ID of the Mediator messages. This instance ID is the Mediator instance ID created for that particular message.

getPayload

This method retrieves a payload of the Mediator messages.

getHeaders

This method retrieves a header of the Mediator messages.

getComponentDN

This method retrieves a componentDN for the Mediator service component.


Notes:

  • The oracle.tip.mediator.common.api.AbstractJavaCalloutImpl class is a dummy implementation of the IJavaCallout interface. This class defines all the methods present in the IJavaCallout interface. Therefore, you can extend this class to override only a few specific methods of the IJavaCallout interface.

    Dummy implementation of an interface means that the implementation class provides definitions for all the methods declared in the particular interface, but one or more defined methods may have an empty method body. Extending a dummy implementation class is much easier because you can choose to override only a subset of the methods, unlike implementing an interface and defining all the methods.

  • Details of the processing occurring within the Java callout are not displayed in the Mediator audit trail screen.

Sample Java Callout Class 

Example 20-20 shows a sample Java callout class:

Example 20-20 Sample Java Callout Class

package qa.as11tests.javacallout;
 
import com.collaxa.cube.persistence.dto.XmlDocument;
 
import com.oracle.bpel.client.NormalizedMessage;
 
import java.util.logging.Logger;
import java.util.Map;
import java.util.Iterator;
 
import oracle.tip.mediator.common.api.CalloutMediatorMessage;
import oracle.tip.mediator.common.api.ExternalMediatorMessage;
import oracle.tip.mediator.common.api.IJavaCallout;
import oracle.tip.mediator.common.api.MediatorCalloutException;
import oracle.tip.mediator.metadata.CaseType;
import oracle.tip.mediator.utils.XmlUtils;
 
import oracle.tip.pc.services.functions.ExtFunc;
 
import oracle.xml.parser.v2.XMLDocument;
 
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
 
public class JavaCalloutSanity implements IJavaCallout {
    Logger logger = Logger.getLogger("Callout");
    public JavaCalloutSanity() {    }    
    
    public void initialize(Logger logger) throws MediatorCalloutException {
        this.logger = logger;
        this.logger.info("Initializing...");
    }
    public boolean preRouting(CalloutMediatorMessage calloutMediatorMessage) {
        System.out.println("Pre routing...");
        String sPayload = "null";
        String sPayload_org = "null";        
        for (Iterator msgIt = calloutMediatorMessage.getPayload().entrySet().iterator();
             msgIt.hasNext(); ) {
            Map.Entry msgEntry = (Map.Entry)msgIt.next();
            Object msgKey = msgEntry.getKey();
            Object msgValue = msgEntry.getValue();
            if (msgKey.equals("request"))
                sPayload = XmlUtils.convertDomNodeToString((Node)msgValue);           
       }
        sPayload_org = sPayload;
        String tobeReplaced = "CHANGE_THIS";
        String replaceWith = "JAVA_CALLOUT_||_PRE_ROUTING";
        int start = sPayload.indexOf(tobeReplaced);
        StringBuffer sb = new StringBuffer();
        sb.append(sPayload.substring(0, start));
        sb.append(replaceWith);
        sb.append(sPayload.substring(start + tobeReplaced.length()));
        String changedPayload = sb.toString();        
        String uid;
        try {
            uid = ExtFunc.generateGuid();            
        } catch (Exception e) {
        }
              XMLDocument changedoc;        
        try {
            changedoc = XmlUtils.getXmlDocument(changedPayload);
            String mykey = "request";
            calloutMediatorMessage.addPayload(mykey,
                                              changedoc.getDocumentElement());
            //calloutMediatorMessage.getPayload().put(mykey, changedoc);
        } catch (Exception e) {
        }
        System.out.println("Changed from : \n"+sPayload_org+"\nTo\n"+changedPayload);
        System.out.println("End Pre routing...\n\n");
        return false;
    }
    public boolean postRouting(CalloutMediatorMessage calloutMediatorMessage,
                               CalloutMediatorMessage calloutMediatorMessage1,
                               Throwable throwable) throws MediatorCalloutException {
        System.out.println("Start Post routing...");
        String sPayload = "null";
        String sPayload_org = "null";        
        for (Iterator msgIt = calloutMediatorMessage1.getPayload().entrySet().iterator();
             msgIt.hasNext(); ) {
            Map.Entry msgEntry = (Map.Entry)msgIt.next();
            Object msgKey = msgEntry.getKey();
            Object msgValue = msgEntry.getValue();
            if(msgKey.equals("reply"))
                sPayload = XmlUtils.convertDomNodeToString((Node)msgValue);          
        }
        
        sPayload_org = sPayload;        
        String tobeReplaced = "POST_ROUTING_RULE_REQUEST_REPLY";
        String replaceWith = "POST_ROUTING_RULE_REQUEST_REPLY_||_POSTROUTING_||_JAVA_CALLOUT_WORKING";
        int start = sPayload.indexOf(tobeReplaced);
        StringBuffer sb = new StringBuffer();
        sb.append(sPayload.substring(0, start));
        sb.append(replaceWith);
        sb.append(sPayload.substring(start + tobeReplaced.length()));
        String changedPayload = sb.toString();
        XMLDocument changedoc;
        try {
            changedoc = XmlUtils.getXmlDocument(changedPayload);
            String mykey = "reply";
            calloutMediatorMessage1.addPayload(mykey,changedoc.getDocumentElement());
            // calloutMediatorMessage1.getPayload().put(mykey, changedoc.getDocumentElement());
        } catch (Exception f) {
        }
        System.out.println("Changed from : \n"+sPayload_org+"\nTo\n"+
                changedPayload);
        System.out.println("End Post routing...\n\n");
        return false;
    }
    public boolean preRoutingRule(CaseType caseType,
                                  CalloutMediatorMessage calloutMediatorMessage) {
        System.out.println("\nStart PreRoutingRule.\n");
        String sPayload = "null";
        String sPayload_org = "null";
        for (Iterator msgIt =
             calloutMediatorMessage.getPayload().entrySet().iterator();
             msgIt.hasNext(); ) {
 
            Map.Entry msgEntry = (Map.Entry)msgIt.next();
            Object msgKey = msgEntry.getKey();
            Object msgValue = msgEntry.getValue();
            if(msgKey.equals("request"))
                sPayload = XmlUtils.convertDomNodeToString((Node)msgValue);            
        }        
        sPayload_org = sPayload;
        String tobeReplaced = "PRE_ROUTING";
        String replaceWith = "PRE_ROUTING_||_PRE_ROUTING_RULE";
        int start = sPayload.indexOf(tobeReplaced);
        StringBuffer sb = new StringBuffer();
        sb.append(sPayload.substring(0, start));
        sb.append(replaceWith);
        sb.append(sPayload.substring(start + tobeReplaced.length()));
        String changedPayload = sb.toString();
        XMLDocument changedoc;
        try {
            changedoc = XmlUtils.getXmlDocument(changedPayload);
            String mykey = "request";
            calloutMediatorMessage.addPayload(mykey,
                                              changedoc.getDocumentElement());
            // calloutMediatorMessage.getPayload().put(mykey, changedoc);
        } catch (Exception e) {
        }
        System.out.println("Changed from : \n"+sPayload_org+"\nTo\n"+changedPayload);
        System.out.println("End PreRoutingRule.\n\n");
        return true;
    }
    public boolean postRoutingRule(CaseType caseType,
                                   CalloutMediatorMessage calloutMediatorMessage,
                                   CalloutMediatorMessage calloutMediatorMessage1,
                                   Throwable throwable) {
        System.out.println("Start PostRoutingRule.");
        String req_sPayload = "null";
        String req_sPayload_org = "null";
        String rep_sPayload = "null";
        String rep_sPayload_org = "null";
        for (Iterator msgIt =
             calloutMediatorMessage.getPayload().entrySet().iterator();
             msgIt.hasNext(); ) {
            Map.Entry msgEntry = (Map.Entry)msgIt.next();
            Object msgKey = msgEntry.getKey();
            Object msgValue = msgEntry.getValue();
            if(msgKey.equals("request"))
                req_sPayload = XmlUtils.convertDomNodeToString((Node)msgValue);            
        }
        req_sPayload_org = req_sPayload;
        String tobeReplaced = "PRE_ROUTING_RULE";
        String replaceWith = "PRE_ROUTING_RULE_||_POST_ROUTING_RULE_REQUEST";
        int start = req_sPayload.indexOf(tobeReplaced);
        StringBuffer sb = new StringBuffer();
        sb.append(req_sPayload.substring(0, start));
        sb.append(replaceWith);
        sb.append(req_sPayload.substring(start + tobeReplaced.length()));
        String changedPayload = sb.toString();
        XMLDocument changedoc;
        try {
            changedoc = XmlUtils.getXmlDocument(changedPayload);
            String mykey = "request";
            calloutMediatorMessage.addPayload(mykey,
                                              changedoc.getDocumentElement());
            // calloutMediatorMessage.getPayload().put(mykey, changedoc);
        } catch (Exception e) {
        }
        for (Iterator msgIt =
             calloutMediatorMessage1.getPayload().entrySet().iterator();
             msgIt.hasNext(); ) {
            Map.Entry msgEntry = (Map.Entry)msgIt.next();
            Object msgKey = msgEntry.getKey();
            Object msgValue = msgEntry.getValue();
            if(msgKey.equals("reply"))
                rep_sPayload = XmlUtils.convertDomNodeToString((Node)msgValue);            
        }
        rep_sPayload_org = rep_sPayload;        
        tobeReplaced = "PRE_ROUTING_RULE";
        replaceWith = "PRE_ROUTING_RULE_||_POST_ROUTING_RULE_REQUEST_REPLY";
        start = rep_sPayload.indexOf(tobeReplaced);
        sb = new StringBuffer();
        sb.append(rep_sPayload.substring(0, start));
        sb.append(replaceWith);
        sb.append(rep_sPayload.substring(start + tobeReplaced.length()));
        changedPayload = sb.toString();
        try {
            changedoc = XmlUtils.getXmlDocument(changedPayload);
            String mykey = "reply";
            calloutMediatorMessage1.addPayload(mykey,changedoc.getDocumentElement());
            // calloutMediatorMessage1.getPayload().put(mykey, changedoc.getDocumentElement());
        } catch (Exception e) {
        }
        System.out.println("Changed from : \n"+req_sPayload_org+"\nTo\n"+changedPayload);
        System.out.println("End postRoutingRule\n\n");
        return true;
    }
}

20.3.3 How to Create Dynamic Routing Rules

The basic idea behind dynamic routing is to separate the control logic, which determines the path taken by the process, from the execution of the process. In the dynamic routing scenario, a decision matrix determines the type of Level-2 service to be chosen for each routing. The factors that affect the decision on the type of Level-2 service are channel, customer type, and so on. The solution allows this decision matrix to be modified externally by business analysts without changing the routing. The decision matrix must be evaluated to determine the outbound service.

How to create dynamic routing rules:

  1. Use the dynamic routing rule option of the Mediator Editor, as shown in Figure 20-32:

    Figure 20-32 Mediator Editor Displaying Dynamic Routing Rule Option

    Description of Figure 20-32 follows
    Description of "Figure 20-32 Mediator Editor Displaying Dynamic Routing Rule Option"

    This creates a new business rule service component that is wired to the Mediator service component within the SOA composite of the Mediator service component. The wire links between the business rule service component and the Mediator service component are considered implementation details and are shown as dotted lines in the SOA Composite Editor, as shown in Figure 20-33.

    Figure 20-33 SOA Composite Editor with Wire Links Between the Business Rule and Mediator Service Components

    Description of Figure 20-33 follows
    Description of "Figure 20-33 SOA Composite Editor with Wire Links Between the Business Rule and Mediator Service Components"

    The business rule service component includes a rule dictionary. The rule dictionary is a metadata container for the rule engine artifacts, such as fact types, rulesets, rules, decision tables and so on. As part of creating the business rule service component, the rule dictionary is preinitialized with the following data.

    • Fact Type Model

      The fact type model is the data model that can be used for modeling rules. The rule dictionary is populated with a fact type model that corresponds to the input of a phase activity in a BPEL process, and some fixed data model that is required as part of the contract between the Mediator service component and the business rule service component.

    • Ruleset

      A ruleset is a container of rules used as a kind of grouping mechanism for rules. A ruleset can be exposed as a service. As part of creating the business rule service component, one ruleset is created within the rule dictionary.

    • Decision Table (or matrix)

      From a rule engine perspective, a decision table is a collection of rules with the same fact type model elements in the condition and action part of the rules. The decision table enables you to visualize rules in a tabular format. As part of creating the business rule service component, a new decision table is created within the ruleset.

    • Decision Service

      As part of creating the business rule service component, a decision service is created to expose the ruleset as a service of the business rule service component. The service interface is used by the Mediator service component to evaluate the decision table.

    After all the required artifacts of the phase activity are created, the wizard starts modeling the phase decision matrix (PDM). The wizard launches the Business Rules Designer of Oracle JDeveloper and enables you to edit the phase decision matrix. Figure 20-34 shows a sample decision table within the Business Rules Designer.

    Figure 20-34 Sample Decision Table Within the Rule Designer

    Description of Figure 20-34 follows
    Description of "Figure 20-34 Sample Decision Table Within the Rule Designer"

  2. Once the dynamic routing is created, you can modify the associated decision matrix by clicking Edit Dynamic Rules. This launches the Business Rules Designer and enables modification of the associated decision table of the business rule service component. After you create dynamic routing for the Mediator service component, you cannot return to static routing without deleting the dynamic routing. Currently, there is no option for mixing these two types of routing.

    The Mediator Editor looks as shown in Figure 20-35 after the dynamic routing option is chosen.

    Figure 20-35 Mediator Editor with a Dynamic Routing Rule

    Description of Figure 20-35 follows
    Description of "Figure 20-35 Mediator Editor with a Dynamic Routing Rule"

    The changes in Source view are as follows.

    <Mediator name="Shipment" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns="http://xmlns.oracle.com/sca/1.0/mediator">
     <operation name="execute" deliveryPolicy="AllOrNothing" priority="0">
      <switch decisionServiceRef="Phase1DecisionService"
              decisionServiceOperation="executeFunction"></switch>
     </operation>
    </Mediator>
    

    The switch element contains the decision service reference and operation details to enable the Mediator service component to invoke the decision service in runtime for obtaining the dynamic routing decisions. Dynamic decisions are returned by the business rule service engine user configuration at runtime.

    External service invocation contains an extra attribute called bindingInfo, which contains binding information to make the invocation dynamic.

20.3.4 What You May Need to Know About Using Dynamic Routing Rules

Note the following limitations on using dynamic routing rules with Mediator:

  • As of now, only SOAP bindings are supported. There is a dummy SOAP binding in the composite.xml file. This endpoint is overridden by Mediator in runtime through an NM property. Therefore, outbound services can be called only over SOAP.

  • Payload manipulation is limited for dynamic routing rules. No assignment, transformation, or validation can be performed.

  • The reference WSDL file (layer 2 or called references) should have the same abstract WSDL file as the phase reference that gets automatically created.

  • Dynamic routing is not possible for Mediators with a synchronous or one-way interface.

20.3.5 How to Define Default Routing Rules

Mediator processes messages depending on the conditions specified in the routing rules. In some cases, a Mediator may not process an incoming message because the message does not satisfy any of the conditions specified in the routing rules. You can define a default routing rule for such messages. The default routing rule is executed when none of the conditions of other routing rules are satisfied.

A default routing rule is the same as the routing rules discussed in Section 20.3.2, "How to Create Static Routing Rules." The only difference between a default routing rule and other routing rules is that a default routing rule does not have any condition associated with it. Otherwise, a default routing rule is the same as other routing rules in every other aspect, such as target service, response handling, fault handling, and so on.

Notes:

  • Default rules are available only for static routing rules.

  • You cannot specify a default routing rule for a Mediator service component with dynamic routing rules because you cannot define both static and dynamic routing rules in the same Mediator service component.

20.3.5.1 Default Rule Scenarios

A default routing rule can be either a sequential rule or a parallel rule. A default routing rule, whether sequential or parallel, is guaranteed to be executed when no other routing rule condition is satisfied. When the default rule is executed, the Mediator audit trail shows that the filter conditions of all the routing rules failed, and the filter condition of the default routing rule passed and was executed. Example 20-21 provides details.

Example 20-21 Default Rule Scenarios

ActivityJan 7, 2010 4:35:15 PM 
Message onCase "fileout2.Write" 
Jan 7, 2010 4:35:15 PM 
Message Evaluation of xpath condition " No Filter (DEFAULT CASE) " resulted 
true

You can define all routing rules, including default routing rules, as either sequential or parallel routing rules, so the expected behavior of routing rules varies. The following sections discuss each combination and the expected behavior:

Sequential Default Routing Rule 

You can have the following possible scenarios with a sequential default routing rule:

  • All the other routing rules of the Mediator are sequential: This is the simplest case in which all the routing rules, including the default routing rule, are of a sequential type. Runtime evaluates the filter conditions of all routing rules and, if none of the filter conditions are matched, then the default sequential routing rule is executed. Default sequential routing rule execution happens in the same transaction as the incoming message. After the default rule is executed, a post Java callout occurs.

  • At Least One of the Routing Rules of the Mediator are parallel: This is a complex case in which the default routing rule is sequential and at least one of the other routing rules is parallel. The default behavior at runtime is to execute all sequential routing rules first and then execute parallel routing rules. Therefore, this is a tricky situation because a default rule should be executed only after all other routing rules are evaluated to be false.

    In this case, the server first evaluates the filter condition of parallel rules before evaluating the default routing rule filter condition. If none of the other filter conditions are matched, then the default sequential routing rule is executed.

Parallel Default Routing Rule 

You can have the following possible scenarios with a parallel default routing rule:

  • All the other routing rules of the Mediator are parallel: This is a straightforward case. The default routing rule is not executed if any of the filter conditions specified in the other routing rules are matched. If none of the filter conditions are matched, then the default routing rule is executed asynchronously.

  • Other Routing Rules of the Mediator are sequential or parallel: This is a complex but common use case in which there are other sequential or parallel routing rules available, and the default routing rule is parallel. The default routing rule is not executed if any of the other sequential or parallel routing rule criteria is matched. If none of the conditions are matched, then the default routing rule is executed asynchronously.

Note:

The fact that the default routing rule is executed automatically implies that the default routing rule is the only case that was executed for the given Mediator service component. Similarly, if a Mediator service component has one routing rule without any filter condition and also has a default routing rule, then the default routing rule is never executed.

20.3.5.2 Default Rule Target

The target of the default routing rule is the same as the supported targets of any other existing routing rule. This indicates that the target can be a service, an event, or an echo. Similarly, the response from the default routing rule target service can be forwarded or returned to the original caller. If the target service returns a fault, then the fault is handled in the same way as it is handled in any other routing rule.

Note:

If exceptions occur while evaluating or executing other routing rules, then the default routing rule is not executed.

20.3.5.3 Default Rule: Validation, Transformation, and Assign Functionality

Schematron validation, transformation, and assign functionality for the default routing rule works in the same way as other routing rules.

20.3.5.4 Default Rule: Java Callouts

The current behavior of a pre-Java callout or post-Java callout works in the same way as for other routing rules. For Java callouts, the default routing rule is considered another routing rule. Therefore, for the scenarios in which the default routing rule is executed, the postRouting() callback method occurs only after the default routing rule is executed.

Note:

The post-Java callouts occur after the execution of sequential rules and do not wait for the parallel rules to complete execution. Therefore, if the default routing rule is sequential, then the postRouting() callback method occurs after executing the default routing rule. If the default routing rule is parallel, then the postRouting() callback occurs after all sequential rules are executed and does not wait for the execution of the parallel default routing rule.

20.3.5.5 Default Rule: Mediator .mplan File

To set a routing rule as the default one, click the Set as Default Routing Rule icon shown on Figure 20-2. The .mplan file changes, as shown in Figure 20-36.

Figure 20-36 .mplan File of a Mediator with a Default Routing Rule

Description of Figure 20-36 follows
Description of "Figure 20-36 .mplan File of a Mediator with a Default Routing Rule"

20.4 Mediator Routing Use Cases

Two tutorials are available that give you step-by-step instructions for creating two of the Mediator sample projects provided on the Oracle SOA Suite samples page. They illustrate how to define routing rules for the Mediators you create. You can download the tutorials from http://java.net/projects/oraclesoasuite11g/downloads/download/Mediator/Tutorials/med_rr_tutorial.pdf.