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_NAMErefers to the file name of the WSDL file, in our example above this would beTestInterface.wsdl.BPEL_PARTNER_LINKrefers to thenameattribute of the<partnerLink>tag which correspond to this WSDL.WSDL_TARGET_NAMESPACErefers to thetargetNamespaceattribute of the<definitions>root element of the WSDL.WSDL_PORT_TYPErefers to thenameattribute 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_NAMErefers to the file name of the WSDL file, in our example above this would beTestInterface.wsdl.BPEL_PARTNER_LINKrefers to thenameattribute of the<partnerLink>tag which correspond to this WSDL.WSDL_TARGET_NAMESPACErefers to thetargetNamespaceattribute of the<definitions>root element of the WSDL.WSDL_PORT_TYPErefers to thenameattribute of the<portType>element in the WSDL.REVISIONrefers the revision of this component. Typically, this is1.0.COMPONENT_NAMErefers to the name of the component. Typically, this is the name of the BPEL process. In this caseReceiveReply.BPEL_FILE_NAMErefers to the bpel file name.WSDL_SERVICE_NAMErefers to thenameattribute of the<service>element in the WSDL.WSDL_PORT_NAMErefers to thenameattribute 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.