Skip Headers
Oracle® Communications Order and Service Management Developer's Guide
Release 7.2.2

E35419-02
Go to Documentation Home
Home
Go to Table of Contents
Contents
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
PDF · Mobi · ePub

5 Using Automation

This chapter describes the Oracle Communications Order and Service Management (OSM) automation, which enables you to configure and automatically run automated tasks and notifications.

About Using Automation

The OSM automation framework provides the primary interface for outbound operations that interact with external systems for automated order fulfillment. The automation framework carries out the actions required by automated tasks that are required to fulfill an order. For example, you can model an automated task that requests a telephone number from an inventory system. You can also create notifications that trigger automations. See OSM Concepts for information about automated tasks and notifications.

To run automated tasks, you write automation plug-ins. The automation plug-ins are run by the automation framework.

An automation plug-in can be a:

The automation framework is supported by the following plug-ins:

You can define additional custom plug-ins. See the Oracle Communications Design Studio Help and "About Custom Automation Plug-ins" for more information.

Figure 5-1 shows the flow of an automated task and an automated notification, and how they call their corresponding automation plug-in. Design Studio provides the ability to map a specific automated task (Task A) to a specific automation plug-in (Automation Plug-in A), or a specific automated notification (Notification B) to a specific automation plug-in (Automation Plug-in B). This is called automation mapping. The mappings are saved to a cartridge, which is then deployed to the OSM server. OSM processes the automated tasks and automated notifications, which then trigger the mapped automation plug-ins.

Figure 5-1 Automation Flow

Shows the flow of an automated task and an automated notification, and how they call the corresponding automation plug-in

When an automated task or automated notification is triggered, OSM creates a JMS message (1) and sends it to an internal message queue (2). The internal message queue is created with your OSM installation, and the automation framework subscribes to this internal message queue (3). The automation framework picks up the message (4), processes the automated task or automated notification (5) and, using the automation mappings that were defined in Design Studio and deployed to the OSM server, determines which automation plug-in to call (6).

About Automation Mapping

Automation mapping is the process of mapping automated tasks and notifications to plug-ins. When you create or examine an automated task or notification in Design Studio, you bring up the Add Automation dialog box to create or select a plug-in for the task or notification and give it a name.

If you are creating a plug-in, you will give it a name and an Automation Type. There are two basic types of built-in automation plug-ins: Sender and Automator. Select the Automator type if the plug-in will receive data and perform some work. Select the Sender type if the plug-in will receive data, perform some work, then send data to external systems.

You will also set the Event Type, which specifies whether the new plug-in receives data internally from OSM or from an external systems. The choices are as follows:

You do not have this choice when defining an automation for an automated notification. Automated notifications are always defined as internal event receivers because, as the name implies, notifications are used to notify OSM users or other areas of the OSM system of some happening within OSM. That is why notifications do not receive messages from external systems; the information with which to notify always originates within OSM.

The new plug-in appears in the Automation list. Once you add a plug-in to the your automated task, you define the plug-in properties. See the Design Studio Help for further information.

The automation mapping involves defining other information as well, as described in this section. Collectively, this definition is called Automation in Design Studio.

Automation plug-ins that are external event receivers (send requests to external systems and process responses from external systems in reply to those requests) listen for responses (JMS messages) from external systems on an external message queue (JMS queue). In some cases you are required to specify filter criteria, defined in Design Studio as a message property selector, which OSM uses to identify the automation plug-in to call for each JMS message on the JMS queue. The external system must echo back the filter criteria information by extracting and reinserting it into its response.

Each automation task can have one or more external event receivers listening on the JMS queue. If the automation task has only one external event receiver, and you are using the Optimized build-and-deploy mode to build and deploy cartridges, you are not required to specify a message property selector. In this case, automation tasks can share the same JMS queue without the need for filter criteria. If the automation task has more than one external event receiver listening on the same JMS queue, you are required to specify a message property selector.

Note:

You must also specify a message property selector if you do either of the following:
  • You use the Legacy build-and-deploy mode to build and deploy cartridges.

  • You use the Both (Allow server preference to decide) build-and-deploy mode to build and deploy cartridges and configure the Internal dispatch mode for the OSM server.

For information on how OSM processes plug-ins according to the build-and-deploy mode you set, see "About Dispatch Modes for Automation Plug-ins". For information on message property selector filter criteria, see the Design Studio Help.

AutomationMap.xml

After you have defined the automated task or automated notification, and defined the automation for it, a successful build of the project automatically generates the automationMap.xml file:

  • This file is governed by the rules defined in the cartridgeName/customAutomation/automationMap.xsd file, which is only visible when in the Java perspective. The customAutomation directory and XSD file are present with the creation of an OSM cartridge.

  • This file is placed in the cartridgeName/cartridgeBuild/automation directory, which is only visible when in the Java perspective.

Editing AutomationMap.xml Files

If you are deploying a cartridge outside Design Studio, for example using OSM's cartridge management tools, the first time you upgrade a cartridge from a pre-OSM 7.0.3 version to a version of OSM that is 7.0.3 or later, you need to update the automationMap.xml manually. You need to add two elements to each <taskAutomator> element:

<cartridgeNamespace>Namespace</cartridgeNamespace>
<cartridgeVersion>Version</cartridgeVersion>

These elements are required because of changes to the automationMap.xsd.

If you are upgrading a pre-OSM 7.0.3 cartridge created in Design Studio, to a version that is 7.0.3 or later, no manual change is required.

Appendix A, "AutomationMap.xml File" provides numerous examples of generated XML for automations defined for automated tasks and automated notifications. The information is not included in this chapter because Oracle recommends that when defining the automation, you take the defaults and allow the project build to generate the automationMap.xml file. The information in the appendix is provided for in-depth understanding of the file should you need to modify it for some rare, obscure business reason.

Mnemonic Element

For automations defined as internal event receivers, the automationMap.xml generates the <mnemonic> element. This value of this element varies as described in Table 5-1.

The String value of the mnemonic element cannot exceed a length of fifty characters. If the length is greater than fifty, the following build error is encountered:

Exception caught assembling plug-ins: "Parse/validation of automation map cartridgeName/cartridgeBuild/automation/automationMap.xml using schema cartridgeName/customAutomation/automationMap.xsd failed: Invalid text fiftyPlusMnemonicValue in element: mnemonic."

Table 5-1 Mnemonic Values

Automated Task or Automated Notification <mnemonic> value

Automated task

taskName

Order milestone-based event notification

The <mnemonic> element is not generated for order milestone-based event notifications.

Task state-based event notification (task Events tab)

taskName

Task state-based event notification (process Events tab)

processName_eventName

Task status-based event notification

processName_eventName

Order data changed event notification

orderName_eventNotificationName

Order jeopardy notification

orderName_jeopardyName

Task jeopardy notification

taskName_jeopardyName


About Correlation

Correlation is a property that associates an incoming external system message with an outbound OSM message previously sent to initiate communication with the external system.

Correlation in OSM

Correlation uses the correlation ID parameter, which is configured in the outbound message at the OSM side, to retrieve the JMSCorrelationID of the incoming message. OSM compares the JMSCorrelationID with the correlation ID and associates the two messages if the respective values match.

Note:

No correlation configuration is required at the external system that sends the response message.

Correlation is of two types: Message Property and XML Body correlation.

In Message Property correlation, you specify a message header as the correlation ID in the outbound OSM message. For example:

outboundMessage:setJMSCorrelationID($outboundMessage, $corrID)

You can also specify additional message header properties in the outbound message. For example:

outboundMessage:setStringProperty($outboundMessage, $HEADER1, $corrID)

By default, Message Property correlation uses JMSCorrelationID as the correlation ID.

The XML Body correlation uses an XPath expression to retrieve the correlation ID from the body of the XML message.

Intercommunication Between Orders in the Same Domain

There is a special consideration when managing intercommunication between orders, and by extension cartridges that are deployed in the same domain. This situation can occur whenever there are two or more cartridges deployed in the same OSM server that need to communicate with each other.

The automation sender in the child cartridge needs to use the correlation ID specified by the parent order's task. By default, OSM uses the JMSCorrelationID property in the message header as the correlation ID. However, if both parent and child task senders use the same JMSCorrelationID property as the correlation ID, there is a potential situation where duplicate entries will exist in the OSM database with the same correlation ID, resulting in an error when the parent receiver tries to look up an automation context.

The design guideline to handle this is as follows:

  • For the parent automation sender, set the JMSCorrelationID header either programmatically, or allow the system to auto-generate this value.

  • For the child automation sender, set the JMSCorrelationID header to a different correlation ID than what the parent task sent, for example by using a different algorithm than the one used in the automator for the parent, or allowing the system to auto-generate a value. Define a separate custom field in the JMS header to contain the correlation ID expected by the parent task.

  • For the parent automation receiver, use the message property correlation configuration to retrieve the correlation ID from the custom defined JMS header field. This will prevent multiple entries with the same correlation ID in the database and will allow the parent task to correlate the automation context properly.

About Dispatch Modes for Automation Plug-ins

When you build and deploy your OSM cartridges in Design Studio, you can configure a build-and-deploy mode for automation plug-ins included in the cartridge. Design Studio uses the build-and-deploy mode to build and deploy the automation components OSM requires to process the automation plug-ins in the mode you prefer. A dispatch mode setting on the OSM server works in conjunction with the build-and-deploy mode configured in Design Studio in certain cases. The build-and-deploy mode configured in Design Studio controls building and deploying the automation components required for each mode while the dispatch mode setting on the server controls specifying the preferred mode OSM uses at run-time.

The Optimized dispatch mode runs all automation plug-ins inside the oms.ear file. Running all automation plug-ins in oms.ear improves the performance of processing of automated tasks and improves the performance of build and deployment of cartridges with automated tasks; it is the default mode for OSM 7.0.3. The Legacy dispatch mode runs each automation plug-in included in a cartridge in its own EAR file and is the dispatch mode used for OSM 7.0.2 and earlier releases; this method of building and deploying automation plug-ins is now referred to as the Legacy mode but it is simply the manner in which automation plug-ins were deployed and executed prior to OSM 7.0.3. Oracle recommends moving automation plug-ins to Optimized mode and to use Legacy mode only if necessary (for example, if there is a fundamental incompatibility with class libraries). To use Optimized mode, you must upgrade your cartridges from OSM 7.0.2 and earlier.

Tip:

The build-and-deploy mode you set for automation plug-ins in Design Studio indicates whether you want the plug-ins to be able to run within the oms.ear file or not. The dispatch mode on the OSM server indicates the ability for OSM to invoke an automation plug-in that is running within the bounds of the oms.ear file. If you want the server dispatch mode setting to take precedence, set the Design Studio build-and-deploy mode to Both.

Figure 5-2 illustrates that when automation plug-ins are built and deployed using Legacy mode, internal event receiver type plug-ins are contained within a J2EE application (.ear file) that is distinct from the OSM application (oms.ear file).

Figure 5-2 Legacy Mode Dispatch of Automation Plug-ins

Description of Figure 5-2 follows
Description of "Figure 5-2 Legacy Mode Dispatch of Automation Plug-ins"

Figure 5-3 illustrates that when automation plug-ins are built and deployed using Optimized mode, internal event receiver type plug-ins run within the OSM application. Therefore, internal dispatch automation plug-ins no longer require their own J2EE application. The figure also illustrates that with Optimized mode, the business logic of external event receiver type plug-ins is also run within the OSM application and only the automation framework of external event receiver type plug-ins requires its own J2EE application to listen on the external message queue.

Figure 5-3 Optimized Mode Dispatch of Automation Plug-ins

Description of Figure 5-3 follows
Description of "Figure 5-3 Optimized Mode Dispatch of Automation Plug-ins"

External event receiver type automation plug-ins always require their own J2EE application in order to listen on a JMS destination. When you use Optimized mode, all of the business logic for external event receiver type plug–in J2EE applications is executed within the OSM application and they need to be rebuilt only when the JNDI name of the JMS destination changes.

External event receiver type automation plug-ins are made up of both:

When you use Legacy mode, the J2EE application of an external event receiver type automation plug-in contains both the automation framework and the business logic for handling the incoming message.

When you use Optimized mode, the J2EE application of an external event receiver type automation plug-in contains only the minimum amount of automation framework infrastructure that allows it to listen on the external message queue and forward the message to the core OSM application logic. This means the business logic of the automation plug-in is now executed within the OSM application which enables it to more efficiently interact with the core OSM application logic. The automation framework acts primarily to forward the message to OSM. By containing the business logic within the OSM application, the only time you need to rebuild an external event receiver type automation plug-in is when you decide to use a different external message queue (when the JNDI name of the JMS destination changes).

Oracle recommends moving automation plug-ins to use the Optimized dispatch mode. For information on upgrading your cartridges to use the Optimized mode, see the upgrade impacts section of the OSM Installation Guide.

You can set the automation plug-in build-and-deploy mode for all cartridges in the same workspace or for individual cartridges.

By setting the Both (Allow server preference to decide) build-and-deploy mode, Design Studio builds and deploys the automation components required to process the automation plug-in in both Optimized and Legacy modes. In this case, OSM uses the dispatch mode defined on the OSM server to process the automation plug-in. For information on how to set the dispatch mode on the OSM server, see "Setting Dispatch Modes for Automation Plug-ins".

Table 5-2 summarizes the dispatch mode OSM uses at runtime based on how the automation plug-in build-and-deploy mode and the OSM server dispatch mode are set:

Table 5-2 Truth Table for Dispatch Mode Used at Run Time

Automation Plug-in Build-and-Deploy Mode OSM Server Dispatch Mode Effective Mode Used at Runtime

Optimized

Legacy

Optimized

Optimized

Internal

Optimized

Legacy

Legacy

Legacy

Legacy

Internal

Legacy

Both

Legacy

Legacy

Both

Internal

Optimized


For information on setting automation plug-in build-and-deploy modes, see "Setting Dispatch Modes for Automation Plug-ins" and the Design Studio Help.

Setting Dispatch Modes for Automation Plug-ins

You set a build-and-deploy mode for automation plug-ins included in your OSM cartridges in Design Studio. See "About Dispatch Modes for Automation Plug-ins" for a description of build-and-deploy modes. You can set a build-and-deploy mode for all cartridges and for individual cartridges. For instructions on setting build-and-deploy modes for OSM cartridges, see the topic on defining automation plug-in build-and-deploy modes in the Design Studio Help.

You set a server dispatch mode on the OSM server in the OSM configuration entry com.mslv.oms.automation.AutomationDispatcher.DefaultAutomationPluginDispatch. By setting a server dispatch mode on the OSM server, you indicate your preferred mode for OSM to invoke automation plug-ins if the build-and-deploy mode is set to Both (Allow server preference to decide). Based on the combined configuration of the build-and-deploy mode and the server dispatch mode, OSM determines the run-time behavior of automation plug-ins. See Table 5-2 for a truth table that shows the dispatch mode OSM uses at run time based on how the automation plug-in build-and-deploy mode and the OSM server dispatch mode are set.

To set the OSM server dispatch mode for processing automation plug-ins:

  1. Add or modify the following configuration entry in the oms-config.xml file:

    com.mslv.oms.automation.AutomationDispatcher.DefaultAutomationPluginDispatch

    See the chapter on configuring OSM with oms-config.xml in OSM System Administrator's Guide for detailed instructions on accessing and modifying the oms-config.xml file.

  2. Modify the configuration entry as follows:

    • To run automation plug-ins in a common EAR file (to use the Optimized dispatch mode), enter INTERNAL (default).

    • To run each automation plug-in it its own EAR file (to use the Legacy dispatch mode), enter LEGACY.

  3. Save the file.

For information on how OSM processes automation plug-ins based on the build-and-deploy modes you set for the cartridge and the dispatch mode you set for the OSM server, see "About Dispatch Modes for Automation Plug-ins".

About Custom Automation Plug-ins

All custom automation plug-in Java source files must reside in the cartridgeName/src directory. You can create subdirectories within the src directory as needed. When you compile the source file, the resultant Java class file is placed in the cartridgeName/out directory. Any subdirectories you created within the src directory are reflected in the out directory.

All custom automation plug-ins must extend one of the following automation classes, located in the OSM_home/SDK/automation/automationdeploy_bin/automation_plugins.jar file:

The custom automation plug-in can directly or indirectly extend AbstractAutomator or AbstractSendAutomator: If needed, there can be one or more layers of inheritance between AbstractAutomator or AbstractSendAutomator, and the automation plug-in.

These classes are hierarchically related. AbstractAutomator is the parent of AbstractSendAutomator as shown in Figure 5-4. Both classes reside in the com.mslv.automation.plugin package.

Figure 5-4 Class Hierarchy

Shows the class hierarchy.

The AbstractAutomator can receive information, either from OSM or from an external system. The AbstractSendAutomator inherits this ability, so it can also receive information from OSM or from an external system; however, it can also send information. If the custom automation plug-in you are writing is to send a message, it should extend the AbstractSendAutomator class; otherwise, it should extend the AbstractAutomator class.

Custom Automation Plug-in Method

AbstractAutomator and AbstractSendAutomator each define abstract methods which require child classes to define those methods. The custom automation plug-in must define a specific method, depending on which Java class the custom automation plug-in extends:

  • A custom automation plug-in that extends AbstractAutomator must define the method:

    public void run(String inputXML, AutomationConext automationContext)
     
    
  • A custom automation plug-in that extends AbstractSendAutomator must define the method:

    public void makeRequest(String inputXML, AutomationConext automationContext, TextMessage outboundMessage)
    

By defining one of these methods in a custom automation plug-in, when an automated task or automated notification is triggered, OSM can process the automation mapping and call the method, knowing it is defined for the class name provided in the automation mapping.

inputXML Argument

The inputXML argument is a java.lang.String object. The custom automation plug-in does not need to include an import statement for this object because it is included in the hierarchy from which the custom automation is extending.

The inputXML argument is the input data in XML document form that can be parsed to access the individual pieces of data. If the automation is defined as an internal event receiver, the XML document defines OSM order data. If the automation is defined as an external event receiver, the XML document defines data from an external source. In either case, you need to know the expected XML definition in order to write the code to parse the data.

Data is not stored at the element for a given XML tag; it is stored at its child, so the approach for retrieving order data is not obvious. A command to retrieve order data looks like this:

Element clli_a = root.getElementsByTagName("clli_a").item(0); 
String text = clli_a.getFirstChild().getNodeValue();

automationContext Argument

The automationContext argument is a com.mslv.automation.oms.AutomationContext object. The custom automation plug-in does not need to include an import statement for this object because it is included in the hierarchy from which the custom automation is extending.

The AutomationContext object is part of a class hierarchy, as shown in Figure 5-5. The AutomationContext object is, either directly or indirectly, the parent class to all other context object classes in the automation framework. (OrderContext and NotificationContext are no longer used, but remain as part of the relational hierarchy.)

Figure 5-5 Context Object Class Hierarchy

Shows the context object class hierarchy.

The context object passed to the automation plug-in method as an argument differs depending on the OSM event that triggers the automation plug-in, as shown in Table 5-3.

All context objects are located in the OSM_home/SDK/automation/automationdeploy_bin/automation_plugins.jar file. All context objects are defined in the same package: com.mslv.automation.oms.

Table 5-3 Context Objects Passed To Plug-in

Automation Plug-in Trigger Design Studio Definition Location OSM Event OSM Event Type Context Object Passed To Plug-in

Automated task

Task editor, Automation tab

Task state transitions to Received

Task Event

TaskContext

Order milestone-based event notification

Order editor, Events tab

Order reaches specified milestone

Order Notification Event

OrderNotificationContext

Task state-based event notification

Task editor, Events tab

Task reaches specified state

Task Notification Event

TaskNotificationContext

Task state-based event notification

Process editor, Events tab on Properties view of a task in the process

Task reaches specified state, then data condition specified by rule evaluates to true.

Task Notification Event

TaskNotificationContext

Task status-based event notification

Process editor, Events tab on Properties view of a status in the process

Task reaches specified status, then data condition specified by rule evaluates to true.

Task Notification Event

TaskNotificationContext

Order data changed event notification

Order editor, Notifications tab

Specified order data changes.

Order Notification Event

OrderDataChangeNotificationContext

Order jeopardy notification

Order editor, Jeopardy tab

At polling, data condition defined by rule evaluates to true.

System Notification Event

OrderNotificationContext

Task jeopardy notification

Task editor, Jeopardy tab

At polling, data condition defined by rule evaluates to true.

System Notification Event

If the task level jeopardy condition Multiple events per Task instance is set, then TaskNotificationContext is passed. Otherwise OrderNotificationContext is passed.


Casting the Argument

Within the custom plug-in, it is up to you to know which context object to expect as an argument, and then cast the AutomationContext object to the appropriate child context object.

For example, in code below, the expected context object is TaskContext, and automationContext is the name of the AutomationContext object argument.

if (automationContext instanceof TaskContext) {
    TaskContext taskContext = (TaskContext)automationContext; }
else { //log an error }

After the AutomationContext object is cast to the appropriate context object, all methods on the context object are available to the custom plug-in.

outboundMessage Argument

The outboundMessage argument is a javax.jms.TextMessage object. The custom automation plug-in does not need to include an import statement for this object because it is included in the hierarchy from which the custom automation is extending.

The outboundMessage argument is defined only for the makeRequest method; it is not defined for the run method. The makeRequest method is defined for classes that extend AbstractSendAutomator, which automatically send a message to an external system. You can write custom code that populates outboundMessage, which is sent to the external message queue defined by the automation definition. You do not have to write custom code to connect to the external system or send the message; OSM automation handles the connection and the message upon completion of the makeRequest method.

Accessing JDBC from Within an Automation Plug-in

Because custom automation plug-ins run inside a J2EE container, JDBC services are readily available.

To use JDBC from a plug-in, you must create a data source through the WebLogic console. The data source contains all the connection information for your proprietary database, such as host names, user names, passwords, number of connections, and so on.

For information on setting up data sources in WebLogic, see the overview of WebLogic Server applications development in the Oracle WebLogic documentation.

The following code illustrates how to connect to a proprietary database from OSM and perform a "SELECT *".

javax.naming.InitialContext initialContext = new InitialContext();
javax.sql.DataSource datasource = (javax.sql.DataSource) initialContext.lookup ("java:comp/env/jdbc/DataSource");

javax.sql.connection connection = datasource.getConnection();
javax.sql.Statement statement = connection.createStatement();

javax.sql.ResultSet resultSet = statement.executeQuery("SELECT * FROM my_custom_table");

Line two, the lookup, uses the JNDI name of the data source as a parameter.

Accessing the XML APIs

To access the XML APIs from within a custom automation plug-in, API users must belong to a WebLogic group that provides privilege to access the APIs. For accessing the XML APIs from within a custom automation plug-in, that WebLogic group is OSM_automation. So, to access the APIs from within a custom automation plug-in, the API user must belong to the WebLogic group OSM_automation.

See the Design Studio Help for further information regarding the Run As field, which defines the user of the automation.

Compiling the Custom Automation Plug-in

You must include the following JAR files in your project library list for the custom automation plug-in to compile:

  • WLS_home/wlserver_10.3/server/lib/weblogic.jar

  • OSM_home/SDK/automation/automationdeploy_bin/automation_plugins.jar

Warning:

The version of the automation_plugins.jar that you reference to compile the custom automation plug-in must be the same version that resides in the cartridge osmlib directory. To verify this, check the date and size of each file. If they are different, use the version that came with the OSM installation. To do so, copy the automation_plugins.jar file from the OSM_home/SDK/automation/automationdeploy_bin directory to the osmlib directory of your cartridge. After the file is copied to the cartridge, clean and rebuild the cartridge.

Depending on the content of the custom automation plug-in, you may also need to include additional JAR files.

To include a JAR file in the project library list:

  1. From the Design Studio menu bar, select Project, then select Properties.

    The Properties for CartridgeName window opens.

  2. In the left navigation pane, click Java Build Path.

  3. Click the Libraries tab.

  4. Click Add External JARs.

    The Jar Selection window opens.

  5. Navigate to the location of the JAR file and double-click the JAR file to add it to the library list.

Defining the Custom Automation Plug-in

Note:

There is a difference between the terms custom automation plug-in and Custom Automation Plug-in: The former is a custom Java class, the latter is a Design Studio entity.

For every custom automation plug-in you write, you must define a corresponding Custom Automation Plug-in entity in Design Studio. The Custom Automation Plug-in editor associates a Java class representing the custom automation plug-in to the Custom Automation Plug-in Design Studio entity. For example, if you create MyCustomPlugin.java and compile it, the result is MyCustomPlugin.class. You then create a new Custom Automation Plug-in entity, and populate the fields defined on the editor:

XML Template

The Custom Automation Plug-in editor also defines the XML Template field.

You must provide XML that defines the implementation for your custom automation plug-in. This is done through the <implement> element, as shown in Example 5-1. The <implement> element is defined in the cartridgeName/customAutomation/automationMap.xsd file, which is available with the creation of an OSM cartridge, as described in "Package Explorer View of a Cartridge".

Example 5-1 XML Template

<implement xsi:type="hw:customImplementation"
xmlns:hw="http://www.example.org/hello/world"
                        xsi:schemaLocation="http://www.example.org/hello/world helloWorld.xsd">
  <hw:completionStatus>success</hw:completionStatus></implement>
 

You must also provide the corresponding schema file that defines the rules for the XML that you entered in the XML Template field. The schema file name in this example is helloWorld.xsd, shown on the third line of Example 5-1. The content of helloWorld.xsd is shown in Example 5-2.

Example 5-2 Schema for XML Template

<?xml version="1.0" encoding="UTF-8"?><schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.example.org/hello/world"     xmlns:tns="http://www.example.org/hello/world"
        elementFormDefault="qualified"
xmlns:Q1="http://www.oracle.com/OMS/AutomationMap/2001/11/23/">
<import schemaLocation="automationMap.xsd"
  namespace="http://www.oracle.com/OMS/AutomationMap/2001/11/23/">
</import>
<complexType name="customImplementation">
        <complexContent>
                <extension base="Q1:Implementation">
                            <sequence>
                                      <element name="completionStatus" type="string"></element>
                                </sequence>
                  </extension>
        </complexContent>
  </complexType>
</schema>
 

The schema files you create must reside in the cartridgeName/customAutomation directory.

Note:

The generated automationMap.xml file includes the <implement> element for predefined automation plug-ins, but not for custom automation plug-ins. For additional examples of the implement element, see Appendix A, "AutomationMap.xml File".

When looking at the examples, note that the sub-elements defined for the implement element differ for senders versus automators.

Asynchronous and Synchronous Communication

Automated tasks and the automation plug-ins they trigger can handle asynchronous or synchronous communication. Automated notifications and the automation plug-ins they trigger can handle asynchronous communication only, as described in the first two sections; that is because an automated notification can not be defined as external event receiver, so it can not process a response as described in the last two sections.

Neither Asynchronous Nor Synchronous

You can define an automation as an internal event receiver that extends AbstractAutomator. In this scenario, the input data is coming from OSM and not being sent anywhere, so there is no communication with an external system. The automation plug-in may perform some internal calculation, or just complete the task.

This scenario is shown in Figure 5-1, "Automation Flow", at the beginning of this chapter. In the figure, Automation Plug-ins A and B are internal event receivers/automators.

Asynchronous

You can define an automation as an internal event receiver that extends AbstractSendAutomator. In this scenario, the input data is coming from OSM and being sent to an external system. The automation plug-in sends an asynchronous "fire-and-forget" message. That is, it completes the task and sends a message to an external system, but does not expect a response back from the external system.

This scenario is shown Figure 5-6, which builds upon Figure 5-1, "Automation Flow". In the figure, Automation Plug-in A is an internal event receiver/sender.

Figure 5-6 Automation Flow: Asynchronous

Illustrates asynchronous automation flow, as described in surrounding text.

Simple Synchronous

You can define an automated task that defines two automation plug-ins:

  • You can define the first automation as an internal event receiver that extends AbstractSendAutomator. In this scenario, the input data is coming from OSM and being sent to an external system. The automation plug-in sends a synchronous message which expects a response back from the external system.

  • You can define the second automation as an external event receiver that extends AbstractAutomator. In this scenario, the input data is coming from the external system (it is the response from the message sent by the first automation) and not being sent anywhere. The automation plug-in processes the response and completes the task.

This scenario is shown Figure 5-7, which builds upon Figure 5-6. In the figure, Automation Plug-in A-1 is an internal event receiver/sender, and Automation Plug-in A-2 is an external event receiver/automator.

Figure 5-7 Automation Flow: Simple Synchronous

Illustrates simple synchronous automation flow, as described in surrounding text.

Complex Synchronous

You can define an automated task that defines multiple automation plug-ins:

  • You can define the first automation as an internal event receiver that extends AbstractSendAutomator. In this scenario, the input data is coming from OSM and being sent to an external system. The automation plug-in sends a synchronous message which expects a response back from the external system.

  • You can define the second automation as an external event receiver that extends AbstractSendAutomator. In this scenario, the input data is coming from the external system (it is the response from the message sent by the first automation) and being sent back to the external system. The automation plug-in processes the response and replies back by sending another message.

  • You can define the third automation as an external event receiver that extends AbstractAutomator. In this scenario, the input data is coming from the external system (it is the response from the second message sent by the second automation) and not being sent anywhere. The automation plug-in processes the response and completes the task.

This scenario is shown Figure 5-8, which builds upon Figure 5-7. In the figure, Automation Plug-in A-1 an internal event receiver/sender, Automation Plug-in A-2 is an external event receiver/sender, and Automation Plug-in A-3 is an external event receiver/automator.

There can be multiple exchanges in such a scenario; this is just an example. After some number of messages back and forth, the final automation must be an external event receiver that extends AbstractAutomator, to complete the task. This example shows communication with two different external systems; however, steps 13-18 could continue communications with External System X, rather than with External System Y.

Figure 5-8 Automation Flow: Complex Synchronous

Illustrates complex synchronous automation flow as described in surrounding text.

About Predefined Automation Plug-ins

The OSM installation provides several predefined automation plug-ins, as described in the following sections. The sections are presented in the order that the predefined automation plug-ins display within Design Studio, on the Add Automation window Automation Type list field.

All of the predefined automation plug-ins are part of the automation class hierarchy; they extend, either directly or indirectly, the AbstractAutomator class, as shown in Figure 5-9.

Figure 5-9 Predefined Automation Plug-ins Class Hierarchy

Illustrates the predefined automation plug-ins class hierarchy.

Note:

The XSLT Automator predefined automation plug-in Java class is XSLTReceiver. The XQuery Automator predefined automation plug-in Java class is XQueryReceiver. The presentation in Design Studio was changed to remove confusion. The names receiver and sender imply that one receives and one sends, which is not true: Both receive. The sender just has the added ability to send a message.

XSLT Sender

The XSLT Sender predefined automation plug-in provides a way to transform data and send it to an external system using JMS, with you supplying the extensible stylesheet language transformation (XSLT).

Defining the Automation

When defining the automation on the Add Automation window, select XSLT Sender from the Automation Type list field.

For an automation defined as an internal event receiver, the XSLT must transform the OSM input data to SystemY data, where SystemY is the external system that the automation is sending the transformed data to.

For an automation defined as an external event receiver, the XSLT must transform SystemX data to SystemY data, where SystemX is the external system that the automation is receiving input data from, and SystemY is the external system that the automation is sending the transformed data to.

XSLT Tab

Selecting XSLT Sender from the Automation Type list field results in XSLT tab being present on the Properties view for the automation. The XSLT tab is where you specify your XSLT file so the predefined automation plug-in can access it. You can specify your XSLT file in one of three ways by choosing the appropriate radio button:

  • When you choose Bundle in, you can select your XSLT file from a list that displays all XSLT files defined in the cartridge resources directory, which populates the XSLT field for you.

  • When you choose Absolute path, you must enter the path and name of your XSLT file in the XSLT field.

  • When you choose URL, you must enter the unified resource locator (URL) to your XSLT file in the XSLT field.

Note:

Oracle recommends that you choose Bundle in for production mode because it pulls the XSLT files into the PAR file. As a result, you can deploy the EAR file (which contains the PAR file) to any server and, at run time, the application can locate the XSLT files. If you choose Absolute Path or URL for production mode, you can deploy the EAR file to any server but are responsible for ensuring the XSLT files reside in the specified location on the server.

Conversely, Absolute Path or URL are optimal for testing mode because they do not require a rebuild and redeploy to pick up changes to the XSLT.

The XSLTSender class can cache the associated XSLT file, incurring minimal overhead on each invocation. When the automation is defined to cache the XSLT, the implementation detects at runtime whether the XSLT source has changed by checking the URL modification time and the XSLT is automatically reloaded if required. You can configure caching through the Maximum Number in Cache and Cache Timeout fields.

You can set exceptions for the XSLT processing by setting the Exception field. For automations defined on a task, the Exception list field provides the values of success and failure, which are task statuses. If you define additional task statuses, they also appear in the list. (The Exception field is not applicable for automations defined on an order.)

Oracle uses Saxon as the transformer factory to process XSLT. You can specify use of a different transformer factory by specifying a value for the Transformer Factory field.

Note:

Oracle recommends that you use the default Saxon transformer factory.

Routing Tab

The Routing tab consists of two sub-tabs: To and Reply To. Both sub-tabs define the same set of fields. The To sub-tab defines where the outbound message is being routed to, and the Reply To sub-tab defines where the in-bound message (replying to the outbound message) is being routed to.

Writing the XSLT

When the XSLT transformer is called, it is passed references to the following named parameters that may be used from within the XSLT:

  • Automator: The class instance (for example, the instance of XSLTSender that is calling the XSLT).

  • Log: The automator's instance of org.apache.commons.logging.Log.

  • Context: The context object input parameter to the makeRequest method.

  • OutboundMessage: The outbound JMS TextMessage.

XSLTSender does not automatically complete the associated task after successful processing. If the task needs to be completed, the XSLT must include a call to

TaskContext.completeTaskOnExit(java.lang.String s)
 

as shown in Example 5-3:

Example 5-3 XSLT Java Call

<xsl:stylesheet version="1.0"
        xmlns="http://java.sun.com/products/oss/xml/ServiceActivation" 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
          xmlns:java="http://xml.apache.org/xslt/java" 
          xmlns:xalan="http://xml.apache.org/xslt" 
          xmlns:sa="http://java.sun.com/products/oss/xml/ServiceActivation"
          xmlns:mslv-sa="http://www.oracle.com/oss/ServiceActivation/2003/"
          xmlns:co="http://java.sun.com/products/oss/xml/Common" 
          exclude-result-prefixes="xsl java xalan sa mslv-sa">
          <!-- * -->
          <xsl:param name="automator"/>
          <xsl:param name="log"/>
          <xsl:param name="context"/>
          <!-- * -->
          <xsl:output method="xml" indent="yes" omit-xml-declaration="no" 
  xalan:indent-amount="5"/>
         <!-- * -->
          <xsl:template match="/">
                    <xsl:variable name="void1" select="java:info($log,'completing task 
    with status success')"/>
                  <xsl:variable name="void" select="java:completeTaskOnExit
    ($context,'success')"/>
          </xsl:template>
  <!-- * -->
          <xsl:template match="* | @* | text()">
                    <!-- do nothing -->
                    <xsl:apply-templates/>
          </xsl:template>
</xsl:stylesheet>
 

As the XSLT author, you must ensure that the context parameter provided to the automation plug-in, and so to your XSLT, is an instance of TaskContext or TaskNotificationContext. This implementation attempts to complete the associated task, if applicable, on processing failure, using the exception status defined in the AutomationMap.xml file.

Steps to Follow When Using XSLT Sender

The following high level-steps describe how to set up the XSLT Sender predefined automation plug-in:

  1. Determine the from and to data that your XSLT is to translate.

  2. Write the XSLT.

  3. Define automated task or automated notification that will trigger the automation plug-in.

  4. Define the automation for automated task or automated notification:

    1. Select XSLT Sender from the Automation Type list field.

    2. For an automated task, define the automation as internal or external event receiver.

    3. Populate all applicable automation Properties tabs, including the tabs specific to this type of automation: the XSLT tab and the Routing tab.

  5. Build the cartridge.

  6. Deploy the cartridge to the OSM server.

  7. From within OSM, perform the event that triggers the automation.

  8. XSLTSender uses your XSLT to transform the data and send it to the external system specified by the automation definition.

XSLT Automator

The XSLT Automator predefined automation plug-in provides a way to transform data or update OSM with the transformed data, with you supplying the extensible stylesheet language transformation (XSLT).

Defining the Automation

When defining the automation on the Add Automation window, select XSLT Automator from the Automation Type list field.

For an automation defined as an internal event receiver, the scenario is not very plausible because your corresponding XSLT would not need to transform OSM data to OSM data. However, you can write XSLT that executes Java rather than transforms data, so it is possible to define an XSLT Automator as an internal event receiver, but you can accomplish the same thing by writing a custom automation plug-in. The decision on which to use is based on the complexity of the Java code: If it is fairly short and simple, it may be quicker to use the predefined automation plug-in and just write the XSLT, as opposed to writing the custom automation plug-in.

For an automation defined as an external event receiver, your corresponding XSLT must transform SystemX data to OSM data, where SystemX is the external system that the automation is receiving input data from. You can also specify to update OSM with the transformed data.

XSLT Tab

Selecting XSLT Automator from the Automation Type list field results in XSLT tab being present on the Properties view for the automation. The XSLT tab is where you specify your XSLT so the predefined automation plug-in can access it. You can specify your XSLT in one of three ways by choosing the appropriate radio button:

  • When you choose Bundle in, you can select your XSLT file from a list that displays all XSLT files defined in the cartridge resources directory, which populates the XSLT field for you.

  • When you choose Absolute path, you must enter the path and name of your XSLT file in the XSLT field.

  • When you choose URL, you must enter the unified resource locator (URL) that locates your XSLT file in the XSLT field.

Note:

Oracle recommends that you choose Bundle in for production mode and Absolute Path or URL for testing mode.

The XSLTReceiver class can cache the associated XSLT file, incurring minimal overhead on each invocation. When the automation is defined to cache the XSLT, the implementation detects at runtime whether the XSLT source has changed by checking the URL modification time; the XSLT is automatically reloaded if required. You can configure caching through the Maximum Number in Cache and Cache Timeout fields.

You can set exceptions for the XSLT processing by setting the Exception field. For automations defined on a task, the Exception list field provides the values of success and failure, which are task statuses. If you define additional task statuses, they also appear in the list. (The Exception field is not applicable for automations defined on an order.)

Oracle uses Saxon as the transformer factory to process XSLTs. You can specify to use a different transformer factory by specifying a value for the Transformer Factory field.

Note:

Oracle recommends that you use the default Saxon transformer factory.

When XSLT Automator is selected from the Automation Type list, the XSLT tab also includes the Update Order check box, which is not present when XSLT Sender is selected from the Automation Type list. If the check box is selected, XSLTReceiver updates OSM with the transformed order data. If the check box is deselected, XSLTReceiver just transforms the data; it does not update OSM with the transformed data.

Writing the XSLT

When the XSLT transformer is called, it is passed references to the following named parameters that may be used from within the XSLT:

  • Automator: The class instance (for example, the instance of XSLTReceiver that is calling the XSLT).

  • Log: The automator's instance of org.apache.commons.logging.Log.

  • Context: The context object input parameter to the makeRequest method.

XSLTReceiver does not automatically complete the associated task after successful processing. If the task needs to be completed, the XSLT must include a call to

TaskContext.completeTaskOnExit(java.lang.String s)

as shown in Example 5-3, "XSLT Java Call".

As the XSLT author, you must ensure that the context parameter provided to the automation plug-in, and so to your XSLT, is an instance of TaskContext or TaskNotificationContext. This implementation attempts to complete the associated task, if applicable, on processing failure, using the exception status defined in the AutomationMap.xml file.

Steps to Follow When Using XSLT Automator

The following high-steps describe how to set up the XSLT Automator predefined automation plug-in:

  1. Determine the from and to data that your XSLT is to translate.

  2. Write the XSLT.

  3. Define automated task or automated notification that will trigger the automation plug-in.

  4. Define the automation for automated task or automated notification:

    1. Select XSLT Automator from the Automation Type list field.

    2. For an automated task, define the automation as internal or external event receiver.

    3. Populate all applicable automation Properties tabs, including the tab specific to this type of automation; that is, the XSLT tab.

  5. Build the cartridge.

  6. Deploy the cartridge to the OSM server.

  7. From within OSM, perform the event that triggers the automation.

  8. XSLTAutomator uses your XSLT to transform the data or updates OSM with the transformed data.

XQuery Sender

The XQuery Sender predefined automation plug-in provides a way to extract and manipulate XML data and send it to an external system using JMS, with you supplying the XML query (XQuery).

Defining the Automation

When defining the automation on the Add Automation window, select XQuery Sender from the Automation Type list field.

For an automation defined as an internal event receiver, your corresponding XQuery can manipulate OSM data and send it to SystemY, where SystemY is the external system that the automation is sending the manipulated data to.

For an automation defined as an external event receiver, your corresponding XQuery can manipulate SystemX data and send it to SystemY, where SystemX is the external system that the automation is receiving input data from, and SystemY is the external system that the automation is sending the manipulated data to.

XQuery Tab

Selecting XQuery Sender from the Automation Type list field results in XQuery tab being present on the Properties view for the automation. The XQuery tab is where you specify your XQuery file so the predefined automation plug-in can access it. You can specify your XQuery file in one of three ways by choosing the appropriate radio button:

  • When you choose Bundle in, you can select your XQuery file from a list that displays all XQuery files defined in the cartridge resources directory, which populates the XQuery field for you.

  • When you choose Absolute path, you must enter the path and name of your XQuery file in the XQuery field.

  • When you choose URL, you must enter the unified resource locator (URL) to your XQuery file in the XQuery field.

Note:

Oracle recommends that you choose Bundle in for production mode and Absolute Path or URL for testing mode.

The XQuerySender class can cache the associated XQuery file, incurring minimal overhead on each invocation. When the automation is defined to cache the XQuery, the implementation detects at runtime whether the XQuery source has changed by checking the URL modification time; the XQuery is automatically reloaded if required. You can configure caching through the Maximum Number in Cache and Cache Timeout fields.

You can set exceptions for the XSLT processing by setting the Exception field. For automations defined on a task, the Exception list field provides the values of success and failure, which are task statuses. If you define additional task statuses, they also appear in the list. (The Exception field is not applicable for automations defined on an order.)

Routing Tab

The Routing tab consists of two sub-tabs: To and Reply To. Both sub-tabs define the same set of fields. The To sub-tab defines where the outbound message is being routed to, and the ReplyTo sub-tab defines where the in-bound message (replying to the outbound message) is being routed to.

Writing the XQuery

When the XQuery processor is called, it is passed references to the following named parameters that may be used from within the XQuery:

  • Automator: The class instance (for example, the instance of XQuerySender that is calling the XSLT).

  • Log: The automator's instance of org.apache.commons.logging.Log.

  • Context: The context object input parameter to the makeRequest method.

  • OutboundMessage: The outbound JMS TextMessage.

XQuerySender does not automatically complete the associated task after successful processing. If the task needs to be completed, the XQuery must include a call to

TaskContext.completeTaskOnExit(java.lang.String s)
 

as shown in Example 5-3, "XSLT Java Call".

As the XQuery author, you must ensure that the context parameter provided to the automation plug-in, and so to your XQuery, is an instance of TaskContext or TaskNotificationContext. This implementation attempts to complete the associated task, if applicable, on processing failure, using the exception status defined in the AutomationMap.xml file.

Steps to Follow When Using XQuery Sender

The following high-steps describe how to set up the XQuery Sender predefined automation plug-in:

  1. Determine the from and to data that your XQuery is to manipulate.

  2. Write the XQuery.

  3. Define automated task or automated notification that will trigger the automation plug-in.

  4. Define the automation for automated task or automated notification:

    1. Select XQuery Sender from the Automation Type list field.

    2. For an automated task, define the automation as internal or external event receiver.

    3. Populate all applicable automation Properties tabs, including the tabs specific to this type of automation: the XQuery tab and the Routing tab.

  5. Build the cartridge.

  6. Deploy the cartridge to the OSM server.

  7. From within OSM, trigger the automation.

  8. XQuerySender uses your XQuery to manipulate the data and send it to the external system specified by the automation definition.

XQuery Automator

The XQuery Automator predefined automation plug-in provides a way to manipulate data or update OSM with the manipulated data, with you supplying the XML Query (XQuery).

Defining the Automation

When defining the automation on the Add Automation window, select XQuery Automator from the Automation Type list field.

For an automation defined as an internal event receiver, your corresponding XQuery can manipulate the OSM input data or specify to update OSM with the manipulated data.

For an automation defined as an external event receiver, your corresponding XQuery can manipulate the SystemX input data, where SystemX is the external system that the automation is receiving input data from. You can also specify to update OSM with the manipulated data.

XQuery Tab

Selecting XQuery Automator from the Automation Type list field results in XQuery tab being present on the Properties view for the automation. The XQuery tab is where you specify your XQuery so the predefined automation plug-in can access it. You can specify your XQuery in one of three ways by choosing the appropriate radio button:

  • When you choose Bundle in, you can select your XQuery file from a list that displays all XQuery files defined in the cartridge resources directory, which populates the XQuery field for you.

  • When you choose Absolute path, you must enter the path and name of your XQuery file in the XQuery field.

  • When you choose URL, you must enter the unified resource locator (URL) that locates your XQuery file in the XQuery field.

The XQueryReceiver class can cache the associated XQuery file, incurring minimal overhead on each invocation. When the automation is defined to cache the XQuery, the implementation detects at runtime whether the XQuery source has changed by checking the URL modification time; the XQuery is automatically reloaded if required. You can configure caching through the Maximum Number in Cache and Cache Timeout fields.

You can set exceptions for the XSLT processing by setting the Exception field. For automations defined on a task, the Exception list field provides the values of success and failure, which are task statuses. If you define additional task statuses, they also appear in the list. (The Exception field is not applicable for automations defined on an order.)

When XQuery Automator is selected from the Automation Type list, the XQuery tab also includes the Update Order check box, which is not present when XQuery Sender is selected from the Automation Type list. If the check box is selected, XQueryReceiver updates OSM with the manipulated data. If the check box is deselected, XQueryReceiver just manipulates the data; it does not update OSM with the manipulated data.

Writing the XQuery

When the XQuery transformer is called, it is passed references to the following named parameters that may be used from within the XQuery:

  • Automator: The class instance (for example, the instance of XQueryReceiver that is calling the XSLT).

  • Log: The automator's instance of org.apache.commons.logging.Log.

  • Context: The context object input parameter to the makeRequest method.

XQueryReceiver does not automatically complete the associated task after successful processing. If the task needs to be completed, the XQuery must include a call to

TaskContext.completeTaskOnExit(java.lang.String s)
 

as shown in Example 5-3, "XSLT Java Call".

As the XQuery author, you must ensure that the context parameter provided to the automation plug-in, and so to your XQuery, is an instance of TaskContext or TaskNotificationContext. This implementation attempts to complete the associated task, if applicable, on processing failure, using the exception status defined in the AutomationMap.xml file.

Steps to Follow When Using XQuery Automator

The following high-steps describe how to set up the XQuery Automator predefined automation plug-in:

  1. Determine the from and to data that your XQuery is to manipulate.

  2. Write the XQuery.

  3. Define automated task or automated notification that will trigger the automation plug-in.

  4. Define the automation for automated task or automated notification:

    1. Select XQuery Automator from the Automation Type list field.

    2. For an automated task, define the automation as internal or external event receiver.

    3. Populate all applicable automation Properties tabs, including the tab specific to this type of automation; that is, the XQuery tab.

  5. Build the cartridge.

  6. Deploy the cartridge to the OSM server.

  7. From within OSM, trigger the automation.

  8. XQueryReceiver uses your XQuery to manipulate the data or update OSM with the manipulated data.

Retrieving Multiple Order Perspectives

During the fulfillment process, an order may fail (also known as fallout) for reasons such as insufficient data or incorrect data. You may have to revise the order data to fix the fallout. If there are multiple revisions on the order, you may need access to previous versions of it so you can provide the information required to roll back the order to the corresponding successful state rather than rolling it back to the previous successful state.

Using GetOrder's TaskExecutionHistory and OrderChangeID elements, you can obtain the order data for all the revisions happened on an order and use the relevant data in the fulfillment process according to your needs. The GetOrder.Response and GetOrder.Request XML APIs also include these elements and are included with OSM Automation plug-ins.

For example, consider an order which has been revised three times. You can obtain order data of all the three revisions and use the required data for the fulfillment.

See OSM XML API Developer's Guide for more information about these elements.

Use the GetOrder function to retrieve the TaskExecutionHistory element which returns an OrderChangeID associated with each historical perspective.

The following sample code snippet provides the syntax for the GetOrder function:

let $taskData := fn:root(automator:getOrderAsDOM($automator))/oms:GetOrder.Response
let $orderChangeID := $taskData/oms:TaskExecutionHistory/oms:Task[1]/oms:OrderChangeID/text()
let $prevTaskData := fn:root(automator:getOrderAsDOM($automator, $orderChangeID))/oms:GetOrder.Response

In the example above, the OrderChangeID specifies the revision to look for and roll back. An OrderChangeID with a value 0 indicates that it is the original base order with no revisions.

DatabasePlugin

Note:

The OSM installation provides samples of the DatabasePlugin predefined automation plug-in, located in the SDK/Samples/DatabasePlugin directory.

The DatabasePlugin class is a predefined automation plug-in that provides a way to interact with external databases, with you supplying the SQL and stored procedures to query and update a database. The automation plug-in can also be configured to update OSM with data returned from an external database.

DatabasePlugin is slightly different from the previously described predefined automation plug-ins, in that the input is not accessed through a file. Rather, the input is accessed through the XML Template field on the Custom Automation Plug-in editor. Because this predefined automation plug-in requires the use of the XML Template field, it must be defined as a Custom Automation Plug-in. As a result, DatabasePlugin does not appear in the Automation Type list field on the Add Automation window like the other predefined automation plug-ins do.

Defining the Custom Automation Plug-in

To define the Custom Automation Plug-in for the DatabasePlugin predefined automation plug-in, set the Class field by selecting DatabasePlugin. The DatabasePlugin.class is located in the OSM_home/SDK/automation/automationdeploy_bin/automation_plugins.jar file, which comes with your OSM installation.

XML Template

The XML Template field consists of one or more statements defined under the root <implementation> element. A statement may update the database, or update OSM order data, or both. All statements share the following characteristics:

  • May contain SQL or stored procedure calls.

  • May have one or more parameters.

  • May return one or more result sets, either as a result of a database query or through a stored procedure OUT parameter.

  • May contain one or more bind paths.

  • May be configured to handle database exceptions in an implementation appropriate manner.

  • May run as a single transaction or in a group.

SQL statements are specified by the <sql> element and stored procedure statements are specified by the <call> element. The format of the call element is expected to be of the form {? = call <procedure-name>[<arg1>, <arg2>, ...]} or {call <procedure-name>[<arg1>,<arg2>, ...]}. Parameters are declared with the? character.

Example 5-4 and Example 5-5 show the SQL statement and the stored procedure call.

Example 5-4 SQL Statement

<implementationxmlns="http://www.oracle.com/Provisioning/database/DatabasePlugin/2006/02/28/" ...>    ...    <query>        <sql>SELECT 'dummy' FROM dual</sql>    ...    </query></implementation>

Example 5-5 Stored Procedure Call

<implementationxmlns="http://www.oracle.com/Provisioning/database/ DatabasePlugin/2006/02/28/" ...>    ...    <update>        <call>{call a_stored_procedure(?)}</call>        ...    </update></implementation>

Transaction Element

The <transaction> element allows statements to be grouped. All statements contained in a <transaction> element will be run as part of a single database transaction. If a statement is defined outside of the <transaction> element, it is auto-committed immediately after the statement completes. The available configuration parameters are:

  • dataSource: Mandatory. Specifies the JNDI name of the SQL data source used to create the database connection for the transaction. This data source must be defined in your WebLogic domain before the plug-in is called.

    Note:

    Do not configure the data source to support global transactions. The plug-in instance is called under an enclosing transaction, making this option illegal.
  • isolationLevel: Optional. Specifies the transaction isolation level. Valid values are READ_COMMITTED, READ_UNCOMMITTED, REPEATABLE_READ, and SERIALIZABLE. READ_UNCOMMITTED and REPEATABLE_READ are not supported by Oracle.

  • scrollType: Optional. Specifies the type of result sets to be created as part of the transaction. Valid values are FORWARD_ONLY, SCROLL_SENSITIVE, and SCROLL_INSENSITIVE. The SCROLL values apply only when more than one ResultSet definition is defined for the same result set.

  • update: A statement that updates the database, but does not return results.

  • query: A statement that queries the database for information. The returned results are used to update the order data.

Example 5-6 Transaction Definition

<implementation xmlns="http://www.oracle.com/Provisioning/database/DatabasePlugin/2006/02/28/" ...>    <transaction isolationLevel="READ_COMMITTED"    scrollType="SCROLL_INSENSITIVE">        <dataSource>test/dblugin/datasource</dataSource>        <query>            <sql>SELECT 'dummy' FROM dual</sql>            <resultSet>                <column number="1">/path/to/p6/field</column>            </resultSet>        </query>    </transaction></implementation>

Bind Path

The <bind path> element provides a way to correlate outbound parameter values and in-bound result set column values. Instances of this result column will be bound to instances of the specified parameter at the specified path; after which their paths may diverge. This attribute is only relevant when a parameter's path includes a multi-instance group element.

Consider the sample OSM order data shown in Example 5-7 and the corresponding plug-in configuration in Example 5-8.

Example 5-7 OSM Order Data

<employees>    <employee>        <name>William</name>        <job/>    </employee>    <employee>        <name>Mary</name>        <job/>    </employee></employees>

Example 5-8 Plug-in Definition Using a Bind Path

<implementation xmlns="http://www.oracle.com/Provisioning/database/DatabasePlugin/2006/02/28/" ... >    <query>        <sql>SELECT job FROM employee WHERE name = ?</sql>        <bindPath id="emp" path="/employee[2]"/>        <parameter xsi:type="ProvisioningParameterType"        bindPathRef="emp" path="name" type="text"/>        <resultSet appliesTo="1" appliesToRow="all">            <column number="1" bindPathRef="emp" path="job"            updateOnMatch="true"/>        </resultSet>    </query></implementation>
 

The emp bind path selects the second employee (with name of Mary). This bind path is used as the basis for the parameter selection and the corresponding result set column value, ensuring the job field that gets updated is the job corresponding with the employee named Mary.

Parameter

The <parameter> element defines how values are bound to the SQL parameter declarations. Parameters must be defined in the order of the corresponding declarations.

OSMParameterType

Specifies a parameter, the value of which will be bound to a <sql> or <call> statement. Parameters are processed in the order they are declared. The available parameter configuration attributes are:

  • bindPathRef

  • path

  • type

  • mode

bindPathRef and/or path provide the value that will be set on the SQL parameter; type provides the data type of the value; mode specifies whether the parameter is a stored procedure IN, OUT, or INOUT parameter. Each attribute is described in more detail in the sections that follow.

bindPathRef: This is the ID value of a bind path defined elsewhere on the statement. Either bindPathRef, path, or both may be specified. The value bound to the SQL parameter depends on the result of the evaluation of the bind path's XPath expression, as described in the table.

Table 5-4 Bind Path Evaluation Behavior

XPath Result Behavior

null

If path is not specified, the SQL parameter is set to null. If path is specified, the SQL parameter is set based on the path evaluation as described below.

Node-set

If path is not specified, the SQL parameter is set according to the following algorithm:

The first node encountered in the node-set is selected.

If the node is an XML element, the text contained directly under the element is selected as a String (if none, the SQL parameter is set to null).

If the node is an XML attribute, the value of the attribute is selected as a String.

Otherwise, the node itself (as a Java Object) is selected.

The parameter value is set using the selected data based on the parameter's type (see Table 5-6, "OSM Data Type to SQL Data Type Mapping").

Object

The parameter value is set using the selected data based on the parameter's type (see Table 5-6, "OSM Data Type to SQL Data Type Mapping").


path: The XPath selector in the path attribute is evaluated against the plug-in's input data in order to determine the SQL parameter's value. The context node against which the path expression is evaluated depends on the format of the input data and whether or not bindPathRef evaluated to a node-set of XML Elements. If the bindPathRef evaluated to a node-set of Elements, the first encountered Element is used as the context node for the path expression. If the input is an OSM GetOrder.Response document, the context node is the _root element of the document. Otherwise, the context node is the document root element. The value bound to the SQL parameter depends on the result of the evaluation of the path's XPath expression, as described in Table 5-5.

Table 5-5 Path Expression Evaluation Behavior

XPath Result Behavior

null

The SQL parameter is set to null.

Node-set

The SQL parameter is set according to the following algorithm:

The first node encountered in the node-set is selected.

If the node is an XML Element, the text contained directly under the Element is selected as a String (if none, the SQL parameter is set to null).

If the node is an XML Attribute, the value of the Attribute is selected as a String.

Otherwise, the node itself (as a java Object) is selected.

The parameter value is set using the selected data based on the parameter's type (see Table 5-6).

Object

The parameter value is set using the selected data based on the parameter's type (see Table 5-6).


type: Specifies the data type of the parameter, which are OSM specific.Valid values are: boolean, currency, date, dateTime, numeric, phone, and text.

Table 5-6 shows the SQL data type that will be used to set the SQL parameter based on the specified type and the Java class of the parameter value.

Table 5-6 OSM Data Type to SQL Data Type Mapping

type Attribute Value SQL Data TypeFoot 1  Parameter EvaluationFoot 2 

Boolean

Boolean

Evaluated according to java.lang.Boolean.parseBoolean() using the String value of the parameter. OSM values Yes and No are also supported.

currency

double

Evaluated according to java.lang.Double.parseDouble() using the String value of the parameter.

numeric

double

Evaluated according to java.lang.Double.parseDouble() using the String value of the parameter.

date

date

The String value of the parameter is expected to match the format yyyy-MM-dd.

dateTime

timestamp

The String value of the parameter is expected to match the format yyyy-MM-dd'T'HH:mm:ss z.

phone

string

Evaluated according to java.lang.String.valueOf().

text

string

Evaluated according to java.lang.String.valueOf().


Footnote 1 where the parameter is set as java.sql.PreparedStatement.setXXX(#, value)

Footnote 2 If the class of the parameter is directly assignable to the SQL data type, it is not first evaluated as a String. For example, if the type attribute value is numeric and the class of the parameter value is java.lang.Number, no String evaluation is required.

mode: Specifies the mode of the parameter. Valid values are IN, OUT, and INOUT. Applicable only if the statement is a prepared statement, that is, defined with <call>.

Exception

The exception statement specifies the behavior that the plug-in should exhibit when a particular Java exception is caught during processing. Exceptions can be ignored or they can complete the associated task with a particular exit status.

If the exception is an instance of java.sql.SQLException, behavior may be further constrained to exceptions that have a particular error code or SQL state value. Exception handlers are evaluated in document order; that is, the first exception handler that matches the thrown exception will be used. If no exception handler exists for a thrown exception, it will be wrapped in a com.mslv.oms.automation.plugin.JDBCPluginException and re-thrown.

Creating the JDBC Data Source

The Database Plug-in must be associated with a JDBC data source that:

  • Uses a non-XA database drive

  • Does not support global transactions (Supports Global Transactions is check box that is available when defining the WebLogic data source configuration).

When creating the JDBC data source:

  • Create a JDBC Data Source that refers to the schema under which you are running the scripts.

  • The provided Database Plug-in sample assumes that the JNDI name of this Data Source is demo/dbplugin/datasource. However, the Data Source can have any JNDI name, but the configuration XML files in the config directory needs to be updated appropriately.

  • For Database Type, select Oracle.

  • For Database Driver, select Oracle's Driver @ (Thin) Versions: 9.0.1, 9.2.0, 10.

Deselect the Supports Global Transactions check box. (This check box defaults to being selected, so you must deselect it.)

Exception

If you create a JDBC data source that uses an XA database drive or that supports global transactions, the DatabasePlugin implementation throws the exception shown in Example 5-9.

Example 5-9 Exception

An automation exception has occurred at 
AutomationDispatcherImpl.runAutomator:/automation/plugin/internal/task/
database_plugin_demo/1.0/get_employee_names/do.
The reason is: 
com.mslv.oms.automation.AutomationException: 
com.mslv.oms.automation.AutomationException: 
com.mslv.oms.util.jdbc.exception.UncategorizedSQLException:
Unable to commit transaction.
com.mslv.oms.automation.AutomationException: 
com.mslv.oms.automation.AutomationException: 
com.mslv.oms.util.jdbc.exception.UncategorizedSQLException:
Unable to commit transaction.
at com.mslv.oms.automation.plugin.AutomationEventHandlerImpl.a(Unknown Source)
at com.mslv.oms.automation.plugin.AutomationEventHandlerImpl.processMessage
(Unknown Source)
at com.mslv.oms.automation.AutomationDispatcher.onMessage(Unknown Source) 
at weblogic.ejb.container.internal.MDListener.execute(MDListener.java:429) 
at weblogic.ejb.container.internal.MDListener.transactionalOnMessage
(MDListener.java:335)
at weblogic.ejb.container.internal.MDListener.onMessage(MDListener.java:291) 
at weblogic.jms.client.JMSSession.onMessage(JMSSession.java:4060) 
at weblogic.jms.client.JMSSession.execute(JMSSession.java:3953) 
at weblogic.jms.client.JMSSession$UseForRunnable.run(JMSSession.java:4467) 
at weblogic.work.ExecuteRequestAdapter.execute(ExecuteRequestAdapter.java:21) 
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:145) 
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:117) 

Synchronous and Asynchronous Communication

Automated tasks and the automation plug-ins they trigger can handle synchronous or asynchronous communication. This topic was presented in the section on custom automation plug-ins, and is also applicable to predefined automation plug-ins. See "Asynchronous and Synchronous Communication".

Building and Deploying Automation Plug-ins

Building and deploying an automation plug-in is a matter of building and deploying the cartridge that defines the automation plug-in. See "Packaging and Building a Cartridge" and "Deploying a Cartridge".

Automating the Build and Deploy

You can also automate and build the deploy of an automation plug-in by automating the build and deploy of the cartridge that defines the automation plug-in. See "Automating the Cartridge Build and Deployment".

Troubleshooting Automations

If you encounter a problem when attempting to run an automation, you must verify that you are not using multiple versions of the automation_plugins.jar file. You do this by checking that the date and size of the file are the same in the following locations:

If the two versions of the file are not the same, use the version from the OSM installation:

  1. Copy the automation_plugins.jar file from the OSM_home/SDK/automation/automationdeploy_bin directory to the osmlib directory of your cartridge within your Eclipse workspace.

  2. Clean and rebuild the cartridge.

  3. Redeploy the cartridge.

  4. Run the automation.

Note:

When the versions of the automation_plugins.jar file are not the same, you may also encounter a marshalling error when deploying the cartridge, prior to attempting to run the automation. The marshalling error, which states that it cannot find the getProductBuildVersion() method, displays on the WebLogic console; it does not display in Design Studio when deploying the cartridge. If you encounter this error, the resolution is the same. Follow the steps described above.

Upgrading Automation Plug-ins

If you are upgrading from a previous release of OSM, and the previous release included automation plug-ins (custom or predefined), the same steps that are required to define a new automation plug-in are required to define the existing automation plug-in in the new release, with the exception of writing of the actual custom Java code.

For example, if the previous release included the automation plug-in genericPlugin, to upgrade genericPlugin in the new release you need to:

If genericPlugin is a custom automation plug-in, you can reuse the custom Java code by placing the Java source file in the cartridge src directory, compiling it, and selecting the class when defining the Custom Automation Plug-in. If genericPlugin is a predefined automation plug-in, you can select the predefined class when defining the automation, and reuse your XSLT or XQuery files by copying them into the cartridge resource directory.

Examples of Custom Automation Plug-ins

This section provides various examples of common usage for a custom automation plug-ins.

Basic Custom Automation Plug-in Example

This example shows the minimal amount of code required for a custom automation plug-in to run. This example assumes that it is triggered by an automated task.

Example 5-10 Basic Custom Automation Plug-in

01:  package com.mslv.oms.sample.atm_frame;
02:
03:  import com.mslv.oms.automation.plugin.*;
04:  import com.mslv.oms.automation.*;
05:  import java.rmi.*;
06:  
07:  public class MyPlugin extends AbstractAutomator {
08:    protected void run(String inputXML, AutomationContext context)
09:                   throws com.mslv.oms.automation.AutomationException {
10:      try {
11:        TaskContext taskContext = (TaskContext)context;
12:        String taskName = taskContext.getTaskMnemonic();
13:        System.out.println("This plug-in was triggered by task " + taskName); }
14:      catch(RemoteException ex) {
15:        throw new AutomationException(ex); }
16:      catch(AutomationException x) {
17:        throw x; }
18:    }
19:  }
 

Note:

You can use the TaskContext object to do many things, such as complete the task, suspend it, and so on.

Explanation of Example 5-10

For the automation framework to call a custom automation plug-in, the plug-in must extend either the AbstractAutomator class or the AbstractSendAutomator class. Both classes reside in the com.mslv.automation.plugin package.

Line 01 defines the package where the custom automation plug-in resides.

Lines 03-05 are import statements required for this custom automation plug-in.

Line 07 defines the arbitrary class name, MyPlugin, which extends AbstractAutomator.

Lines 08-09 define the required run method, as dictated by the parent class, AbstractAutomator.

Line 11 casts the AutomationContext object to the TaskContext object. This example assumes that the custom automation plug-in is triggered by an automated task, so the code is expecting the context input an argument to be an instance of the TaskContext object.

Line 12 calls a method on the TaskContext object to retrieve the task name.

Line 13 prints out the retrieved task name.

Basic Custom Automation Plug-in Send Example

This example shows the minimal amount of code required for a custom automation plug-in that sends data to run. This example assumes that it is triggered by an automated task.

Example 5-11 Basic Custom Automation Plug-in Send

01:  package com.mslv.oms.sample.atm_frame;
02:
03:  import com.mslv.oms.automation.plugin.*;
04:  import com.mslv.oms.automation.*;
05:  import javax.jms.TextMessage;
06:  import java.rmi.*;
07:  
08:  public class MyPlugin extends AbstractSendAutomator {
09:    protected void makeRequest(String inputXML, AutomationContext context,
10:                   TextMessage outboundMessage)
11:                   throws com.mslv.oms.automation.AutomationException {
12:      try {
13:        TaskContext taskContext = (TaskContext)context;
14:        String taskName = taskContext.getTaskMnemonic();
15:        outboundMessage.setText("Received task event for task = " + taskName);}
16:      catch(javax.jms.JMSException ex) {
17:        throw new AutomationException(ex); }
18:      catch(RemoteException x) {
19:        throw new AutomationException(x); }
20:    }
21:  }
 

Note:

You can use the TaskContext object to do many things, such as complete the task, suspend it, and so on.

Explanation of Example 5-11

For the automation framework to call a custom automation plug-in, the plug-in must extend either the AbstractAutomator class or the AbstractSendAutomator class. Both classes reside in the com.mslv.automation.plugin package.

Line 01 defines the package where the custom automation plug-in resides.

Lines 03-06 are import statements required for this custom automation plug-in.

Line 08 defines the arbitrary class name, MyPlugin, which extends AbstractSendAutomator.

Lines 09-11 define the required makeRequest method, as dictated by the parent class, AbstractSendAutomator.

Line 13 casts the AutomationContext object to the TaskContext object. This example assumes that the custom automation plug-in is triggered by an automated task, so the code can expect that the context input argument is an instance of the TaskContext object.

Line 14 calls a method on the TaskContext object to retrieve the task name.

Line 15 sets the text for the outbound message, which is sent to the external message queue defined by the automation definition. The custom code does not establish a connection to an external system or send the message; the automation framework handles the connection and sends the message upon completion of the makeRequest method.

Updating OSM Task Status Example

This example shows a custom automation plug-in that updates the OSM task status. This example assumes that the automation definition is an external event receiver that is receiving a message from ASAP, and that it is triggered by an automated task.

Example 5-12 Updating OSM Task Status

01:  package com.mslv.oms.sample.atm_frame;
02: 
03:  import com.mslv.oms.automation.plugin.*;
04:  import com.mslv.oms.automation.*;
05:  import java.rmi.*;
06:
07:  public class AsapResponseHandler extends AbstractAutomator {
08:    public void run(String inputXML, AutomationContext task)
09:                throws AutomationException {
10:      try {
11:        TaskContext tctx = (TaskContext)task;
12:        String taskName = tctx.getTaskMnemonic();
13:        AtmFrameCatalogLogger.logTaskEventResponse
14:          (taskName,tctx.getOrderId(),tctx.getOrderHistoryId(),inputXML);
15:        tctx.completeTaskOnExit("activation_successful"); }
16:      catch(RemoteException ex) {
17:        throw new AutomationException(ex); }
18:      catch(AutomationException x) {
19:        throw x; }
20:    }
21:  }

Note:

The automation framework keeps track of the order ID and the order history ID of the task that triggered the automation. Regarding line 14, there are two ways you can get the Order History ID:
  • By parsing the inputXML

  • By calling the TaskContext.getOrderHistoryId method

In most cases, these return the same order history ID. However, if you use automation to handle task events, the order history ID obtained from:

  • Parsing the inputXML returns the order history ID as it was when the task was generated

  • Calling the TaskContext.getOrderHistoryID method returns the order history ID as it is now (current)

Explanation of Example 5-12

For the automation framework to call a custom automation plug-in, the plug-in must extend either the AbstractAutomator class or the AbstractSendAutomator class. Both classes reside in the com.mslv.automation.plugin package.

Line 01 defines the package where the custom automation plug-in resides.

Lines 03-05 are import statements required for this custom automation plug-in.

Line 07 defines the arbitrary class name, AsapResponseHandler, which extends AbstractAutomator. The name reflects that this example is an external event receiver, receiving information from ASAP.

Lines 08-09 define the required run method, as dictated by the parent class, AbstractAutomator.

Line 11 casts the AutomationContext object to the TaskContext object. This example assumes that the custom automation plug-in is triggered by an automated task, so the code can expect that the context input argument is an instance of the TaskContext object.

Line 12 calls a method on the TaskContext object to retrieve the task name.

Lines 13-14 logs the information regarding the response that the plug-in is handling. AtmFrameCatalogLogger is available to this plug-in based on the package in which the plug-in resides.

Line 15 updates the task status by calling a method on the TaskContext object.

Using OrderDataUpdate Elements to Pass Order Modification Data

You use OrderDataUpdate XML elements to pass data add, modify and delete data nodes in an order.

OrderDataUpdate elements can be passed as a parameter to updateOrderData(). XSL translations whose results are passed to setUpdateOrder() must be in OrderDataUpdate format. See the OSM Javadocs for details on both methods. You can also pass OrderDataUpdate format elements to the DataChange Web Service (see the SDK schema OrderManagementWS.xsd) and UpdateOrder.request XML API call (see the SDK schema oms-xmlapi.xsd).

For update and delete operations on multi-instance nodes, you must specify the order node index as it exists in the input XML. Specify the order node index as "[@index='index_value']" where index_value is the order node index.

The example below shows how to specify the addition of an order node with OrderDataUpdate. The path attribute identifies the parent node under which to add the element:

Example 5-13 Adding an Order Node with OrderDataUpdate

<OrderDataUpdate>
  <Add path="/">
    <ProvisioningOrderResponse>
      <OrderInformation>
        <OrderNumber>1238723</OrderNumber>
      </OrderInformation>
    </ProvisioningOrderResponse>
  </Add>
</OrderDataUpdate>

The example below shows a combined update and delete operation on a multi-instance node using OrderDataUpdate. In Delete attributes, the path attribute identifies the data to delete. In Update attributes, the path attribute identifies the data to update. Indexes are required on Update and Delete attributes when modifying multi-instance nodes. Note how the order node index values are specified in the Update and Delete attributes.

Example 5-14 Modifying Multi-Instance Order Nodes with OrderDataUpdate

<OrderDataUpdate>
  <Update path="/a_group_1/a_text">This line is updated by Update request</Update> 
  <Delete path="/client_info/address[@index='80132']" /> 
  <Update path="/client_info/address[@index='76579']/city">Newark</Update> 
</OrderDataUpdate>

The example below shows a combined update and delete operation on single-instance node using OrderDataUpdate:

Example 5-15 Updating and Deleting Order Nodes with OrderDataUpdate

<OrderDataUpdate>
  <Delete path="/client_info/address[@index='80132']/city" />
  <Update path="/client_info/address[@index='76579']/city">Newark</Update>
  <Update path="/customer_details/service_address/street">55 Updated St</Update>"
  <Delete path="/service_details/current_account_number"></Delete>
</OrderDataUpdate>

See "Updating OSM With Data Received From an External System" for an example in which OrderDataUpdate XML data is created dynamically within Java code and passed to UpdateOrderData().

OrderDataUpdate Schema

The schema for OrderDataUpdate is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<schema targetNamespace="http://
www.metasolv.com/OMS/OrderDataUpdate" xmlns:odu="http://www.metasolv.com/
OMS/OrderDataUpdate" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
 
  <element name="OrderDataUpdate">
  <complexType>
    <choice maxOccurs="unbounded">
      <element ref="odu:Add"/>
      <element ref="odu:Delete"/>
      <element ref="odu:Update"/>
    </choice>
  </complexType>
  </element>
 
  <element name="Add">
    <annotation>
      <documentation>It contains a node to be added. The path attribute identifies the parent node under which to add the element.</documentation>
    </annotation>
    <complexType>
      <sequence>
        <any/>
      </sequence>
      <attribute name="path" type="string" use="required"/>
    </complexType>
  </element>
 
  <element name="Delete">
    <annotation>
      <documentation>It contains a node to be deleted. The path attribute identifies the node to delete.</documentation>
    </annotation>
    <complexType>
      <attribute name="path" type="string" use="required"/>
    </complexType>
  </element>
 
  <element name="Update">
    <annotation>
      <documentation>It contains a node to update. The path attribute identifies the node to update.</documentation>
    </annotation>
    <complexType>
      <simpleContent>
        <extension base="string">
          <attribute name="path" type="string" use="required"/>
        </extension>
      </simpleContent>
    </complexType>
  </element>
</schema>

Updating OSM With Data Received From an External System

If an automated task sends data to an external system and the external system sends a response back, you may need to update OSM with the data received from the external system. This example shows how to update data in OSM. The code is an example of updating OSM with data received from UIM when calling the server extension FRDemo.AssignFacilities.

Example 5-16 Updating OSM Data

01:  package com.mslv.oms.sample.atm_frame;
02:
03:  import com.mslv.oms.automation.plugin.*;
04:  import com.mslv.oms.automation.*;
05:  import java.rmi.*;
06:  import java.util.*;
07:  import java.io.*;
08:  import java.net.*;
09:  import org.xml.sax.*;
10:  import org.w3c.dom.*;
11:  import javax.xml.parsers.*;
12:
13:  public class UIMResponseHandler extends AbstractAutomator {
14:  
15:    public void run( String inputXML, AutomationContext task)
16:                throws AutomationException {
17:      try {
18:        TaskContext tctx = (TaskContext)task;
19:        String taskName = tctx.getTaskMnemonic();
20:        AtmFrameCatalogLogger.logTaskEventResponse
21:          (taskName,tctx.getOrderId(),tctx.getOrderHistoryId(),inputXML);
22: 
23:        // Using the data returned from UIM, update the OSM order data
24:        String updateXml = generateOMSUpdateString(inputXML);
25:        tctx.updateOrderData(updateXml);
26:
27:        // Complete the OSM task with the correct status
28:        tctx.completeTaskOnExit( "success" ); }
29:
30:      catch(OrderUpdateException ex) {
31:        throw new AutomationException( ex ); }
32:      catch(RemoteException ex) {
33:        throw new AutomationException( ex ); }
34:     catch(AutomationException x ) {
35:       throw x; }
36:    }
37:
38:    static private String generateOMSUpdateString(String inputXML) {
39:      StringBuffer osmUpdate = new StringBuffer("");
40:      try {
41:        osmUpdate = new StringBuffer
42:         ("<OrderDataUpdate xmlns=\"http://www.w3.org/2001/XMLSchema\""+
43:          " xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"" +
44:          " xmlns:odu=\"http://www.oracle.com/OMS/OrderDataUpdate\/"/" +
45:          " targetNameSpace=\"http://www.oracle.com/OMS/OrderDataUpdate\/">");
46: 
47:        // Use updates from UIM to update OSM
48:        osmUpdate.append("<AddMandatory>true</AddMandatory>");
49:        DocumentBuilderFactory docBuilderFactory =
50:          DocumentBuilderFactory.newInstance();
51:        DocumentBuilder parser = docBuilderFactory.newDocumentBuilder();
52:        Document doc = parser.parse(new StringBufferInputStream(inputXML));
53:        Element root = doc.getDocumentElement();
54:        root.normalize();
55:        NodeList a_site_list = root.getElementsByTagName("a_site information");
56:        NodeList a_site_data = a_site_list.item(0).getChildNodes();
57:
58:        for(int i=0;i<a_site_data.getLength();i++) {
59:          Element e = (Element)a_site_data.item(i);
60:          osmUpdate.append("<Add path=\"/a_site_information/");
61:          osmUpdate.append(e.getTagName());
62:          osmUpdate.append("\">");
63:          osmUpdate.append(e.getFirstChild().getNodeValue());
64:          osmUpdate.append("</Add>"); 
65:        }
66:
67:        NodeList z_site_list = root.getElementsByTagName("z_site_information");
68:        NodeList z_site_data = z_site_list.item(0).getChildNodes();
69:
70:        for(int i=0;i<a_site_data.getLength();i++) {
71:          Element e = (Element)a_site_data.item(i);
72:          osmUpdate.append("<Add path=\"/z_site_information/");
73:          osmUpdate.append(e.getTagName());
74:          osmUpdate.append("\">");
75:          osmUpdate.append(e.getFirstChild().getNodeValue());
76:          osmUpdate.append("</Add>");
77:        }
78:
79:        osmUpdate.append("</OrderDataUpdate>");
80:
81:        System.out.println(omsUpdate.toString()); }
82:
83:    catch(Exception e) {
84:      System.out.println(e.getMessage()); }
85: 
86:    return omsUpdate.toString();
87:    }
88:  }

Explanation of Example 5-16

Line 25 displays where OSM data is updated, using XML input to describe which data nodes to update.

Lines 38-87 builds the OrderDataUpdate XML string to update the data in OSM using data garnered by parsing the UIM XML. See "Using OrderDataUpdate Elements to Pass Order Modification Data".

The structure of the XML document to update OSM data is as follows:

"<OrderDataUpdate xmlns=\"http://www.w3.org/2001/XMLSchema\""+
" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"" +
" xmlns:odu=\"http://www.oracle.com/OMS/OrderDataUpdate\/"/" +
" targetNameSpace=\"http://www.oracle.com/OMS/OrderDataUpdate\/">" +
"<AddMandatory>true</AddMandatory>" +
"<Add path=\"/service_details/new_number\">98765</Add>" +
"<Update path=\"/customer_details/service_address/street\">55 Updated St</Update>" +
"<Delete path=\"/service_details/current_account_number\">" +
"</Delete>" +
"</OrderDataUpdate>";

This example illustrates adding a data node (Add path), updating a data node (Update path), and deleting a data node (Delete path).

The code from lines 38-86 differs for every order template and every external system. This code represents the translation step where you convert the data from the format of an external system to the format that OSM expects.

Line 48 specifies a mandatory parameter. If set to true, the following rules apply:

  • If you delete a mandatory node, AddMandatory replaces the node and populates it with the default value.

  • If the update is missing a mandatory node, AddMandatory adds the missing node and populates it with the default value.

    Note:

    If you add a mandatory field, but do not include a value, AddMandatory will not add a default value and the request will generate an error-error code 200.

ATM-Frame Demo Sample

When a new Provision Network task arrives in the "Received" state, run the class com.mslv.oms.sample.atm_frameObjectelplug-in, and send the data Object the JMS queue com/mslv/Objectel/RequestQueue.

Note:

When you run the ATM-frame plug-in assembly, you will receive a number of warnings from the EJB compiler (ejbc) similar to those shown below. These messages can be safely ignored.
EJB Deployment: <EJB name> has a class <class name> that is in the classpath. This class should only be located in the ejb-jar file.

Examples of Sending Messages to External Systems

Automation simplifies the process of sending messages to external systems. The automation framework does the following:

An OSM event that is sent to an external system follows this process flow:

  1. OSM creates the event.

  2. The automation framework maps the event, using the automationMap.xml configuration, onto custom business logic and calls the makeRequest method on the custom automator class.

  3. The makeRequest method performs some business logic and sets the content of the outbound message.

  4. The automation framework adds properties to the outbound message to aid in correlating external system responses to requests.

  5. The automation framework uses information from the automationMap.xml to send the JMS message to the JMS queue representing the external system.

Sending Data to an External System

This example shows a custom automation plug-in that sends data to an external system.

Example 5-17 Sending Data to an External System

01: package com.mslv.oms.sample.atm_frame;
02: 
03: import com.mslv.oms.automation.plugin.*;
04: import com.mslv.oms.automation.*;
05: import javax.jms.TextMessage;
06: import java.rmi.*;
07: 
08: public class ObjectelPlugin extends AbstractSendAutomator {
09: 
10: protected void makeRequest(String inputXML, AutomationContext context, TextMessage outboundMessage) throws com.mslv.oms.automation.AutomationException {
11:
12: try {
13: TaskContext taskContext = (TaskContext)context;
14: String taskName = taskContext.getTaskMnemonic();
15: AtmFrameCatalogLogger.logTaskEvent(taskName, taskContext.getOrderId(), taskContext.getOrderHistoryId(), inputXML);
16:
17: //
18: // Set the outgoing message
19: //
20: String xmlRequest = "<Message type=\"ni\"><iLibPlus:findFunctionalPortOnLocation.Request xmlns:iLibPlus=\"http://www.oracle.com/objectel\/"><location><DS><AG2ObjectID>189438</AG2ObjectID><AG2ParentID>189428</AG2ParentID><CLLIX>XML.CO.1</CLLIX><SiteName>XML.CO.1</SiteName></DS></location><feType>PP</feType><portType>$FEP</portType><selectionMethod>LOAD_BALANCE</selectionMethod><portSelectionAttribName><string>AG2ObjectID</string><string>AG2ParentID</string><string>AG2PortLabel</string></portSelectionAttribName><portSelectionAttribValue><string>189508</string><string>189478</string><string>F-31-OC-48</string></portSelectionAttribValue><portUpdateAttribName/><portUpdateAttribValue/></iLibPlus:findFunctionalPortOnLocation.Request></Message>";
21: outboundMessage.setText( xmlRequest );
22:
23: } catch( javax.jms.JMSException x ) {
24: throw new AutomationException( x );
25: } catch(RemoteException ex){
26: throw new AutomationException( ex );
27: }
28: }
29: }

Explanation of Example 5-17

Line 20 generates an output XML string. In this example it is hard coded. In a business case you would use business logic to transform OSM data into what the external system expects.

Line 21 sets the output data.

This code does not establish a connection to an external system or send a message. After the data is set in the code, the message is automatically sent upon exit of the makeRequest method.

Examples of Handling Responses from External Systems

In Message Property Correlation, the following steps describe how responses from external systems are handled.

  1. The plug-in populates the message content.

  2. The plug-in sets a property on the outbound JMS message, with name of the value set for correlationproperty in the automationMap.xml file, and a value decided by the business logic. For example, you could use this to correlate on a reference number.

  3. If the value of the correlationproperty in the automationMap.xml file is set to the value JMSCorrelationID, the plug-in is not required to set the property on the outbound message (as described in Step 2). The automation framework does this automatically.

  4. The automation framework saves the message properties set for each message with the event information.

  5. The automation framework sets the replyTo property on the JMS message.

  6. The external system copies the properties on the request message to the response message (line 17 in Example 5-19, "What the External System Does").

  7. The external system sends the message to the reply queue specified in the automationMap.xml file.

  8. The automation framework uses the configuration in the automationMap.xml file to map messages from external systems to plug-ins. The plug-ins are automators written by system integrators. Configuration of an automator for receiving messages from an external system are defined within Design Studio and saved to the automationMap.xml file.

  9. The automation framework uses the message properties of the response, plus the correlation information saved in step four above, to reload a Context for the response message.

  10. The run method of the external system automator is called and is passed the Context created in step 9.

  11. The automator performs business logic, such as completing the task.

Handling Responses from an External System

This example shows a custom automation plug-in that handles and processes response messages from an external system.

Example 5-18 Handling Responses from an External System

01: package com.mslv.oms.sample.atm_frame;
02:
03: import com.mslv.oms.automation.plugin.*;
04: import com.mslv.oms.automation.*;
05: import java.rmi.*;
06:
07: public class UIMResponseHandler extends AbstractAutomator {
08:
09: public void run( String inputXML, AutomationContext task)
10: throws AutomationException {
11:
12: try {
13: TaskContext tctx = (TaskContext)task;
14:
15: tctx.completeTaskOnExit( "success" );
16:
17: } catch(RemoteException ex){
18: throw new AutomationException( ex );
19: } catch(AutomationException x ) {
20: throw x;
21: }
22: }
23:}

Explanation of Example 5-18

Line 07: This automation plug-in does not need to send JMS messages to any system, so it extends AbstractAutomator.

Line 13: This plug-in is intended to process Task automation responses, so it casts the Context to a TaskContext.

Line 15: Automator completes the task.

What the External System Does

This example shows what the external system is expected to do for the message property correlation to work.

Example 5-19 What the External System Does

01: public void sendMessage(Message originalMessage) {
02: try {
03: //
04: // Set up the JMS connections
05: //
06: QueueConnectionFactory connectionFactory = (QueueConnectionFactory)jndiCtx.lookup(connectionFactoryName); 
07: QueueConnection queueConnection = connectionFactory.createQueueConnection();
08: QueueSession queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
09: Queue replyQueue = (Queue)originalMessage.getJMSReplyTo();
10: QueueSender queueSender = queueSession.createSender(replyQueue);
11:
12: //
13: // Create the message
14: //
15: TextMessage textMessage = queueSession.createTextMessage(((TextMessage)originalMessage).getText());
16: textMessage.setStringProperty("MESSAGE_NAME","ActivationResponse");
17: textMessage.setJMSCorrelationID(originalMessage.getJMSCorrelationID());
18:
19: //
20: // Send the message
21: //
22: queueSender.send(textMessage, javax.jms.DeliveryMode.PERSISTENT, javax.jms.Message.DEFAULT_PRIORITY, 1800000);
23:
24: } catch(javax.jms.JMSException ex){
25: ex.printStackTrace();
26: } catch(javax.naming.NamingException ex){
27: ex.printStackTrace();
28: }
29: }

Explanation of Example 5-19

Lines 09-10 show how the external system chooses which JMS destination to send the reply to.

Line 16 shows the external system setting a property that identifies the nature of the JMS message. This implies that the automation was defined with a message property selector select statement that matches these parameters.

Line 17 shows the external system echoing the correlation information onto the reply message. This implies that the automation was defined to correlate based on JMSCorrelationID.