Skip to content

Instantly share code, notes, and snippets.

@simonharrer
Created November 30, 2012 12:14
Show Gist options
  • Save simonharrer/4175442 to your computer and use it in GitHub Desktop.
Save simonharrer/4175442 to your computer and use it in GitHub Desktop.
Oracle SOA Suite 11g - Deployment Archives and Scripts

Oracle SOA Suite 11g - Deployment Archives and Scripts

This article sheds some light on the question: "How to get a BPEL process packaged and deployed to the Oracle SOA Suite 11g automatically without any IDE?"

The BPEL process

The BPEL process has to be very simple as the task focus on packaging and deployment. I chose the ReceiveReply test from the betsy test suite which receives an integer and echos it back to the caller. Here is some pseudo code on how it works:

ReceiveReply: int -> int

Examples
5 -> 5
1 -> 1

The BPEL process itself comprises one folder and two files.

ReceiveReply/
	ReceiveReply.bpel
	TestInterface.wsdl

The ReceiveReply.bpel process and its corresponding TestInterface.wsdl interface are shown below.

<?xml version="1.0" encoding="UTF-8"?>
<process name="ReceiveReply"
    targetNamespace="http://dsg.wiai.uniba.de/betsy/activities/bpel/receiveReply"
    xmlns="http://docs.oasis-open.org/wsbpel/2.0/process/executable"
    xmlns:ti="http://dsg.wiai.uniba.de/betsy/activities/wsdl/testinterface">
    <import namespace="http://dsg.wiai.uniba.de/betsy/activities/wsdl/testinterface" location="TestInterface.wsdl" importType="http://schemas.xmlsoap.org/wsdl/"/>
    <partnerLinks>
        <partnerLink name="MyRoleLink" partnerLinkType="ti:TestInterfacePartnerLinkType" myRole="testInterfaceRole"/>
    </partnerLinks>
    <variables>
        <variable name="ReplyData" messageType="ti:executeProcessSyncResponse"/>
        <variable name="InitData" messageType="ti:executeProcessSyncRequest"/>
    </variables>
    <sequence>
        <receive name="InitialReceive" createInstance="yes" partnerLink="MyRoleLink" operation="startProcessSync" portType="ti:TestInterfacePortType" variable="InitData"/>
        <assign name="AssignReplyData">
            <copy>
                <from variable="InitData" part="inputPart"/>
                <to variable="ReplyData" part="outputPart"/>
            </copy>
        </assign>
        <reply name="ReplyToInitialReceive" partnerLink="MyRoleLink" operation="startProcessSync" portType="ti:TestInterfacePortType" variable="ReplyData"/>
    </sequence>
</process>
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="TestInterface"
             targetNamespace="http://dsg.wiai.uniba.de/betsy/activities/wsdl/testinterface"
             xmlns="http://schemas.xmlsoap.org/wsdl/"
             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
             xmlns:plink="http://docs.oasis-open.org/wsbpel/2.0/plnktype"
             xmlns:tns="http://dsg.wiai.uniba.de/betsy/activities/wsdl/testinterface">

    <plink:partnerLinkType name="TestInterfacePartnerLinkType">
        <plink:role name="testInterfaceRole" portType="tns:TestInterfacePortType"/>
    </plink:partnerLinkType>

    <types>
        <xsd:schema targetNamespace="http://dsg.wiai.uniba.de/betsy/activities/wsdl/testinterface"
        			xmlns:tns="http://dsg.wiai.uniba.de/betsy/activities/wsdl/testinterface">
            <xsd:element name="testElementSyncRequest" type="xsd:int"/>
            <xsd:element name="testElementSyncResponse" type="xsd:int"/>
            <xsd:element name="testElementSyncFault" type="xsd:int"/>
        </xsd:schema>
    </types>

    <message name="executeProcessSyncRequest">
        <part name="inputPart" element="tns:testElementSyncRequest"/>
    </message>
    <message name="executeProcessSyncResponse">
        <part name="outputPart" element="tns:testElementSyncResponse"/>
    </message>
    <message name="executeProcessSyncFault">
        <part name="payload" element="tns:testElementSyncFault"/>
    </message>

    <portType name="TestInterfacePortType">
        <operation name="startProcessSync">
            <input name="syncInput" message="tns:executeProcessSyncRequest"/>
            <output name="syncOutput" message="tns:executeProcessSyncResponse"/>
            <fault name="syncFault" message="tns:executeProcessSyncFault"/>
        </operation>
    </portType>

    <binding name="TestInterfacePortTypeBinding" type="tns:TestInterfacePortType">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <operation name="startProcessSync">
            <soap:operation soapAction="sync"/>
            <input name="syncInput">
                <soap:body use="literal"/>
            </input>
            <output name="syncOutput">
                <soap:body use="literal"/>
            </output>
            <fault name="syncFault">
                <soap:fault name="syncFault" use="literal"/>
            </fault>
        </operation>
    </binding>

</definitions>

The Package Structure

The package structure requires a componentType file for each BPEL process file describing which services are provided and which references are required by the component. In case of our ReceiveReply.bpel file, an ReceiveReply.componentType file is required describing the service it provides. In our case, the file looks like this:

<?xml version="1.0" encoding="UTF-8" ?>
<componentType xmlns="http://xmlns.oracle.com/sca/1.0"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               xmlns:ui="http://xmlns.oracle.com/soa/designer/">
  <service name="MyRoleLink" ui:wsdlLocation="TestInterface.wsdl">
    <interface.wsdl interface="http://dsg.wiai.uniba.de/betsy/activities/wsdl/testinterface#wsdl.interface(TestInterfacePortType)"/>
  </service>
</componentType>

I extracted a template to be used for similar processes. Variables are marked like this [[VAR_NAME]].

  • WSDL_FILE_NAME refers to the file name of the WSDL file, in our example above this would be TestInterface.wsdl.
  • BPEL_PARTNER_LINK refers to the name attribute of the <partnerLink> tag which correspond to this WSDL.
  • WSDL_TARGET_NAMESPACE refers to the targetNamespace attribute of the <definitions> root element of the WSDL.
  • WSDL_PORT_TYPE refers to the name attribute of the <portType>element in the WSDL.
<?xml version="1.0" encoding="UTF-8" ?>
<componentType xmlns="http://xmlns.oracle.com/sca/1.0"
               xmlns:ui="http://xmlns.oracle.com/soa/designer/">
  <service name="[[BPEL_PARTNER_LINK]]" ui:wsdlLocation="[[WSDL_FILE_NAME]]">
    <interface.wsdl interface="[[WSDL_TARGET_NAMESPACE]]#wsdl.interface([[WSDL_PORT_TYPE]])"/>
  </service>
</componentType>

Next, the composite.xml file is required. It basically consists of wiring components together as well as exposing services or importing references ensuring communication with software outside of the container. In our case, the ReceiveReply component has to be exposed such that requests to the TestInterface web service are processed by the ReceiveReply component.

<?xml version="1.0" encoding="UTF-8" ?>
<composite name="ReceiveReply"
           revision="1.0"
           label="2012-11-22_14-49-01_094" mode="active" state="on"
           xmlns="http://xmlns.oracle.com/sca/1.0"
           xmlns:ui="http://xmlns.oracle.com/soa/designer/">
  <import namespace="http://dsg.wiai.uniba.de/betsy/activities/wsdl/testinterface"
          location="TestInterface.wsdl" importType="wsdl"/>
  <service name="ReceiveReplyTestInterfaceService"
           ui:wsdlLocation="TestInterface.wsdl">
    <interface.wsdl interface="http://dsg.wiai.uniba.de/betsy/activities/wsdl/testinterface#wsdl.interface(TestInterfacePortType)"/>
    <binding.ws port="http://dsg.wiai.uniba.de/betsy/activities/wsdl/testinterface#wsdl.endpoint(ReceiveReplyTestInterfaceService/TestInterfacePort)" />
  </service>

  <component name="ReceiveReply" version="2.0">
    <implementation.bpel src="ReceiveReply.bpel"/>
  </component>
  <wire>
    <source.uri>ReceiveReplyTestInterfaceService</source.uri>
    <target.uri>ReceiveReply/MyRoleLink</target.uri>
  </wire>
</composite>

I extracted a template analog to the componentType file.

  • WSDL_FILE_NAME refers to the file name of the WSDL file, in our example above this would be TestInterface.wsdl.
  • BPEL_PARTNER_LINK refers to the name attribute of the <partnerLink> tag which correspond to this WSDL.
  • WSDL_TARGET_NAMESPACE refers to the targetNamespace attribute of the <definitions> root element of the WSDL.
  • WSDL_PORT_TYPE refers to the name attribute of the <portType>element in the WSDL.
  • REVISION refers the revision of this component. Typically, this is 1.0.
  • COMPONENT_NAME refers to the name of the component. Typically, this is the name of the BPEL process. In this case ReceiveReply.
  • BPEL_FILE_NAME refers to the bpel file name.
  • WSDL_SERVICE_NAME refers to the name attribute of the <service> element in the WSDL.
  • WSDL_PORT_NAME refers to the name attribute of the <port> element in the WSDL.
<?xml version="1.0" encoding="UTF-8" ?>
<composite name="[[COMPONENT_NAME]]"
           revision="[[REVISION]]"
           label="2012-11-22_14-49-01_094" mode="active" state="on"
           xmlns="http://xmlns.oracle.com/sca/1.0"
           xmlns:ui="http://xmlns.oracle.com/soa/designer/">
  <import namespace="[[WSDL_TARGET_NAMESPACE]]"
          location="[[WSDL_FILE_NAME]]" importType="wsdl"/>
  <service name="[[WSDL_SERVICE_NAME]]" ui:wsdlLocation="[[WSDL_FILE_NAME]]">
    <interface.wsdl interface="[[WSDL_TARGET_NAMESPACE]]#wsdl.interface([[WSDL_PORT_TYPE]])"/>
    <binding.ws port="[[WSDL_TARGET_NAMESPACE]]#wsdl.endpoint([[WSDL_SERVICE_NAME]]/[[WSDL_PORT_NAME]])" />
  </service>

  <component name="[[COMPONENT_NAME]]" version="2.0">
    <implementation.bpel src="[[BPEL_FILE_NAME]]"/>
  </component>
  <wire>
    <source.uri>[[WSDL_SERVICE_NAME]]</source.uri>
    <target.uri>[[COMPONENT_NAME]]/[[BPEL_PARTNER_LINK]]</target.uri>
  </wire>
</composite>

The current folder structure comprises one folder and four files.

ReceiveReply/
	ReceiveReply.bpel
	TestInterface.wsdl
	ReceiveReply.componentType
	composite.xml

Last, you need to package these files into a deployable archive. Oracle requires specific file naming conventions for archives. They have to be prefixed with sca_ and postfixed with the current revision, e.g., for revision 1.0 _rev1. The part in between must be the name of the composite. The file itself has to be jar file.

sca_${COMPOSITE_NAME}_rev${REVISION}.jar

Example
sca_ReceiveReply_rev1.jar

This can be easily scripted by combining Groovy and Apache Ant.

String folder = "ReceiveReply"
String bpelName = "ReceiveReply"
String revision = "1"
String filename = "sca_${bpelName}_rev${revision}.jar"
new AntBuilder().zip(destfile: filename, basedir: folder)

The current folder structure comprises one folder and five files.

ReceiveReply/
	ReceiveReply.bpel
	TestInterface.wsdl
	ReceiveReply.componentType
	composite.xml
package.groovy

When you execute groovy package.groovy, the new folder structure should look like this.

ReceiveReply/
	ReceiveReply.bpel
	TestInterface.wsdl
	ReceiveReply.componentType
	composite.xml
package.groovy
sca_ReceiveReply_rev1.jar

Deployment

The deployment can be scripted using the Apache Ant scripts from JDeveloper. Thus, JDeveloper has to be available which includes the Ant scripts. The groovy script below can be used to deploy the archive to the official Oracle SOA Suite 11g Virtual Machine.

String jdeveloperPath = "c:/Oracle/Middleware/jdeveloper" //substitute with your JDeveloper path
String antFileFolder = "${jdeveloperPath}/bin"
new AntBuilder().ant(antfile: "ant-sca-deploy.xml", dir: antFileFolder) {
	property(name: "user", value: "weblogic")
	property(name: "password", value: "welcome1")
	property(name: "overwrite", value: "true")
	property(name: "serverURL", value: "http://localhost:7001")
	property(name: "sarLocation", value: filename)
}

The final folder structure is shown below.

ReceiveReply/
	ReceiveReply.bpel
	TestInterface.wsdl
	ReceiveReply.componentType
	composite.xml
package.groovy
sca_ReceiveReply_rev1.jar
deploy.groovy

Executing groovy deploy.groovy should produce the following console output:

     [echo] oracle.home = c:\Oracle\Middleware\jdeveloper\bin/..

deploy:
    [input] skipping input as property serverURL has already been set.
    [input] skipping input as property sarLocation has already been set.
    [input] skipping input as property password has already been set.
[deployComposite] setting user/password..., user=weblogic
[deployComposite] Processing sar=sca_ReceiveReply_rev1.jar
[deployComposite] Adding sar file - C:\tmp\sca_ReceiveReply_rev1.jar
[deployComposite] INFO: Creating HTTP connection to host:localhost, port:7001
[deployComposite] INFO: Received HTTP response from the server, response code=200
[deployComposite] ---->Deploying composite success.

When you have a similar output, you have successfully deployed the ReceiveReply bpel process to the Oracle SOA Suite 11g. You can access the WSDL via http://localhost:7001/soa-infra/services/default/ReceiveReply/ReceiveReplyTestInterfaceService?WSDL or test it via http://localhost:7001/em by logging in with weblogic/welcome1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment