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 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 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 beTestInterface.wsdl
.BPEL_PARTNER_LINK
refers to thename
attribute of the<partnerLink>
tag which correspond to this WSDL.WSDL_TARGET_NAMESPACE
refers to thetargetNamespace
attribute of the<definitions>
root element of the WSDL.WSDL_PORT_TYPE
refers to thename
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 beTestInterface.wsdl
.BPEL_PARTNER_LINK
refers to thename
attribute of the<partnerLink>
tag which correspond to this WSDL.WSDL_TARGET_NAMESPACE
refers to thetargetNamespace
attribute of the<definitions>
root element of the WSDL.WSDL_PORT_TYPE
refers to thename
attribute of the<portType>
element in the WSDL.REVISION
refers the revision of this component. Typically, this is1.0
.COMPONENT_NAME
refers to the name of the component. Typically, this is the name of the BPEL process. In this caseReceiveReply
.BPEL_FILE_NAME
refers to the bpel file name.WSDL_SERVICE_NAME
refers to thename
attribute of the<service>
element in the WSDL.WSDL_PORT_NAME
refers to thename
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
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
.