Wednesday, November 13, 2019

12c SOA - Use of call template

Call template is usually called named templates to the XSLT map. These templates can be edited within the XSLT Map Editor. We can invoke named templates by using the xsl:call-template instruction.

Use case:
Here I will show you how to get the time Zone Hour AM PM as "9:00AM" from the input as orientationStartDateTime "2019-11-11T09:00:00" using the call template.

Create a SOA Project

 Select composite with BPEL Process
 Select Synchronous BPEL Process
 Modify the schema
 <?xml version="1.0" encoding="UTF-8"?>
<schema attributeFormDefault="unqualified"
                elementFormDefault="qualified" targetNamespace="http://xmlns.oracle.com/SOAApplication/Project1/CallTemplateBPELProcess"
                xmlns="http://www.w3.org/2001/XMLSchema">
                <element name="process">
                                <complexType>
                                                <sequence>
                                                                <element name="orientationStartDateTime" type="string"/>
                                                </sequence>
                                </complexType>
                </element>
                <element name="processResponse">
                                <complexType>
                                                <sequence>
                                                                <element name="timeZoneHourAMPM" type="string"/>
                                                </sequence>
                                </complexType>
                </element>
</schema>
 Drag and drop a Transformation activity from Components pallet
 Select the source and Target payloads
 Open the XSLT
 Add the call template

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:ns0="http://xmlns.oracle.com/SOAApplication/Project1/CallTemplateBPELProcess"
                xmlns:socket="http://www.oracle.com/XSL/Transform/java/oracle.tip.adapter.socket.ProtocolTranslator"
                xmlns:oracle-xsl-mapper="http://www.oracle.com/xsl/mapper/schemas"
                xmlns:dvm="http://www.oracle.com/XSL/Transform/java/oracle.tip.dvm.LookupValue"
                xmlns:mhdr="http://www.oracle.com/XSL/Transform/java/oracle.tip.mediator.service.common.functions.MediatorExtnFunction"
                xmlns:oraxsl="http://www.oracle.com/XSL/Transform/java"
                xmlns:oraext="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.ExtFunc"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                xmlns:xp20="http://www.oracle.com/XSL/Transform/java/oracle.tip.pc.services.functions.Xpath20"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xref="http://www.oracle.com/XSL/Transform/java/oracle.tip.xref.xpath.XRefXPathFunctions"
                exclude-result-prefixes="oracle-xsl-mapper xsi xsd xsl ns0 socket dvm mhdr oraxsl oraext xp20 xref"
                xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype"
                xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
  <oracle-xsl-mapper:schema>
    <!--SPECIFICATION OF MAP SOURCES AND TARGETS, DO NOT MODIFY.-->
    <oracle-xsl-mapper:mapSources>
      <oracle-xsl-mapper:source type="WSDL">
        <oracle-xsl-mapper:schema location="../WSDLs/CallTemplateBPELProcess.wsdl"/>
        <oracle-xsl-mapper:rootElement name="process"
                                       namespace="http://xmlns.oracle.com/SOAApplication/Project1/CallTemplateBPELProcess"/>
      </oracle-xsl-mapper:source>
    </oracle-xsl-mapper:mapSources>
    <oracle-xsl-mapper:mapTargets>
      <oracle-xsl-mapper:target type="WSDL">
        <oracle-xsl-mapper:schema location="../WSDLs/CallTemplateBPELProcess.wsdl"/>
        <oracle-xsl-mapper:rootElement name="processResponse"
                                       namespace="http://xmlns.oracle.com/SOAApplication/Project1/CallTemplateBPELProcess"/>
      </oracle-xsl-mapper:target>
    </oracle-xsl-mapper:mapTargets>
    <!--GENERATED BY ORACLE XSL MAPPER 12.2.1.0.0(XSLT Build 151013.0700.0085) AT [WED NOV 13 11:17:16 IST 2019].-->
  </oracle-xsl-mapper:schema>
  <!--User Editing allowed BELOW this line - DO NOT DELETE THIS LINE-->
  <xsl:template match="/">
    <xsl:variable name="orientationStartDateTime" select="/ns0:process/ns0:orientationStartDateTime"/>
    <xsl:variable name="hour" select="xp20:hours-from-dateTime($orientationStartDateTime)"/>
    <xsl:variable name="amPm"
                  select="substring(xp20:format-dateTime($orientationStartDateTime, '[D] [MNn] [Y] [h]:[m01][PN,*-2]'),string-length(xp20:format-dateTime($orientationStartDateTime, '[D] [MNn] [Y] [h]:[m01][PN,*-2]'))-1)"/>
    <ns0:processResponse>
      <xsl:variable name="timeZoneHourAMPM">
<!-- Call template -->
        <xsl:call-template name="timeZoneHour">
          <xsl:with-param name="hour" select="$hour"/>
          <xsl:with-param name="startDateTime" select="$orientationStartDateTime"/>
          <xsl:with-param name="amPm" select="$amPm"/>
        </xsl:call-template>
      </xsl:variable>
      <ns0:timeZoneHourAMPM>
        <xsl:value-of select="$timeZoneHourAMPM"/>
      </ns0:timeZoneHourAMPM>
    </ns0:processResponse>
  </xsl:template>
<!--Called template definition-->
  <xsl:template name="timeZoneHour">
    <xsl:param name="hour"/>
    <xsl:param name="startDateTime"/>
    <xsl:param name="amPm"/>
    <xsl:variable name="minutes">
      <xsl:choose>
        <xsl:when test="xp20:minutes-from-dateTime($startDateTime) &lt; 10">
          <xsl:value-of select="concat(xp20:minutes-from-dateTime($startDateTime),'0')"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:value-of select="xp20:minutes-from-dateTime($startDateTime)"/>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:choose>
      <xsl:when test="$hour > 12">
        <xsl:value-of select="concat($hour -12,':',$minutes,'PM')"/>
      </xsl:when>
      <xsl:when test="$hour = 0">
        <xsl:value-of select="concat(12,':',$minutes,'AM')"/>
      </xsl:when>
      <xsl:when test="$hour &lt; 0">
        <xsl:value-of select="concat($hour + 12,':',$minutes,'PM')"/>
      </xsl:when>
      <xsl:when test="$hour &lt; 12">
        <xsl:value-of select="concat($hour ,':',$minutes,'AM')"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="concat($hour,':',$minutes,$amPm)"/>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

Deploy and test from EM console


Another call template sample code to get the following date format from Datetime format.
Input: orientationStartDateTime "2019-11-11T09:00:00
Output: Date: Monday, November 11th, 2019

Call Template:
<xsl:call-template name="date-format">
<xsl:with-param name="yyyy-mm-dd" select="concat(xp20:year-from-dateTime($OrientationStartDateTime),'-',xp20:month-from-dateTime($OrientationStartDateTime),'-',xp20:day-from-dateTime($OrientationStartDateTime))"/>
</xsl:call-template>
Called template:
<xsl:template name="date-format">
      <xsl:param name="yyyy-mm-dd"/>
      <xsl:variable name="yyyy" select="substring-before($yyyy-mm-dd, '-')"/>
      <xsl:variable name="mm-dd" select="substring-after($yyyy-mm-dd, '-')"/>
      <xsl:variable name="mm" select="substring-before($mm-dd, '-')"/>
      <xsl:variable name="dd" select="substring-after($mm-dd, '-')"/>
      <xsl:variable name="Y">
         <xsl:choose>
            <xsl:when test="$mm &lt; 3">
               <xsl:value-of select="$yyyy - 1"/>
            </xsl:when>
            <xsl:otherwise>
               <xsl:value-of select="$yyyy + 0"/>
            </xsl:otherwise>
         </xsl:choose>
      </xsl:variable>
      <xsl:variable name="y" select="$Y mod 100"/>
      <xsl:variable name="c" select="floor($Y div 100)"/>
      <xsl:variable name="d" select="$dd+0"/>
      <xsl:variable name="m">
         <xsl:choose>
            <xsl:when test="$mm &lt; 3">
               <xsl:value-of select="$mm + 12"/>
            </xsl:when>
            <xsl:otherwise>
               <xsl:value-of select="$mm + 0"/>
            </xsl:otherwise>
         </xsl:choose>
      </xsl:variable>
      <xsl:variable name="w" select="(($d + floor(($m + 1) * 2.6) + $y + floor($y div 4) + floor($c div 4) - $c * 2 - 1)+70) mod 7"/>
      <xsl:variable name="www">
         <xsl:choose>
            <xsl:when test="$w = 0">Sunday</xsl:when>
            <xsl:when test="$w = 1">Monday</xsl:when>
            <xsl:when test="$w = 2">Tuesday</xsl:when>
            <xsl:when test="$w = 3">Wednesday</xsl:when>
            <xsl:when test="$w = 4">Thursday</xsl:when>
            <xsl:when test="$w = 5">Friday</xsl:when>
            <xsl:when test="$w = 6">Saturday</xsl:when>
         </xsl:choose>
      </xsl:variable>
      <xsl:variable name="mmm">
         <xsl:choose>
            <xsl:when test="$mm =  1">January</xsl:when>
            <xsl:when test="$mm =  2">February</xsl:when>
            <xsl:when test="$mm =  3">March</xsl:when>
            <xsl:when test="$mm =  4">April</xsl:when>
            <xsl:when test="$mm =  5">May</xsl:when>
            <xsl:when test="$mm =  6">June</xsl:when>
            <xsl:when test="$mm =  7">July</xsl:when>
            <xsl:when test="$mm =  8">August</xsl:when>
            <xsl:when test="$mm =  9">September</xsl:when>
            <xsl:when test="$mm = 10">October</xsl:when>
            <xsl:when test="$mm = 11">November</xsl:when>
            <xsl:when test="$mm = 12">December</xsl:when>
         </xsl:choose>
      </xsl:variable>
      <xsl:variable name="th">
         <xsl:choose>
            <xsl:when test="$dd = 1">st</xsl:when>
            <xsl:when test="$dd = 21">st</xsl:when>
            <xsl:when test="$dd = 31">st</xsl:when>
            <xsl:when test="$dd = 2">nd</xsl:when>
            <xsl:when test="$dd = 22">nd</xsl:when>
            <xsl:when test="$dd = 3">rd</xsl:when>
            <xsl:when test="$dd = 23">rd</xsl:when>
            <xsl:otherwise>th</xsl:otherwise>
         </xsl:choose>
      </xsl:variable>
      <xsl:value-of select="concat($www, ', ', $mmm, ' ', $d,$th,', ',$yyyy)"/>
   </xsl:template>

Tuesday, November 12, 2019

12c SOA - Dehydrate activity in BPEL to commit transaction

By default, dehydration points are set on activities such as a receive, onMessage, onAlarm, and wait. The dehydrate activity enables you to explicitly specify a dehydration point. This activity acts as a dehydration point to automatically maintain long-running asynchronous processes and their current state information in a database while they wait for asynchronous callbacks. Storing the process in a database preserves the process and prevents any loss of state or reliability if a system shuts down or a network problem occurs. This feature increases both BPEL process reliability and scalability.

The bpelx:dehydrate extension implements dehydration. For BPEL projects that
support BPEL version 1.1, the syntax is as follows:
<bpelx:dehydrate name="DehydrateInstance"/>
For BPEL projects that support BPEL version 2.0, the syntax is as shown in the
following example:
<extensionActivity>
<bpelx:dehydrate name="DehydrateInstance"/>
</extensionActivity>

Use Case:
TBD

For a use case click here dehyrate

12c SOA - Oracle BPEL Dehydration

BPEL dehydration process:
  • BPEL dehydration process is the action from the BPEL engine to compress and store the BPEL instances into the database. The incoming messages are stored in the database for processing later by worker threads.
  • Storing the current status of the BPEL process(i.e. long running process, asynchronous process) into the database tables is known as dehydration.
  • SOA_INFRA schema is the dehydration store which contains tables to hold the meta data of the process.
Why Dehydration
  • Long running process or processes waiting for response consumes memory and CPU While waiting for the response the bpel engine can store the process, thus freeing up server resources.
  • To increase both Reliability and Scalability of the BPEL process.
  • You can also use it to support clustering and failover.
  • Over the life cycle of the BPEL instance, the instance with the current state of execution may be saved in database.
Note: BPEL Activity is dehydrated immediately after execution and recorded in the dehydration store. It provides better failover protection, but may impact performance if the BPEL process accesses the dehydration store frequently.

Synchronous Process
  • Process gets dehydrated only at the end of the process.
  • Using Dehydrate activity we can explicitly dehydrate process state if required.
Asynchronous Process
  • Automatically dehydrated the process based on the activities used.
When dehydration occurs:

When the BPEL instance encounters a mid-process breakpoint activity (not including the initial receive). The activities are used : 
  • a mid-receive activities(without create instance). 
  • Pick (onMessage & onAlarm) activity
  • just before wait activity (depends on the duration)
  • Dehydrate(11g) / Checkpoint(10g)
  • Commit(Java embedded)
  • a (implicit) transaction is committed
That is where an existing BPEL instance must wait for an event, which can be either a timer expiration or message arrival. When the event occurs (the alarm expires or the message arrives), the instance is loaded from the dehydration store and execution is resumed. This type of dehydration occurs only in durable processes, which have mid-process breakpoint activities. A transient process does not have any mid process breakpoint activities.
    When the BPEL instance encounters a non-idempotent activity
      When Oracle BPEL Server recovers after a crash, it retries the activities in the process instance. However, it should only retry the idempotent activities. Therefore, when Oracle BPEL Server encounters a non-idempotent activity, it dehydrates it. This enables Oracle BPEL Server to memorize that this activity was performed once and is not performed again when Oracle BPEL Server recovers from a crash.
          Idempotent activities are those activities where the result is the same irrespective of no. of times you execute the process.
              Repeated invocations have the same effect as one invocation.
                  E.g. Read only services, Receive activity

                  When RequiresNew BPEL transaction is completed or When the BPEL instance finishes
                  At the end of the BPEL process, Oracle BPEL Server saves the process instance to the dehydration store, unless you explicitly configure it not to do so. This happens to both durable and transient processes.

                  Note: A BPEL invoke activity is by default (true) an idempotent activity, meaning that the BPEL process does not dehydrate instances immediately after invoke activities. Therefore, if idempotent is set to true and Oracle BPEL Server fails right after an invoke activity executes, Oracle BPEL Server performs the invoke again after restarting. This is because no record exists that the invoke activity has executed. This property is applicable to both durable and transient processes. If idempotent is set to false, the invoke activity is dehydrated immediately after execution and recorded in the dehydration store. If Oracle BPEL Server then fails and is restarted, the invoke activity is not repeated, because Oracle BPEL Process Manager sees that the invoke already executed.

                  Idempotent vs non idempotent activities
                  Idempotent:Activities which can be retried are called idempotent activities. Examples are : assign activity, invoke activity etc. So if the BPEL process is recovered from the dehydration store , then these activities are retried again (idempotent activities are not stored in dehydration store if there is no dehydration activity like checkpoint() ) .
                  Non idempotent: Activities are those which causes the BPEL process to dehydration and so there state is saved into dehydration store. If the BPEL process is recovered from the dehydration store, these activities are not retried . Examples are : wait activity, mid point receive activity, pick activity , checkpoint() etc.

                  So when you specify the idempotent property as "false" in the partner link of a BPEL process , this becomes non idempotent and cause the BPEL process for dehydration and so a commit occurs . This is another way of ending the current transaction of a BPEL process and start a new one.

                  Types of BPEL Process
                  When and how dehydration occurs differ based on process types. Based on the dehydration we can categorize process in to 2 categories

                  Transient Process: Oracle BPEL server dehydrates the process instance only at the end of the process. If server crashes in middle of the running process instance, the instances will not be visible in EM
                  Durable Process: Oracle BPEL Server dehydrates the process instance in-flight at all midprocess breakpoint and non-idempotent activities, plus the end of the process. When the server crashes, this process instance appears in Oracle BPEL Control up to the last dehydration point (breakpoint activity) once the server restarts. If the server crashes before the process instance reaches the first midprocess breakpoint activity, the instance is not visible in Oracle BPEL Control after the server restarts.

                  Important Notes:
                  • Remember that theses dehydration statement must be avoided in synchronous BPEL process.
                  • Idempotence is a mathematical term that basically means that calling a function multiple times doesn’t change the result for example f(f(x))=f(x).
                  • What does it mean for messaging service system ? If a service receives the same message again, it should be able to handle it without changing the state of the system. For example; in a bank scenario you wouldn’t want that withdraw message to be processed more than once !
                  • An idempotent activity in BPEL (for example, an assign activity or an invoke activity) is an activity that can be retried
                  • To ensure data consistency, the dehydration database is done using the same transaction context in which the BPEL process is executed. However, BPEL engine use a separate transaction context for the audit logging information, which aids (a lot) for debugging failed instance.
                  Skipping dehydration
                  • Skipping dehydration will increase performance with a cost of auditing.
                  • By Default, all BPEL processes are dehydrated regardless of whether they are Synchronous or Asynchronous process.
                  • For Synchronous processes that do not need to be durable, you can turn off the dehydration mechanism by setting the following properties at process or engine level:
                  1. Set inMemoryOptimization to true.
                  2. Set completionPersistPolicy property to faulted or Off.
                  • Asynchronous process invocation messages are always saved to the dehydration store.
                  • Durable process are always dehydrated regardless of the settings of the persistence properties.

                  Dehydration Tables
                  Cube_Instance: Stores the information about the composite instance that gets created.
                  Cube_scope: Stores information about the scopes and variables declared and used.
                  DLV_Message: All the incoming payload details are stored.
                  Invoke_Message: All the outgoing message payload details are stored.
                  Audit_Trail: Used to store information of the xml that is rendered in EM console.


                  Wednesday, November 6, 2019

                  12C OSB - Leverage work manager for throttling

                  Work Manager vs Throttling:


                  Work Manager with Proxy Service:
                  Work Manager configured on Proxy Service is used to limit the number of threads running a Proxy Services.
                  Work Manager with Business Service:
                  Work Manager configured on Proxy Service is used to limit the number of threads that process responses from the back-end system.

                  Throttling with Business Service:
                  • Throttling configured on Business Service only limited loads (requests) to back-end services and to avoid overloading the back-end.
                  • Throttling is used to restrict the message flow to a business service however work managers are used to prioritize service work. Eg: The WorkManager with MaxThreadsConstraint only limits the number of threads which can be used for example to limit the number of listening threads on a queue.
                  • In case of throttling there is possibility of message loss however with work manager setup there is no such possibility.
                  Implementation steps:
                  Domain⇾Environment⇾Work Managers
                  Create new and create a minimum thread constraint.
                  Minimum thread constraint: Ensure that whatever may be the load in the server this minimum number of threads will be allocated to the service.

                  Give it a logical name and assign minimum thread. by default it is -1 which mean infinite.
                  Click next and point it to the server.
                  Create a work manager


                  Next point it to server and finish the wizard
                  You can now go to your work manager and select the constraint you have defined



                   Save the changes.
                  Nowyou just need to attach this created work manager to the business process in OSB.
                  Open up the osb console⇾Go to your Proxy/business service⇾go to transport details and select the work manager that you have created in the previous steps.

                  Save the changes and reactivate your session.

                  For configuring work manager in SOA we do not much options. SOA Services uses a default work manager called as wm/SOAWorkManager.You can configure your own constraints and update the work managers to use the constraints.

                  Tuesday, November 5, 2019

                  12c SOA - Move file using file adapter

                  Here i will show how to move file from one location to other without reading its content using file adapter.

                  Implementation steps:
                  Create a SOA Project


                   Choose Composite with One way BPEL Process


                   Right click on right swim lane and choose file adapter 



                   Choose Operation Type as "Synchronous Read file"
                   Provide a dummy directory and file name

                   Here we will choose Opaque schema as we will not read the file content.

                   Wire the the adpater with the BPEL process
                   Open the JCA file
                   Modify it as per below
                   <adapter-config name="fileMoveAdapter" adapter="file" wsdlLocation="../WSDLs/fileMoveAdapter.wsdl"
                                  xmlns="http://platform.integration.oracle/blocks/adapter/fw/metadata">
                    <connection-factory location="eis/FileAdapter"/>
                    <endpoint-interaction portType="SynchRead_ptt" operation="SynchRead">
                      <!--interaction-spec className="oracle.tip.adapter.file.outbound.FileReadInteractionSpec">
                        <property name="PhysicalDirectory" value="dummy"/>
                        <property name="FileName" value="dummy"/>
                        <property name="DeleteFile" value="true"/>
                      </interaction-spec-->
                      <interaction-spec className="oracle.tip.adapter.file.outbound.FileIoInteractionSpec">
                        <property name="SourcePhysicalDirectory" value="SourceDirectory"/>
                        <property name="SourceFileName" value="SourceFileName.txt"/>
                        <property name="TargetPhysicalDirectory" value="TargetDirectory"/>
                        <property name="TargetFileName" value="TragetFileName.txt"/>
                        <property name="Type" value="MOVE"/>
                      </interaction-spec>
                    </endpoint-interaction>
                  </adapter-config>
                  Create following 4 variables and assign the the real values.
                      <variable name="sourceDirectory" type="xsd:string"/>
                      <variable name="sourceFileName" type="xsd:string"/>
                      <variable name="targetDirectory" type="xsd:string"/>
                      <variable name="targetFileName" type="xsd:string"/>

                   Invoke the file adapter partnerlink and add the JCA properties in the properties tab:

                  <invoke name="Invoke_fileMoveAdapter" partnerLink="fileMoveAdapter"
                              portType="ns1:SynchRead_ptt" operation="SynchRead"
                              inputVariable="Invoke_fileMoveAdapter_SynchRead_InputVariable"
                              outputVariable="Invoke_fileMoveAdapter_SynchRead_OutputVariable" bpelx:invokeAsDetail="no">
                        <bpelx:toProperties>
                          <bpelx:toProperty name="jca.file.SourceDirectory" variable="sourceDirectory"/>
                          <bpelx:toProperty name="jca.file.SourceFileName" variable="sourceFileName"/>
                          <bpelx:toProperty name="jca.file.TargetDirectory" variable="targetDirectory"/>
                          <bpelx:toProperty name="jca.file.TargetFileName" variable="targetFileName"/>
                        </bpelx:toProperties>
                      </invoke>
                   Deploy the composite and place the file in the source directory and you test it.


                  Friday, November 1, 2019

                  12c SOA - Rename a SOA Composite using template

                  Rename a SOA Composite using template

                  Follow the steps:
                  Right click on the composite to be renamed ⇾Create SOA Template
                   Provide a template name
                   Finish
                   New⇾Project
                   SOA project
                   Provide the new name
                   Choose the SOA template created
                   Composite is successfully renamed.

                  Featured Post

                  11g to 12c OSB projects migration points

                  1. Export 11g OSB code and import in 12c Jdeveloper. Steps to import OSB project in Jdeveloper:   File⇾Import⇾Service Bus Resources⇾ Se...