Predefined Automation Plug-ins

The following topics provide automation plug-in examples for the predefined automation plug-in implementations that support XQuery and XSLT automations:

Message Example

The predefined automation plug-in examples presuppose the following sample order:

<?xml version="1.0" encoding="UTF-8"?>
<ws:CreateOrder xmlns:ws="http://xmlns.oracle.com/communications/ordermanagement">
  <ProcessSalesOrderFulfillmentEBM xmlns="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/SalesOrder/V2" xmlns:sord="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/SalesOrder/V2" xmlns:aia="http://www.oracle.com/XSL/Transform/java/oracle.apps.aia.core.xpath.AIAFunctions" xmlns:xref="http://www.oracle.com/XSL/Transform/java/oracle.tip.xref.xpath.XRefXPathFunctions">
     <corecom:EBMHeader xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
       <corecom:EBMID>2d323736303332343736363930353735</corecom:EBMID>
       <corecom:EBMName>{http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/SalesOrder/V2} ProcessSalesOrderFulfillmentEBM</corecom:EBMName>
       <corecom:EBOName>{http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/SalesOrder/V2} SalesOrderEBO</corecom:EBOName>
       <corecom:CreationDateTime>2009-03-09T18:46:36-07:00</corecom:CreationDateTime>
       <corecom:VerbCode>process</corecom:VerbCode>
       <corecom:MessageProcessingInstruction>
         <corecom:EnvironmentCode>PRODUCTION</corecom:EnvironmentCode>
       </corecom:MessageProcessingInstruction>
       <corecom:Sender>
       <!-- Information about the sender - for example, a Siebel CRM -->
       </corecom:Sender>
       <corecom:BusinessScope></corecom:BusinessScope>
       <corecom:EBMTracking></corecom:EBMTracking>
     </corecom:EBMHeader>
     <DataArea>
       <corecom:Process xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2"/>
       <ProcessSalesOrderFulfillment>
           <corecom:Identification xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                <corecom:BusinessComponentID schemeID="SALESORDER_ID" schemeAgencyID="COMMON">34333939373132333239373135353138</corecom:BusinessComponentID>
                <corecom:ID schemeID="SALESORDER_ID" schemeAgencyID="SEBL_01">ScenarioA2</corecom:ID>
                <corecom:ApplicationObjectKey>
                     <corecom:ID schemeID="SALESORDER_ID" schemeAgencyID="SEBL_01">88-2SGSG</corecom:ID>
                </corecom:ApplicationObjectKey>
                <corecom:Revision>
                    <corecom:Number>1</corecom:Number>
                </corecom:Revision>
           </corecom:Identification>
           <OrderDateTime>2009-03-09T18:40:21Z</OrderDateTime>
           <RequestedDeliveryDateTime>2009-03-10T00:00:00Z</RequestedDeliveryDateTime>
           <TypeCode>SALES ORDER</TypeCode>
           <FulfillmentPriorityCode>9</FulfillmentPriorityCode>
           <FulfillmentSuccessCode>DEFAULT</FulfillmentSuccessCode>
           <FulfillmentModeCode>DELIVER</FulfillmentModeCode>
           <SalesChannelCode/>
           <ProcessingNumber/>
           <ProcessingTypeCode/>
           <corecom:Status xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                <corecom:Code>OPEN</corecom:Code>
                <corecom:Description/>
           </corecom:Status>
           <corecom:BusinessUnitReference xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                <corecom:BusinessUnitIdentification>
                      <corecom:ID schemeID="ORGANIZATION_ID" schemeAgencyID="SEBL_01">0-R9NH</corecom:ID>
                </corecom:BusinessUnitIdentification>
           </corecom:BusinessUnitReference>
           <corecom:CustomerPartyReference xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                <corecom:CustomerPartyAccountIdentification>
                      <corecom:BusinessComponentID schemeID="CUSTOMERPARTY_ACCOUNTID" schemeAgencyID="COMMON">2d353537333130353233303536343833</corecom:BusinessComponentID>
                      <corecom:ID schemeID="CUSTOMERPARTY_ACCOUNTID" schemeAgencyID="SEBL_01">88-2PB18</corecom:ID>
                      <corecom:ApplicationObjectKey>
                            <corecom:ID schemeID="CUSTOMERPARTY_ACCOUNTID" schemeAgencyID="SEBL_01">88-2PB18</corecom:ID>
                      </corecom:ApplicationObjectKey>
                </corecom:CustomerPartyAccountIdentification>
                <corecom:CustomerPartyAccountName>Adam,10000</corecom:CustomerPartyAccountName>
                <corecom:CustomerPartyAccountContactIdentification>
                      <corecom:BusinessComponentID schemeID="CUSTOMERPARTY_CONTACTID" schemeAgencyID="COMMON">2d353130393634353031313333353938</corecom:BusinessComponentID>
                      <corecom:ApplicationObjectKey>
                           <corecom:ID schemeID="CUSTOMERPARTY_CONTACTID" schemeAgencyID="SEBL_01">88-2MKA1</corecom:ID>
                      </corecom:ApplicationObjectKey>
                </corecom:CustomerPartyAccountContactIdentification>
                <corecom:CustomerPartyAccountContactAddressCommunication>
                      <corecom:AddressCommunication>
                           <corecom:Address>
                                <!-- Enter Address Nodes -->
                           </corecom:Address>
                      </corecom:AddressCommunication>
                </corecom:CustomerPartyAccountContactAddressCommunication>
                <corecom:CustomerPartyAccountTypeCode>RESIDENTIAL </corecom:CustomerPartyAccountTypeCode>
           </corecom:CustomerPartyReference>
           <corecom:PriceListReference xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                <corecom:PriceListIdentification>
                    <corecom:ID>88-2D1YC</corecom:ID>
                </corecom:PriceListIdentification>
           </corecom:PriceListReference>
           <corecom:ShipToPartyReference xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
               <corecom:LocationReference>
                    <corecom:Address>
                        <!-- Enter Address Nodes -->
                    </corecom:Address>
               </corecom:LocationReference>
               <corecom:CustomerPartyAccountIdentification>
                    <corecom:BusinessComponentID schemeID="CUSTOMERPARTY_ACCOUNTID" schemeAgencyID="COMMON"/>
               </corecom:CustomerPartyAccountIdentification>
               <corecom:CustomerPartyAccountContactIdentification>
                    <corecom:BusinessComponentID schemeID="CUSTOMERPARTY_CONTACTID" schemeAgencyID="COMMON">2d353130393634353031313333353938</corecom:BusinessComponentID>
                    <corecom:ApplicationObjectKey>
                         <corecom:ID schemeID="CUSTOMERPARTY_CONTACTID" schemeAgencyID="SEBL_01">88-2MKA1</corecom:ID>
                    </corecom:ApplicationObjectKey>
               </corecom:CustomerPartyAccountContactIdentification>
           </corecom:ShipToPartyReference>
           <corecom:ParentSalesOrderReference xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                <corecom:SalesOrderIdentification>
                    <corecom:BusinessComponentID schemeID="SALESORDER_ID" schemeAgencyID="COMMON"/>
                </corecom:SalesOrderIdentification>
           </corecom:ParentSalesOrderReference>
           <corecom:ProjectReference xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
               <corecom:ProjectIdentfication>
                   <corecom:ID schemeID="PROJECT_ID" schemeAgencyID="SEBL_01"/>
               </corecom:ProjectIdentfication>
           </corecom:ProjectReference>
           <corecom:SalespersonPartyReference xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
               <corecom:PartyIdentification>
                    <corecom:ID schemeID="SALESPERSON_PARTYID" schemeAgencyID="SEBL_01">0-1</corecom:ID>
               </corecom:PartyIdentification>
           </corecom:SalespersonPartyReference>
           <!-- Enter order line items here -->
       </ProcessSalesOrderFulfillment>
       </DataArea>
  </ProcessSalesOrderFulfillmentEBM>
</ws:CreateOrder>

Automation Plug-in XQuery Examples

The following topics provide XQuery automation plug-in examples for automation tasks:

Internal XQuery Sender

The Automated Task editor internal XQuery automator receives task data from OSM and sends data to an external system. You can send a message to an external system using whatever protocol that system requires, such as, Telnet, HTTP, CORBA, SOAP, or web services.

The XQuery has the following characteristics:

  • XQuery context in prolog: The input document for any automated task automation plug-in is the order data defined in the Automation Task editor Task Data tab. You can access this data by declaring the TaskContext OSM Java class. Always declare this class along with the $context java binding. For example:

    declare namespace context = "java:com.mslv.oms.automation.TaskContext”;
    ...
    declare variable $context external; 
    
  • Prolog: You must declare ScriptSenderContextInvocation in any internal XQuery automator which extends ScriptReceiverContextInvocation. Always declare this class along with the $automator java binding. For example:

    declare namespace automator = "java:oracle.communications.ordermanagement.automation.plugin.ScriptSenderContextInvocation”;
    ...
    declare variable $automator external; 
    

    Oracle recommends that you use the standard Apache log class. Always declare this class along with the $log java binding.

    declare namespace log = "java:org.apache.commons.logging.Log”;
    ...
    declare variable $log external; 
    

    You must use the TextMessage class for sending JMS based messages. Always declare this class along with the $outboundMessage Java binding. You can use JMS text based messages to send OSM Web Service messages to other OSM systems, such as a service order from an OSM COM system to an OSM SOM system.

    declare namespace outboundMessage = "java:javax.jms.TextMessage";
    ...
    declare variable $outboundMessage external;
    

    Note:

    If you need to support any other protocol for sending messages, you can implement a custom Java automation plug-in for the protocol or import a helper function implementation that supports the protocol.
  • Body: The body for an internal XQuery sender can contain the following elements:

    • Use outboundMessage to set up the standard WebLogic JMS message properties for web services:

      outboundMessage:setStringProperty($outboundMessage, '_wls_mimehdrContent_Type', 'text/xml; charset=&quot;utf-8&quot;'),
      
    • Use outboundMessage to set up the OSM Web Service URI JMS message property:

      outboundMessage:setStringProperty($outboundMessage, 'URI', '/osm/wsapi'),
      
    • You can optionally use outboundMessage with the XML API to populate a JMS property value from order data. For example this code sets up an Ora_OSM_COM_OrderId parameter that is populated with the OSM order ID:

      outboundMessage:setStringProperty($outboundMessage, 'Ora_OSM_COM_OrderId', /oms:GetOrder.Response/oms:OrderID),
      
    • You can optionally use outboundMessage to set the JMS Correlation ID for the automation task before sending the message. This allows OSM to route a return message with the same corresponding JMS property value to an external XQuery automator on the same automation task as the original sender automation plug-in. For example, the following code sets the JMS correlation ID using the original OSM COM order:

      outboundMessage:setJMSCorrelationID($outboundMessage, concat($order/oms:_root/oms:messageXmlData/ebo:ProcessSalesOrderFulfillmentEBM/ebo:DataArea/ebo:ProcessSalesOrderFulfillment/corecom:Identification/corecom:ID/text(),'-COM')),
      

      If this code were applied to "Message Example," the return value would be a concatenation of ScenarioA2 and -COM: ScenarioA2-COM.

      Note:

      Other correlation scenarios are possible. For example, you may send a message from an automation task without expecting any response to the same automation task. In this scenario, another automation task further down in the process may be dedicated to receiving the response message, in which case an automation plug-in would be required that would set the correlation ID expected from the return message for that automated task. See the chapter about using automation in OSM Developer's Guide for more information about asynchronous communication scenarios.
    • Access to the task level order data (the task view) using the XML API GetOrder.Response function call. For example, the following code provides access to all order data passed into the task as a variable that is then used in other variables to access different parts of the data:

      let $order := /oms:GetOrder.Response
      let $othervariable := $order/oms:_root/oms:orderid
      
    • Any XQuery logic your plug-in requires, such as if-then or if-then-else statements that evaluate based on one or more parameters within the response message. For example, there could be a choice of two or more messages that could be sent depending on the order data values, or you might log a message.

    • A completeTaskOnExit method statement that completes the plug-in and transitions the task to the next task based on the status selected if the plug-in is intended to end the task. Typically, an automated task would contain an internal XQuery sender plug-in for sending a message and an external XQuery receiver plug-in for receiving a message, but you can also create an automation that only sends an order with another automation that receives the order. This can be useful if the response message takes a long time to return. If you are expecting the system to respond that you sent the message to, you must configure the internal XQuery sender with a reply to queue that listens for a message acknowledgement, whether the response is returned to an external automator on the same automation task or on another automation task.

The following example provides the code for an XQuery that sends a message from an OSM system in the COM role to an OSM system in the SOM role using the OSM Web Service interface and assumes JMS communication over T3S.

declare namespace automator = "java:oracle.communications.ordermanagement.automation.plugin.ScriptSenderContextInvocation";
declare namespace context = "java:com.mslv.oms.automation.TaskContext";
declare namespace log = "java:org.apache.commons.logging.Log";
declare namespace outboundMessage = "java:javax.jms.TextMessage";
declare namespace oms="urn:com:metasolv:oms:xmlapi:1";
declare namespace to="http://TechnicalOrder";
declare namespace provord="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/ProvisioningOrder/V1";
declare namespace corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2";
declare namespace env="http://schemas.xmlsoap.org/soap/envelope/";
declare namespace cord="http://oracle.communications.c2a.model/internal/order";
declare namespace ebo="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/SalesOrder/V2";
 
declare variable $automator external; 
declare variable $context external;
declare variable $log external;  
declare variable $outboundMessage external;
 
let $order := /oms:GetOrder.Response
let $technicalActions := $order/oms:_root/oms:TechnicalActions
let $ebm := $order/oms:_root/oms:messageXmlData
let $bi := $order/oms:_root/oms:CaptureInteractionResponse
 
return(
outboundMessage:setStringProperty($outboundMessage, '_wls_mimehdrContent_Type', 'text/xml; charset=&quot;utf-8&quot;'),
outboundMessage:setStringProperty($outboundMessage, 'URI', '/osm/wsapi'),
outboundMessage:setStringProperty($outboundMessage, 'Ora_OSM_COM_OrderId', /oms:GetOrder.Response/oms:OrderID),
outboundMessage:setJMSCorrelationID($outboundMessage, concat($order/oms:_root/oms:messageXmlData/ebo:ProcessSalesOrderFulfillmentEBM/ebo:DataArea/ebo:ProcessSalesOrderFulfillment/corecom:Identification/corecom:ID/text(),'-COM')),
log:info($log,concat('Sending Service Order for COM order: ', $order/oms:OrderID)),
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ord="http://xmlns.oracle.com/communications/ordermanagement">
        <soapenv:Header>
        <wsse:Security xmlns:wsse = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
        <wsse:UsernameToken xmlns:wsu = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-4799946">
        <wsse:Username>demo</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">passw0rd</wsse:Password>
        </wsse:UsernameToken>
        </wsse:Security>
        </soapenv:Header>
   <soapenv:Body>
      <ord:CreateOrder>
                <ebo:ProcessProvisioningOrderEBM xmlns:ebo="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/ProvisioningOrder/V1">
<ebo:DataArea>
                             <corecom:Process xmlns="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/ProvisioningOrder/V1" xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2" xmlns:aia="http://www.oracle.com/XSL/Transform/java/oracle.apps.aia.core.xpath.AIAFunctions" xmlns:xref="http://www.oracle.com/XSL/Transform/java/oracle.tip.xref.xpath.XRefXPathFunctions" xmlns:oms="urn:com:metasolv:oms:xmlapi:1" xmlns:provord="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/ProvisioningOrder/V1"/>
                             <provord:ProcessProvisioningOrder xmlns="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/ProvisioningOrder/V1" xmlns:aia="http://www.oracle.com/XSL/Transform/java/oracle.apps.aia.core.xpath.AIAFunctions" xmlns:xref="http://www.oracle.com/XSL/Transform/java/oracle.tip.xref.xpath.XRefXPathFunctions" xmlns:oms="urn:com:metasolv:oms:xmlapi:1" xmlns:provord="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/ProvisioningOrder/V1">
                             <corecom:SalesOrderReference>
                                  <corecom:SalesOrderIdentification>
                                      {$order/oms:_root/oms:ServiceOrder/cord:Order/cord:CustomerDetails/cord:OrderNumber/corecom:Identification/*}
                                  </corecom:SalesOrderIdentification>
                             </corecom:SalesOrderReference>
                             <provord:RequestedDeliveryDateTime>2010-07-16T08:24:38Z </provord:RequestedDeliveryDateTime>
                             <provord:TypeCode>SALES ORDER</provord:TypeCode>
                             <provord:FulfillmentPriorityCode>5</provord:FulfillmentPriorityCode>
                             <provord:FulfillmentSuccessCode>DEFAULT </provord:FulfillmentSuccessCode>
                             <provord:FulfillmentModeCode>DELIVER</provord:FulfillmentModeCode>
                             <provord:ProcessingNumber/>
                             <provord:ProcessingTypeCode/>
                             <corecom:Status xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                                 <corecom:Code>IN PROGRESS</corecom:Code>
                             </corecom:Status>
                             <corecom:BusinessUnitReference xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                                 <corecom:BusinessUnitIdentification>
                                     <corecom:ID schemeID="ORGANIZATION_ID" schemeAgencyID="SEBL_01">0-R9NH</corecom:ID>
                                 </corecom:BusinessUnitIdentification>
                             </corecom:BusinessUnitReference>
                             {$order/oms:_root/oms:ServiceOrder/cord:Order/cord:CustomerDetails/cord:CustomerParty/corecom:CustomerPartyReference}
                             <corecom:ParentProvisioningOrderReference xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                                 <corecom:ProvisioningOrderIdentification>
                                     <corecom:BusinessComponentID schemeID="SALESORDER_ID" schemeAgencyID="COMMON"/>
                                 </corecom:ProvisioningOrderIdentification>
                             </corecom:ParentProvisioningOrderReference>
                             {
                                 for $x in $order/oms:_root/oms:ServiceOrder/cord:Order/cord:ServiceOrderLine
                                 return
                                 <provord:ProvisioningOrderLine>
                                 <corecom:Identification xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                                      <corecom:BusinessComponentID>{concat($x/@id,'')} </corecom:BusinessComponentID>
                                      <corecom:ID schemeID="SALESORDER_LINEID" schemeAgencyID="SEBL_01">{concat($x/@id,'')}</corecom:ID>
                                      <corecom:ApplicationObjectKey>
                                           <corecom:ID schemeID="SALESORDER_LINEID" schemeAgencyID="SEBL_01">{concat($x/@id,'')}</corecom:ID>
                                      </corecom:ApplicationObjectKey>
                                 </corecom:Identification>
                                 <provord:OrderQuantity>1</provord:OrderQuantity>
                                 <provord:ServiceActionCode>{$x/cord:Action/text()} </provord:ServiceActionCode>
                                 <provord:ServicePointCode/>
                                 <corecom:Status xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                                     <corecom:Code>IN PROGRESS</corecom:Code>
                                 </corecom:Status>
                                 <corecom:ServiceAddress xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                                      <corecom:Identification>
                                          <corecom:BusinessComponentID schemeAgencyID="COMMON" schemeID="CUSTOMERPARTY_ADDRESSID">2d323733323231313531313836313331</corecom:BusinessComponentID>
                                          <corecom:ApplicationObjectKey>
                                               <corecom:ID schemeAgencyID="SEBL_01" schemeID="CUSTOMERPARTY_ADDRESSID">88-2KKNH</corecom:ID>
                                          </corecom:ApplicationObjectKey>
                                      </corecom:Identification>
                                      <corecom:LineOne>{$x/cord:Address/cord:LineOne/text()} </corecom:LineOne>
                                      <corecom:CityName>{$x/cord:Address/cord:CityName/text()} </corecom:CityName>
                                      <corecom:StateName>{$x/cord:Address/cord:StateName/text()} </corecom:StateName>
                                      <corecom:ProvinceName>{$x/cord:Address/cord:ProvinceName/ text()}</corecom:ProvinceName>
                                      <corecom:CountryCode>{$x/cord:Address/cord:CountryCode /text()}</corecom:CountryCode>
                                      <corecom:PostalCode>{$x/cord:Address/cord:PostalCode /text()}</corecom:PostalCode>
                                 </corecom:ServiceAddress>
                                 <corecom:ItemReference xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                                 <corecom:ItemIdentification>
                                      <corecom:BusinessComponentID schemeAgencyID="COMMON" schemeID="ITEM_ITEMID"/>
                                      <corecom:ApplicationObjectKey>
                                          <corecom:ID schemeID="ITEM_ITEMID" schemeAgencyID="SEBL_01">{concat($x/cord:InstanceID/text(),'')}</corecom:ID>
                                      </corecom:ApplicationObjectKey>
                                      <corecom:AlternateObjectKey>
                                          <corecom:ContextID/>
                                      </corecom:AlternateObjectKey>
                                      <corecom:SupplierItemID/>
                                 </corecom:ItemIdentification>
                                 <corecom:Name>{concat($x/@name,'')}</corecom:Name>
                                     <corecom:ClassificationCode listID="PermittedTypeCode"></corecom:ClassificationCode>
                                     <corecom:ClassificationCode listID="BillingProductTypeCode"/>
                                     <corecom:ClassificationCode listID="FulfillmentItemCode">{concat($x/@name,'')}</corecom:ClassificationCode>
                                     <corecom:ServiceIndicator>false</corecom:ServiceIndicator>
                                     <corecom:TypeCode>SERVICE</corecom:TypeCode>
                                     <corecom:Description/>
                                     <corecom:SpecificationGroup>
                                         <corecom:Name>ExtensibleAttributes</corecom:Name>
                                         {
                                              for $y in $x/cord:Attribute
                                              return
                                              <corecom:Specification>
                                                  <corecom:ServiceActionCode> </corecom:ServiceActionCode>
                                                  <corecom:Name>{concat($y/@name,'')} </corecom:Name>
                                                  <corecom:DataTypeCode>Text</corecom:DataTypeCode>
                                                  <corecom:Value>{$y/cord:Value/cord:value/text()} </corecom:Value>
                                              </corecom:Specification>
                                         }
                                     </corecom:SpecificationGroup>
                                     <corecom:PrimaryClassificationCode>{concat($x/@name,'')} </corecom:PrimaryClassificationCode>
                                     <corecom:ServiceInstanceIndicator>true </corecom:ServiceInstanceIndicator>
                                 </corecom:ItemReference>
                                 <provord:ProvisioningOrderLineSpecificationGroup>
                                     <corecom:SpecificationGroup>
                                          <corecom:Name>ExtensibleAttributes</corecom:Name>
                                          <corecom:Specification>
                                               <corecom:Name>ParentSalesOrderLine</corecom:Name>
                                               <corecom:Value>{$x/cord:primaryMapping/text()} </corecom:Value>
                                          </corecom:Specification>
                                         {
                                              for $z in $x/cord:secondaryMapping
                                              return
                                              <corecom:Specification>
                                                  <corecom:Name>ParentSalesOrderLine</corecom:Name>
                                              <corecom:Value>{$z/text()}</corecom:Value>
                                              </corecom:Specification>
                                         }
                                     </corecom:SpecificationGroup>
                                 </provord:ProvisioningOrderLineSpecificationGroup>
                                 </provord:ProvisioningOrderLine>
                             }
                          </provord:ProcessProvisioningOrder>
                      </ebo:DataArea>
                 </ebo:ProcessProvisioningOrderEBM>
      </ord:CreateOrder>
   </soapenv:Body>
</soapenv:Envelope>

External XQuery Automator

The Automated Task editor external XQuery automator receives task data from an external system and optionally updates OSM order data. The XQuery has the following characteristics:

  • XQuery context in prolog: The input document for any automated task automation plug-in is the order data defined in the Automation Task editor Task Data tab. You can access this data by declaring the TaskContext OSM Java class. Always declare this class along with the $context java binding. For example:

    declare namespace context = "java:com.mslv.oms.automation.TaskContext”;
    ...
    declare variable $context external;
    
  • Prolog: You must declare ScriptReceiverContextInvocation in any external XQuery automator. Typically, you can use the getOrderAsDOM method to receive external messages and the setUpdateOrder method to update the order data. Always declare this class along with the $automator java binding. For example:

    declare namespace automator = "java:oracle.communications.ordermanagement.automation.plugin.ScriptReceiverContextInvocation”;
    ...
    declare variable $automator external;
    

    Oracle recommends that you use the standard Apache log class. Always declare this class along with the $log java binding.

    declare namespace log = "java:org.apache.commons.logging.Log”;
    ...
    declare variable $log external;
    

    Another necessary declaration includes the xmlapi namespace, that you can use with the ScriptReceiverContextInvocation getOrderAsDom method to retrieve the order data for the task as a variable. This task data variable can be used in an OrderDataUpdate to update the order data with the data values received in the response message, if an update to the order data is required. For example:

    declare namespace oms="urn:com:metasolv:oms:xmlapi:1"; 
    let $taskData := fn:root(automator:getOrderAsDOM($automator))/oms:GetOrder.Response
    
  • Body: The body for an external XQuery automator can contain the following elements:

    • Any XQuery logic your plug-in requires, such as if-then or if-then-else statements that evaluate based on one or more parameters within the response message, or you might log a message.

    • A setUpdateOrder method statement that indicates whether there is an order data update. This method should be identical to what you selected in the Design Studio automation plug-in Properties View XQuery Tab Update Order check box.

    • A completeTaskOnExit method statement that completes the plug-in and transitions the task to the next task based on the status selected, if the plug-in is intended to end the task. Since there can be multiple plug-ins within a task, you would only need this method in the last plug-in listed. For example, the Failed status might transition to a fallout task, and the Succeed status may transition to the next task in the process.

    • An OrderDataUpdate statement that updates the order data based on the information returned in the response. For more information about structuring order update code, see "Using OrderDataUpdate Elements to Pass Order Modification Data".

    • Indexing: Order data in OSM often includes multiple data instances. For example, an orchestration order must include the ControlData/OrderItem and ControlData/Functions multi-instance nodes. Multi-instance nodes in solution cartridges are possible for any data element where the maximum cardinality of the node is greater than 1. When updating a multi-instance data node using automations use the node index to reference the specific node instance you want to update. The node index is available in the XML API GetOrder.Response. See OSM XML API Developer's Guide for an example of a GetOrder response message with indexing.

The following example triggers different order data updates based on the status message returned from an external system. In this case, the external system is another OSM instance running in the SOM role:

declare namespace oms="urn:com:metasolv:oms:xmlapi:1";
declare namespace automator = "java:oracle.communications.ordermanagement.automation.plugin.ScriptReceiverContextInvocation";
declare namespace context = "java:com.mslv.oms.automation.TaskContext";
declare namespace log = "java:org.apache.commons.logging.Log";
declare namespace su="http://StatusUpdate";
declare namespace so="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/SalesOrder/V2";
declare namespace corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2";
 
declare variable $automator external;
declare variable $context external;
declare variable $log external;
 
let $response := fn:root()/su:StatusUpdate (: fn:root(.) :)
let $items := fn:root()/su:StatusUpdate/su:OrderItem
 
let $taskData := fn:root(automator:getOrderAsDOM($automator))/oms:GetOrder.Response
let $component := if (fn:exists($taskData/oms:_root/oms:ControlData/oms:Functions/*/oms:componentKey)) then $taskData/oms:_root/oms:ControlData/oms:Functions/*[fn:position()=1] else ()
 
return (
if($response/su:status/text()='SOM_Completed') then (
    log:info($log,concat('Received SOM Status Update: SOM_Completed; ', $response/su:status/text())),
    automator:setUpdateOrder($automator,"true"),
    context:completeTaskOnExit($context,"success"),
    (
        <OrderDataUpdate xmlns="http://www.metasolv.com/OMS/OrderDataUpdate/2002/10/25">
            {
            for $item in $items
            for $parent in $item/su:ParentLineId
            for $orderComponentItem in $component/oms:orderItem[oms:orderItemRef/oms:LineXmlData/so:SalesOrderLine/corecom:Identification/corecom:ApplicationObjectKey/corecom:ID/text() = $parent/text()]
            return (
                    <Update path="{fn:concat("/ControlData/Functions/Provision/orderItem[@index='",fn:data($orderComponentItem/@index),"']")}">
                       <ExternalFulfillmentState>{$item/su:Status/text()}</ExternalFulfillmentState>
                    </Update>    
              )
                 
            }
        </OrderDataUpdate>
    )
) else if($response/su:status/text()='SOM_Failed') then (
 
    log:info($log,concat('Received SOM Status Update: SOM_Failed; ', $response/su:status/text())),
    automator:setUpdateOrder($automator,"true"),
    context:completeTaskOnExit($context,"failure"),
    (
        <OrderDataUpdate xmlns="http://www.metasolv.com/OMS/OrderDataUpdate/2002/10/25">
            {
            for $item in $items
            for $parent in $item/su:ParentLineId
            for $orderComponentItem in $component/oms:orderItem[oms:orderItemRef/oms:LineXmlData/so:SalesOrderLine/corecom:Identification/corecom:ApplicationObjectKey/corecom:ID/text() = $parent/text()]
            return (
                    <Update path="{fn:concat("/ControlData/Functions/Provision/orderItem[@index='",fn:data($orderComponentItem/@index),"']")}">
                       <ExternalFulfillmentState>{$item/su:Status/text()}</ExternalFulfillmentState>
                    </Update>    
              )
                 
            }
        </OrderDataUpdate>
    )
) else (
    log:info($log,concat('Received SOM Status Update: SOM_InProgress or SOM_Canceled; ', $response/su:status/text())),
    automator:setUpdateOrder($automator,"true"),
    (
        <OrderDataUpdate xmlns="http://www.metasolv.com/OMS/OrderDataUpdate/2002/10/25">
            {
            for $item in $items
            for $parent in $item/su:ParentLineId
            for $orderComponentItem in $component/oms:orderItem[oms:orderItemRef/oms:LineXmlData/so:SalesOrderLine/corecom:Identification/corecom:ApplicationObjectKey/corecom:ID/text() = $parent/text()]
            return (
                    <Update path="{fn:concat("/ControlData/Functions/Provision/orderItem[@index='",fn:data($orderComponentItem/@index),"']")}">
                       <ExternalFulfillmentState>{$item/su:Status/text()}</ExternalFulfillmentState>
                    </Update>    
              )
                 
            }
        </OrderDataUpdate>
    )
)
)

External XQuery Sender

The Automated Task editor external XQuery sender receives task data from an external system, then sends the data (after possibly transforming the data) to another external system or even returns the data back to the original external system. This XQuery combines characteristics of external XQuery automators and internal XQuery senders. For more information, see "External XQuery Automator" and "Internal XQuery Sender".

Note:

You must declare ScriptSenderContextInvocation in any external XQuery sender which inherits the ScriptReceiverContextInvocation class and methods used in internal or external automators.

Internal XQuery Automator

The Automated Task editor internal XQuery automator receives task data from OSM, then processes the data. For example, such an automation might perform computational actions on the data or other similar logic. This XQuery combines characteristics of external XQuery automators and internal XQuery senders. For more information, see "External XQuery Automator" and "Internal XQuery Sender".

Note:

You must declare ScriptReceiverContextInvocation class in an internal XQuery automator.

Automation Plug-in XSLT Examples

The following topics provide XSLT automation plug-in examples for automation tasks.

Internal XSLT Sender

The Automated Task editor internal XSLT automator receives task data from OSM and sends data to an external system. You can send a message to an external system using whatever protocol that system requires, such as, Telnet, HTTP, CORBA, SOAP, or web services.

The XSLT has the following characteristics:

  • XSLT context: The input document for any automated task automation plug-in is the order data defined in the Automation Task editor Task Data tab. You can access this data by declaring the TaskContext OSM Java class. Always declare this class along with the context java variable. For example:

    xmlns:context="java:com.mslv.oms.automation.TaskContext"
    ...
    <xsl:param name="context"/>
    
  • Initial namespace declarations: You must declare ScriptSenderContextInvocation in any internal XSLT automator which extends ScriptReceiverContextInvocation. Always declare this class along with the automator java variable. For example:

    xmlns:automator="java:oracle.communications.ordermanagement.automation.plugin.ScriptSenderContextInvocation"
    ...
    <xsl:param name="automator"/>
    

    Oracle recommends that you use the standard Apache log class. Always declare this class along with the log java variable.

    xmlns:log="java:org.apache.commons.logging.Log"
    ...
    <xsl:param name="log"/>
    

    You must use the TextMessage class for sending JMS based messages. Always declare this class along with the outboundMessage Java variable. You can use JMS text based messages to send OSM Web Service messages to other OSM systems, such as a service order from an OSM COM system to an OSM SOM system.

    xmlns:outboundMessage="java:javax.jms.TextMessage"
    ...
    <xsl:param name="outboundMessage"/>
    

    Note:

    If you need to support any other protocol for sending messages, you can implement a custom Java automation plug-in for the protocol or import a helper function implementation that supports the protocol.
  • Body: The body for an internal XSLT sender can contain the following elements:

    • Use outboundMessage to set up the standard WebLogic JMS message properties for web services:

      <xsl:variable name="outboundMessage" select="java:setStringProperty($outboundMessage, '_wls_mimehdrContent_Type', 'text/xml; charset=&quot;utf-8&quot;')"/>
      
    • Use outboundMessage to set up the OSM Web Service URI JMS message property:

      <xsl:variable name="outboundMessage" select="java:setStringProperty($outboundMessage, 'URI', '/osm/wsapi')"/>
      
    • You can optionally use outboundMessage with the XML API to populate a JMS property value from order data. For example this code sets up an Ora_OSM_COM_OrderId parameter that is populated with the OSM order ID:

      <xsl:variable name="outboundMessage" select="java:setStringProperty($outboundMessage, 'Ora_OSM_COM_OrderId', /oms:GetOrder.Response/oms:OrderID)"/>
      
    • You can optionally use outboundMessage to set the JMS Correlation ID for the automation task before sending the message. This allows OSM to route a return message with the same corresponding JMS property value to an external XQuery automator on the same automation task as the original sender automation plug-in. For example, the following code sets the JMS correlation ID using the original OSM COM order:

      <xsl:variable name="void" select="java:setJMSCorrelationID($outboundMessage, concat($order/oms:_root/oms:messageXmlData/ebo:ProcessSalesOrderFulfillmentEBM/ebo:DataArea/ebo:ProcessSalesOrderFulfillment/corecom:Identification/corecom:ID/text(),'-COM'))"/>
      

      If this code were applied to "Message Example", the return value would be a concatenation of ScenarioA2 and -COM: ScenarioA2-COM.

      Note:

      Other correlation scenarios are possible. For example, you may send a message from automation task without expecting any response to the same automation task. In this scenario, another automation task further down in the process may be dedicated to receiving the response message, in which case an automation plug-in would be required that would set the correlation ID expected from the return message for that automated task. See the chapter about using automation in OSM Developer's Guide for more information about asynchronous communication scenarios.
    • Access to the task level order data (the task view) using the XML API GetOrder.Response function call. For example, the following code provides access to all order data passed into the task as a variable that is then used in other variables to access different parts of the data:

          <xsl:template match="/">
              <xsl:variable name="order" select="oms:GetOrder.Response"/>
              <xsl:variable name="othervariable" select="$order/oms:_root/oms:orderid"/>
      
    • Any XSLT logic your plug-in requires, such as if-then or if-then-else statements that evaluate based on one or more parameters within the response message. For example, there could be a choice of two or more messages that could be sent depending on the order data values, or you might log a message.

    • A completeTaskOnExit method statement that completes the plug-in and transitions the task to the next task based on the status selected if the plug-in is intended to end the task. Typically, an automated task would contain an internal XSLT sender plug-in for sending a message and an external XSLT receiver plug-in for receiving a message, but you can also create an automation that only sends an order with another automation that receives the order. This can be useful if the response message takes a long time to return. If you are expecting the system to respond that you sent the message to, you must configure the internal XSLT sender with a reply to queue that listens for a message acknowledgement, whether the response is returned to an external automator on the same automation task or on another automation task.

The following example provides the code for an XSLT that sends a message from an OSM system in the COM role to an OSM system in the SOM role using the OSM Web Service interface and assumes JMS communication over T3S.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns="http://www.metasolv.com/OMS/OrderDataUpdate"
    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:oms="urn:com:metasolv:oms:xmlapi:1" 
xmlns:automator="java:oracle.communications.ordermanagement.automation.plugin.ScriptSenderContextInvocation"
    xmlns:context="java:com.mslv.oms.automation.TaskContext"
    xmlns:log="java:org.apache.commons.logging.Log"
    xmlns:outboundMessage="java:javax.jms.TextMessage"
    xmlns:to="http://TechnicalOrder"
    xmlns:provord="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/ProvisioningOrder/V1"
    xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2"
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:ebo="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/SalesOrder/V2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    exclude-result-prefixes="xsl java xalan oms com ser soapenv xsi"
    xmlns:fn="http://www.w3.org/2005/02/xpath-functions">

    <!-- * -->
    <xsl:param name="automator"/>
    <xsl:param name="log"/>
    <xsl:param name="context"/>
    <xsl:param name="outboundMessage"/>
 
    <!-- * -->

    <xsl:output method="xml" indent="yes" omit-xml-declaration="no" xalan:indent-amount="5"/>
    <xsl:template match="/">
        <xsl:variable name="order" select="oms:GetOrder.Response"/>
        <xsl:variable name="technicalActions" select="$order/oms:_root/oms:TechnicalActions"/>
        <xsl:variable name="ebm" select="$order/oms:_root/oms:messageXmlData"/>
        <xsl:variable name="bi" select="$order/oms:_root/oms:CaptureInteractionResponse"/>
        <xsl:variable name="outboundMessage" select="java:setStringProperty($outboundMessage, '_wls_mimehdrContent_Type', 'text/xml; charset=&quot;utf-8&quot;')"/>
        <xsl:variable name="outboundMessage" select="java:setStringProperty($outboundMessage, 'URI', '/osm/wsapi')"/>
        <xsl:variable name="outboundMessage" select="java:setStringProperty($outboundMessage, 'Ora_OSM_COM_OrderId', /oms:GetOrder.Response/oms:OrderID)"/>
        <xsl:variable name="void" select="java:setJMSCorrelationID($outboundMessage, concat($order/oms:_root/oms:messageXmlData/ebo:ProcessSalesOrderFulfillmentEBM/ebo:DataArea/ebo:ProcessSalesOrderFulfillment/corecom:Identification/corecom:ID/text(),'-COM'))"/>
        <xsl:variable name="log" select=java:info($log,concat('Sending Service Order for COM order: ', $order/oms:OrderID))"/>
        <xsl:call-template name="sendSomOrder"/>
    </xsl:template>
    <!-- ==================================
         Create the SOAP message for the sendSomOrder call
         ==================================== -->
    <xsl:template name="sendSomOrder">

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ord="http://xmlns.oracle.com/communications/ordermanagement">
        <soapenv:Header>
        <wsse:Security xmlns:wsse = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
        <wsse:UsernameToken xmlns:wsu = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-4799946">
        <wsse:Username>demo</wsse:Username>
        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">passw0rd</wsse:Password>
        </wsse:UsernameToken>
        </wsse:Security>
        </soapenv:Header>
   <soapenv:Body>
      <ord:CreateOrder>
                <ebo:ProcessProvisioningOrderEBM xmlns:ebo="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/ProvisioningOrder/V1">
<ebo:DataArea>
                             <corecom:Process xmlns="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/ProvisioningOrder/V1" xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2" xmlns:aia="http://www.oracle.com/XSL/Transform/java/oracle.apps.aia.core.xpath.AIAFunctions" xmlns:xref="http://www.oracle.com/XSL/Transform/java/oracle.tip.xref.xpath.XRefXPathFunctions" xmlns:oms="urn:com:metasolv:oms:xmlapi:1" xmlns:provord="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/ProvisioningOrder/V1"/>
                             <provord:ProcessProvisioningOrder xmlns="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/ProvisioningOrder/V1" xmlns:aia="http://www.oracle.com/XSL/Transform/java/oracle.apps.aia.core.xpath.AIAFunctions" xmlns:xref="http://www.oracle.com/XSL/Transform/java/oracle.tip.xref.xpath.XRefXPathFunctions" xmlns:oms="urn:com:metasolv:oms:xmlapi:1" xmlns:provord="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/ProvisioningOrder/V1">
                             <corecom:SalesOrderReference>
                                  <corecom:SalesOrderIdentification>
                                      {$order/oms:_root/oms:ServiceOrder/cord:Order/cord:CustomerDetails/cord:OrderNumber/corecom:Identification/*}
                                  </corecom:SalesOrderIdentification>
                             </corecom:SalesOrderReference>
                             <provord:RequestedDeliveryDateTime>2010-07-16T08:24:38Z </provord:RequestedDeliveryDateTime>
                             <provord:TypeCode>SALES ORDER</provord:TypeCode>
                             <provord:FulfillmentPriorityCode>5</provord:FulfillmentPriorityCode>
                             <provord:FulfillmentSuccessCode>DEFAULT </provord:FulfillmentSuccessCode>
                             <provord:FulfillmentModeCode>DELIVER</provord:FulfillmentModeCode>
                             <provord:ProcessingNumber/>
                             <provord:ProcessingTypeCode/>
                             <corecom:Status xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                                 <corecom:Code>IN PROGRESS</corecom:Code>
                             </corecom:Status>
                             <corecom:BusinessUnitReference xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                                 <corecom:BusinessUnitIdentification>
                                     <corecom:ID schemeID="ORGANIZATION_ID" schemeAgencyID="SEBL_01">0-R9NH</corecom:ID>
                                 </corecom:BusinessUnitIdentification>
                             </corecom:BusinessUnitReference>
                             {$order/oms:_root/oms:ServiceOrder/cord:Order/cord:CustomerDetails/cord:CustomerParty/corecom:CustomerPartyReference}
                             <corecom:ParentProvisioningOrderReference xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                                 <corecom:ProvisioningOrderIdentification>
                                     <corecom:BusinessComponentID schemeID="SALESORDER_ID" schemeAgencyID="COMMON"/>
                                 </corecom:ProvisioningOrderIdentification>
                             </corecom:ParentProvisioningOrderReference>
                             {
                                 for $x in $order/oms:_root/oms:ServiceOrder/cord:Order/cord:ServiceOrderLine
                                 return
                                 <provord:ProvisioningOrderLine>
                                 <corecom:Identification xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                                      <corecom:BusinessComponentID>{concat($x/@id,'')} </corecom:BusinessComponentID>
                                      <corecom:ID schemeID="SALESORDER_LINEID" schemeAgencyID="SEBL_01">{concat($x/@id,'')}</corecom:ID>
                                      <corecom:ApplicationObjectKey>
                                           <corecom:ID schemeID="SALESORDER_LINEID" schemeAgencyID="SEBL_01">{concat($x/@id,'')}</corecom:ID>
                                      </corecom:ApplicationObjectKey>
                                 </corecom:Identification>
                                 <provord:OrderQuantity>1</provord:OrderQuantity>
                                 <provord:ServiceActionCode>{$x/cord:Action/text()} </provord:ServiceActionCode>
                                 <provord:ServicePointCode/>
                                 <corecom:Status xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                                     <corecom:Code>IN PROGRESS</corecom:Code>
                                 </corecom:Status>
                                 <corecom:ServiceAddress xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                                      <corecom:Identification>
                                          <corecom:BusinessComponentID schemeAgencyID="COMMON" schemeID="CUSTOMERPARTY_ADDRESSID">2d323733323231313531313836313331</corecom:BusinessComponentID>
                                          <corecom:ApplicationObjectKey>
                                               <corecom:ID schemeAgencyID="SEBL_01" schemeID="CUSTOMERPARTY_ADDRESSID">88-2KKNH</corecom:ID>
                                          </corecom:ApplicationObjectKey>
                                      </corecom:Identification>
                                      <corecom:LineOne>{$x/cord:Address/cord:LineOne/text()} </corecom:LineOne>
                                      <corecom:CityName>{$x/cord:Address/cord:CityName/text()} </corecom:CityName>
                                      <corecom:StateName>{$x/cord:Address/cord:StateName/text()} </corecom:StateName>
                                      <corecom:ProvinceName>{$x/cord:Address/cord:ProvinceName/ text()}</corecom:ProvinceName>
                                      <corecom:CountryCode>{$x/cord:Address/cord:CountryCode /text()}</corecom:CountryCode>
                                      <corecom:PostalCode>{$x/cord:Address/cord:PostalCode /text()}</corecom:PostalCode>
                                 </corecom:ServiceAddress>
                                 <corecom:ItemReference xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2">
                                 <corecom:ItemIdentification>
                                      <corecom:BusinessComponentID schemeAgencyID="COMMON" schemeID="ITEM_ITEMID"/>
                                      <corecom:ApplicationObjectKey>
                                          <corecom:ID schemeID="ITEM_ITEMID" schemeAgencyID="SEBL_01">{concat($x/cord:InstanceID/text(),'')}</corecom:ID>
                                      </corecom:ApplicationObjectKey>
                                      <corecom:AlternateObjectKey>
                                          <corecom:ContextID/>
                                      </corecom:AlternateObjectKey>
                                      <corecom:SupplierItemID/>
                                 </corecom:ItemIdentification>
                                 <corecom:Name>{concat($x/@name,'')}</corecom:Name>
                                     <corecom:ClassificationCode listID="PermittedTypeCode"></corecom:ClassificationCode>
                                     <corecom:ClassificationCode listID="BillingProductTypeCode"/>
                                     <corecom:ClassificationCode listID="FulfillmentItemCode">{concat($x/@name,'')}</corecom:ClassificationCode>
                                     <corecom:ServiceIndicator>false</corecom:ServiceIndicator>
                                     <corecom:TypeCode>SERVICE</corecom:TypeCode>
                                     <corecom:Description/>
                                     <corecom:SpecificationGroup>
                                         <corecom:Name>ExtensibleAttributes</corecom:Name>
                                         {
                                              for $y in $x/cord:Attribute
                                              return
                                              <corecom:Specification>
                                                  <corecom:ServiceActionCode> </corecom:ServiceActionCode>
                                                  <corecom:Name>{concat($y/@name,'')} </corecom:Name>
                                                  <corecom:DataTypeCode>Text</corecom:DataTypeCode>
                                                  <corecom:Value>{$y/cord:Value/cord:value/text()} </corecom:Value>
                                              </corecom:Specification>
                                         }
                                     </corecom:SpecificationGroup>
                                     <corecom:PrimaryClassificationCode>{concat($x/@name,'')} </corecom:PrimaryClassificationCode>
                                     <corecom:ServiceInstanceIndicator>true </corecom:ServiceInstanceIndicator>
                                 </corecom:ItemReference>
                                 <provord:ProvisioningOrderLineSpecificationGroup>
                                     <corecom:SpecificationGroup>
                                          <corecom:Name>ExtensibleAttributes</corecom:Name>
                                          <corecom:Specification>
                                               <corecom:Name>ParentSalesOrderLine</corecom:Name>
                                               <corecom:Value>{$x/cord:primaryMapping/text()} </corecom:Value>
                                          </corecom:Specification>
                                         {
                                              for $z in $x/cord:secondaryMapping
                                              return
                                              <corecom:Specification>
                                                  <corecom:Name>ParentSalesOrderLine</corecom:Name>
                                              <corecom:Value>{$z/text()}</corecom:Value>
                                              </corecom:Specification>
                                         }
                                     </corecom:SpecificationGroup>
                                 </provord:ProvisioningOrderLineSpecificationGroup>
                                 </provord:ProvisioningOrderLine>
                             }
                          </provord:ProcessProvisioningOrder>
                      </ebo:DataArea>
                 </ebo:ProcessProvisioningOrderEBM>
      </ord:CreateOrder>
   </soapenv:Body>
</soapenv:Envelope>
</xsl:template>
    <!-- * -->
    <xsl:template match="* | @* | text()">
        <!-- do nothing -->
        <xsl:apply-templates/>
    </xsl:template>
</xsl:stylesheet>

External XSLT Automator

The Automated Task editor external XSLT automator receives task data from an external system and optionally updates OSM order data. The XSLT has the following characteristics:

  • XSLT context in prolog: The input document for any automated task automation plug-in is the order data defined in the Automation Task editor Task Data tab. You can access this data by declaring the TaskContext OSM Java class. Always declare this class along with the context java binding. For example:

    xmlns:context="java:com.mslv.oms.automation.TaskContext"
    ...
    <xsl:param name="context"/>
    
  • Prolog: You must declare ScriptReceiverContextInvocation in any external XQuery automator. Typically, you can use the getOrderAsDOM method to receive external messages and the setUpdateOrder method to update the order data. Always declare this class along with the automator java binding. For example:

        xmlns:automator="java:oracle.communications.ordermanagement.automation.plugin.ScriptReceiverContextInvocation"
    ...
    <xsl:param name="automator"/>
    

    Oracle recommends that you use the standard Apache log class. Always declare this class along with the $log java binding.

    xmlns:log="java:org.apache.commons.logging.Log"
    ...
    <xsl:param name="log"/>
    

    Another necessary declaration includes the xmlapi namespace, that you can use with the ScriptReceiverContextInvocation getOrderAsDom method to retrieve the order data for the task as a variable. This task data variable can be used in an OrderDataUpdate to update the order data with the data values received in the response message, if an update to the order data is required. For example:

    xmlns:oms="urn:com:metasolv:oms:xmlapi:1"
    <xsl:variable name="taskData" select="fn:root(java:getOrderAsDOM($automator))/oms:GetOrder.Response"/>
    
  • Body: The body for an external XSLT automator can contain the following elements:

    • Any XSLT logic your plug-in requires, such as if-then or if-then-else statements that evaluate based on one or more parameters within the response message, or you might log a message.

    • A setUpdateOrder method statement that indicates whether there is an order data update. This method should be identical to what you selected in the Design Studio automation plug-in Properties View XSLT Tab Update Order check box.

    • A completeTaskOnExit method statement that completes the plug-in and transitions the task to the next task based on the status selected, if the plug-in is intended to end the task. Since there can be multiple plug-ins within a task, you would only need this method in the last plug-in listed. For example, the Failed status might transition to a fallout task, and the Succeed status may transition to the next task in the process.

    • An OrderDataUpdate statement that updates the order data based on the information returned in the response. For more information about structuring order update code, see "Using OrderDataUpdate Elements to Pass Order Modification Data".

    • Indexing: Order data in OSM often includes multiple data instances. For example, an orchestration order must include the ControlData/OrderItem and ControlData/Functions multi-instance nodes. Multi-instance nodes in solution cartridges are possible for any data element where the maximum cardinality of the node is greater than 1. When updating a multi-instance data node using automations use the node index to reference the specific node instance you want to update. The node index is available in the XML API GetOrder.Response. See OSM XML API Developer's Guide for an example of a GetOrder response message with indexing.

The following example triggers different order data updates based on the status message returned from an external system. In this case, the external system is another OSM instance running in the SOM role:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns="http://www.metasolv.com/OMS/OrderDataUpdate" 
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:oms="urn:com:metasolv:oms:xmlapi:1"
    xmlns:automator="java:oracle.communications.ordermanagement.automation.plugin.ScriptReceiverContextInvocation"
    xmlns:context="java:com.mslv.oms.automation.TaskContext"
    xmlns:log="java:org.apache.commons.logging.Log"
    xmlns:su="http://StatusUpdate"
    xmlns:so="http://xmlns.oracle.com/EnterpriseObjects/Core/EBO/SalesOrder/V2"
    xmlns:corecom="http://xmlns.oracle.com/EnterpriseObjects/Core/Common/V2"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    exclude-result-prefixes="xsl java xalan oms soapenv xsi">
 
    <!-- * -->
    <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="taskData" select="fn:root(java:getOrderAsDOM($automator))/oms:GetOrder.Response"/>
     <xsl:variable name="response" select="fn:root()/su:StatusUpdate (: fn:root(.) :)"/>
     <xsl:variable name="items" select="fn:root()/su:StatusUpdate/su:OrderItem"/>
    <xsl:variable name="component" select="if (fn:exists($taskData/oms:_root/oms:ControlData/oms:Functions/*/oms:componentKey)) then $taskData/oms:_root/oms:ControlData/oms:Functions/*[fn:position()=1] else ()"/>
        <xsl:apply-templates/>
</xsl:template>

<!-- Match the status SOM_Complete -->
    <xsl:template match="$response[su:status/text()='SOM_Completed']">
     <xsl:variable name="log" select="java:info($log,concat('Received SOM Status Update: SOM_Completed; ', $response/su:status/text()))"/>
     <xsl:variable name="automator" select="java:setUpdateOrder($automator, true())"/>
     <xsl:variable name="context" select="java:completeTaskOnExit($context, success())"/>
     <OrderDataUpdate xmlns="http://www.metasolv.com/OMS/OrderDataUpdate/2002/10/25">
        <xsl:for-each select="su:ParentLineId">
            <xsl:variable name="parent" select="."/>
            <xsl:for-each select="$component/oms:orderItem[oms:orderItemRef/oms:LineXmlData/so:SalesOrderLine/corecom:Identification/corecom:ApplicationObjectKey/corecom:ID/text() = $parent/text()]">
                 <xsl:variable name="index" select="@index"/>
                     <Update path="{fn:concat("/ControlData/Functions/Provision/orderItem[@index='",fn:data($orderComponentItem/@index),"']")}>
                      <ExternalFulfillmentState>{$item/su:Status/text()}</ExternalFulfillmentState>
                    </Update> 
            </xsl:for-each>
        </xsl:for-each>                      
     </OrderDataUpdate>
    </xsl:template>
 
<!-- Match the status SOM_Failed -->
    <xsl:template match="$response[su:status/text()='SOM_Failed']">
     <xsl:variable name="log" select="java:info($log,concat('Received SOM Status Update: SOM_Failed; ', $response/su:status/text()))"/>
     <xsl:variable name="automator" select="java:setUpdateOrder($automator, true())"/>
     <xsl:variable name="context" select="java:completeTaskOnExit($context, success())"/>
     <OrderDataUpdate xmlns="http://www.metasolv.com/OMS/OrderDataUpdate/2002/10/25">
        <xsl:for-each select="su:ParentLineId">
            <xsl:variable name="parent" select="."/>
            <xsl:for-each select="$component/oms:orderItem[oms:orderItemRef/oms:LineXmlData/so:SalesOrderLine/corecom:Identification/corecom:ApplicationObjectKey/corecom:ID/text() = $parent/text()]">
                 <xsl:variable name="index" select="@index"/>
                     <Update path="{fn:concat("/ControlData/Functions/Provision/orderItem[@index='",fn:data($orderComponentItem/@index),"']")}>
                      <ExternalFulfillmentState>{$item/su:Status/text()}</ExternalFulfillmentState>
                     </Update> 
            </xsl:for-each>
        </xsl:for-each>
     /OrderDataUpdate>
    </xsl:template>
 
    <xsl:template match="$response[su:status/text()='']">
     <xsl:variable name="log" select="java:info($log,concat('Received SOM Status Update: SOM_InProgress or SOM_Canceled; ', $response/su:status/text()))"/>
     <xsl:variable name="automator" select="java:setUpdateOrder($automator, false())"/>
     <xsl:variable name="context" select="java:completeTaskOnExit($context, success())"/>
     <OrderDataUpdate xmlns="http://www.metasolv.com/OMS/OrderDataUpdate/2002/10/25">
        <xsl:for-each select="su:ParentLineId">
            <xsl:variable name="parent" select="."/>
            <xsl:for-each select="$component/oms:orderItem[oms:orderItemRef/oms:LineXmlData/so:SalesOrderLine/corecom:Identification/corecom:ApplicationObjectKey/corecom:ID/text() = $parent/text()]">
                 <xsl:variable name="index" select="@index"/>
                     <Update path="{fn:concat("/ControlData/Functions/Provision/orderItem[@index='",fn:data($orderComponentItem/@index),"']")}>
                      <ExternalFulfillmentState>{$item/su:Status/text()}</ExternalFulfillmentState>
                     </Update> 
            </xsl:for-each>
        </xsl:for-each>
     </OrderDataUpdate>
    </xsl:template>
 
<!-- * -->
    <xsl:template match="* | @* | text()">
        <!-- do nothing -->
        <xsl:apply-templates/>
    </xsl:template>
</xsl:stylesheet>

External XSLT Sender

The Automated Task editor external XSLT sender receives task data from an external system, then sends the data (after possibly transforming the data) to another external system or even returns the data back to the original external system. This XSLT combines characteristics of external XSLT automators and internal XSLT senders. For more information, see "External XSLT Automator" and "Internal XSLT Sender".

Note:

You must declare ScriptSenderContextInvocation in any external XSLT sender which inherits the ScriptReceiverContextInvocation class and methods used in internal or external automators.

Internal XSLT Automator

The Automated Task editor internal XSLT automator receives task data from OSM, then processes the data. For example, such an automation might perform computational actions on the data or other similar logic. This XSLT combines characteristics of external XSLT automators and internal XSLT senders. For more information, see "External XSLT Automator" and "Internal XSLT Sender".

Note:

You must declare ScriptReceiverContextInvocation class in an internal XSLT automator.

Automation Plug-in Examples for Events, Jeopardies, and Notifications

The following topics provide XQuery automation plug-in examples for:

Event Automators

An event automation plug-in can be triggered when an order or a task transitions into a defined milestone. The automation can be any internal XQuery, XSLT, or custom automation since the milestone event, by definition, can only be triggered by milestones happening within an order or a task. For more information about the characteristics for these automations, see "Automation Plug-in XQuery Examples", "Automation Plug-in XSLT Examples", and "Custom Java Automation Plug-ins".

Note:

For an event automation plug-in you must declare the OrderNotificationContext instead of TaskContext. For example:

declare namespace context = "java:com.mslv.oms.automation.OrderNotificationContext”;

The following example is an internal sender automation plug-in that uses methods available to the OrderNotificationContext class to get milestone data from the order and sends an notification message to an external system. Because this sender does not expect a response message (a fire-and-forget message), you must use the OrderNotificationContext class ackNotificationOnExit method to clear the JMS correlation ID for the notification. Also, events do not transition tasks, so you must not specify completeTaskOnExit in a notification.

declare namespace saxon="http://saxon.sf.net/";
declare namespace xsl="http://www.w3.org/1999/XSL/Transform";
declare namespace log = "java:org.apache.commons.logging.Log";
declare namespace outboundMessage = "java:javax.jms.TextMessage";
declare namespace oms="urn:com:metasolv:oms:xmlapi:1";
declare namespace osm="http://xmlns.oracle.com/communications/ordermanagement/model";
declare namespace context = "java:com.mslv.oms.automation.OrderNotificationContext";
 
declare variable $context external;
declare variable $log external;
declare variable $outboundMessage external;
 
let $taskData := fn:root(.)/oms:GetOrder.Response
let $correlationId := $taskData/oms:_root/oms:Id/text() 
let $controlDataArea := if (fn:exists($taskData/oms:_root/oms:ControlData)) 
                            then $taskData/oms:_root/oms:ControlData 
                            else ()
 
return
(
log:info($log, fn:concat('COMCartridge: Invoking orderCompletionNotification for order[',$taskData/oms:OrderID/text(),'] with correlation [', $correlationId,']')),
context:ackNotificationOnExit($context),
outboundMessage:setStringProperty($outboundMessage, "COMCorrelationID", $correlationId),
outboundMessage:setStringProperty($outboundMessage, "SUB_FOLDER_NAME", $taskData/oms:_root/oms:OrderNumber/text()),
outboundMessage:setStringProperty($outboundMessage, "COMMilestone", "COMOrderCompleteEvent"),
<orderNotification xmlns="http://xmlns.oracle.com/communications/sce/dictionary/CommonResourcesCartridge/Notifications"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <OSMOrderId>{$taskData/oms:OrderID/text()}</OSMOrderId>
    <Id>{$correlationId}</Id>
    <OrderNumber>{$taskData/oms:_root/oms:OrderNumber/text()}</OrderNumber>
    {
    for $serviceInstance in $controlDataArea/oms:OrderItem
    return
        <Instance>
            <InstanceID>{$serviceInstance/oms:instanceID/text()}</InstanceID>
            <OrderLineId>{$serviceInstance/oms:orderLineId/text()}</OrderLineId>
            <Status>{$serviceInstance/oms:status/text()}</Status>
        </Instance>
    }
</orderNotification>
)

Jeopardy Automators

An order jeopardy automation plug-in can be triggered when a particular condition is met, such as when a task exceeds the expected duration configured for the task or when the process that the task is a part of exceeds its excepted process duration. The automation can be any internal XQuery, XSLT, or custom automation since the jeopardy, by definition, can only be triggered by events happening within the task or the process. For more information about the characteristics for these automations, see "Automation Plug-in XQuery Examples", "Automation Plug-in XSLT Examples", and "Custom Java Automation Plug-ins".

Note:

For an order level jeopardy automation plug-in you must declare the OrderNotificationContext instead of TaskContext. For example:

declare namespace context = "java:com.mslv.oms.automation.OrderNotificationContext”;

For a task level jeopardy automation plug-in, if the task level jeopardy condition Multiple events per Task instance is set indicating that the task is a multi-instance task and the event should be triggered for each instance, then you must declare TaskNotificationContext so that the task data is passed to each instance of the event. If the task is not a multi-instance task, then OrderNotificationContext should be declared.

The following example is an internal automator plug-in that uses methods available to the OrderNotificationContext class to get notification details from the task in combination with the XML API Notification.Request that logs the jeopardy notification details. Other jeopardy examples could also send an email or trigger a pager.

declare namespace oms="urn:com:metasolv:oms:xmlapi:1";
declare namespace automator = "java:oracle.communications.ordermanagement.automation.plugin.ScriptReceiverContextInvocation";
declare namespace context = "java:com.mslv.oms.automation.OrderNotificationContext";
declare namespace log = "java:org.apache.commons.logging.Log";
 
declare option saxon:output "method=xml";
declare option saxon:output "saxon:indent-spaces=2";
 
declare variable $automator external;
declare variable $context external;
declare variable $log external;
 
declare variable $exitStatus := "success";
 
let $thisOrderId := context:getOrderId($context)
(: let $taskMnemonic := context:getTaskMnemonic($context) :)
let $notificationName := context:getNotificationName($context)
let $notificationType := context:getNotificationType($context)
let $orderId := fn:root(.)/oms:GetOrder.Response/oms:_root/oms:orderId
let $xmlRequest := '<Notifications.Request xmlns="urn:com:metasolv:oms:xmlapi:1" />'
let $notifications := context:processXMLRequest($context, $xmlRequest)
return (
  log:info($log, fn:concat("XQuery jeopardy: order[", $thisOrderId, 
    "], notificationContext [", context:getClass($context), 
    "], notificationName[", $notificationName, 
    "], notificationType[", $notificationType, 
    "], notifications[", $notifications, 
    "] entered order ID [", $orderId/text(), "]")),
  <placeholder/>
)

Order Notification Automation Plug-ins

An order notification automation plug-in can be triggered when specified data changes in the order. For example, you can monitor order status changes using the orchestration data element ControlData/OrderFulfillmentState or individual order item status changes using ControlData/OrderItem/OrderItemFulfillmentState so OSM triggers an internal XQuery sender automation plug-in that sends these status changes to another system, such as from a SOM OSM system to a COM OSM system, or from a COM OSM system to a CRM.

The automation can be any internal XQuery, XSLT, or custom automation since the notification, by definition, can only be triggered by a change in the internal order data. For more information about the characteristics for these automations, see "Automation Plug-in XQuery Examples", "Automation Plug-in XSLT Examples", and "Custom Java Automation Plug-ins".

Note:

For an order notification automation plug-in you must declare the OrderDataChangeNotificationContext instead of TaskContext. For example:

declare namespace context = "java:com.mslv.oms.automation.OrderDataChangeNotificationContext”;

The following example is an internal XQuery sender that sends any order and order item fulfillment state changes to another OSM system. It also provides stubs for transforming the fulfillment states to external system message formats.

declare namespace osm="urn:com:metasolv:oms:xmlapi:1";
declare namespace log = "java:org.apache.commons.logging.Log";
declare namespace to="http://TechnicalOrder";
declare namespace automator = "java:oracle.communications.ordermanagement.automation.plugin.ScriptSenderContextInvocation";
declare namespace su="http://StatusUpdate";
declare namespace context = "java:com.mslv.oms.automation.OrderDataChangeNotificationContext”;
declare namespace outboundMessage = "java:javax.jms.TextMessage";

declare variable $log external;
declare variable $outboundMessage external;

(: 
   This function is for indication purposes only.
   OSM Fulfillment State can be mapped according the expectation of Upstream 
:)
declare function local:getUpstreamFulfillmentState($fulfillmentState as xs:string) as xs:string {
    (: fn:concat('Order_Upstream_' , $fulfillmentState) :)
    fn:concat('' , $fulfillmentState)
};

(: 
   This function is for indication purposes only.
   OSM Fulfillment State can be mapped according the expectation of Upstream 
:)
declare function local:getUpstreamOrderItemFulfillmentState($fulfillmentState as xs:string) as xs:string {
    (: fn:concat('OrderItem_Upstream_' , $fulfillmentState) :)
    fn:concat('' , $fulfillmentState)
};

let $order := ..//osm:GetOrder.Response
let $orderFulfillmentState := $order/osm:_root/osm:ControlData/osm:OrderFulfillmentState
let $mappedUpstreamFulfillmentState := if(exists($orderFulfillmentState)) then local:getUpstreamFulfillmentState($orderFulfillmentState/text()) else ()

return
(
log:info($log,'Sending Upstream Fulfillment State'),
outboundMessage:setStringProperty($outboundMessage, "SOMTOMCorrelationHeader", concat($order/osm:_root/osm:messageXmlData/to:TechnicalOrder/to:SOMOrderId/text(),'-SOM')),
if (fn:count($order/osm:_root/osm:ControlData/osm:OrderItem)=0) then (
<StatusUpdate xmlns="http://StatusUpdate">
<numSalesOrder>{$order/osm:Reference/text()}</numSalesOrder>
<numOrder>{$order/osm:OrderID/text()}</numOrder>
<typeOrder>{$order//osm:OrderHeader/osm:typeOrder/text()}</typeOrder>
<errorCode>0</errorCode>
<status>cancelled</status>
</StatusUpdate>
) else (
<StatusUpdate xmlns="http://StatusUpdate">
<numSalesOrder>{$order/osm:Reference/text()}</numSalesOrder>
<numOrder>{$order/osm:OrderID/text()}</numOrder>
<typeOrder>{$order//osm:OrderHeader/osm:typeOrder/text()}</typeOrder>
<errorCode>0</errorCode>
<status>{$mappedUpstreamFulfillmentState}</status>
{
    for $orderItem in $order/osm:_root/osm:ControlData/osm:OrderItem
    where exists($orderItem/osm:OrderItemFulfillmentState)
    return 
        <OrderItem>
            <LineName>{$orderItem/osm:LineName/text()}</LineName>
            <LineId>{$orderItem/osm:LineId/text()}</LineId>
            <ParentLineId>{$orderItem/osm:ParentLineId/text()}</ParentLineId>
            <SpecificationName>{$orderItem/osm:TypeCode/text()}</SpecificationName>
            <Status>{local:getUpstreamOrderItemFulfillmentState($orderItem/osm:OrderItemFulfillmentState/text())}</Status>
        </OrderItem>
    }
</StatusUpdate>
)
)