This is second of the series Enterprise Integration Patterns (EIP) with OpenESB where we will cover Enterprise Integration Patterns using OpenESB.
According to Enterprise Integration Patterns,
The Dynamic Router is a Router that can self-configure based on special configuration messages from participating destinations.
We can realize this pattern in OpenESB using Dynamic Addressing which uses WS-Addressing to dynamically determine the service location at runtime.
To check this in action we need 3 Projects –
- EJB Module implementing the Web Service – you can use any WSDL based web service, not necessary to use EJB.
- BPEL – This will contain the actual code that determines the endpoint at runtime.
- JBI / CASA – This is a composite application necessary to deploy the BPEL.
Step 1 – We create a web service with 2 operations – addition and subtraction. Both operations take 2 numbers as input and return result.
Here’s the xsd –
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://xml.aurorite.com/schema/numberBase" xmlns:tns="http://xml.aurorite.com/schema/numberBase" elementFormDefault="qualified"> <xsd:element name="NumbersAdditionRequest" type="tns:AdditionType"/> <xsd:element name="NumbersAdditionResponse" type="tns:OperationResultType"/> <xsd:element name="NumbersSubtractionRequest" type="tns:SubtractionType"/> <xsd:element name="NumbersSubtractionResponse" type="tns:OperationResultType"/> <xsd:complexType name="AdditionType"> <xsd:sequence> <xsd:element name="number1" type="xsd:int"/> <xsd:element name="number2" type="xsd:int"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="SubtractionType"> <xsd:sequence> <xsd:element name="number1" type="xsd:int"/> <xsd:element name="number2" type="xsd:int"/> </xsd:sequence> </xsd:complexType> <xsd:complexType name="OperationResultType"> <xsd:sequence> <xsd:element name="result" type="xsd:int"/> <xsd:element name="processor" type="xsd:string"/> </xsd:sequence> </xsd:complexType> </xsd:schema>
and here’s the wsdl –
<?xml version="1.0" encoding="UTF-8"?> <definitions name="NumbersOperations" targetNamespace="http://websvcs.aurorite.com/wsdl/NumberOperationSvcs/NumbersOperations" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://websvcs.aurorite.com/wsdl/NumberOperationSvcs/NumbersOperations" xmlns:ns="http://xml.aurorite.com/schema/numberBase" xmlns:plnk="http://docs.oasis-open.org/wsbpel/2.0/plnktype" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"> <types> <xsd:schema targetNamespace="http://websvcs.aurorite.com/wsdl/NumberOperationSvcs/NumbersOperations"> <xsd:import namespace="http://xml.aurorite.com/schema/numberBase" schemaLocation="numberBase.xsd"/> </xsd:schema> </types> <message name="additionRequest"> <part name="part1" element="ns:NumbersAdditionRequest"/> </message> <message name="additionResponse"> <part name="part1" element="ns:NumbersAdditionResponse"/> </message> <message name="subtractionRequest"> <part name="part1" element="ns:NumbersSubtractionRequest"/> </message> <message name="subtractionResponse"> <part name="part1" element="ns:NumbersSubtractionResponse"/> </message> <portType name="NumbersOperationsPortType"> <operation name="addition"> <input name="input1" message="tns:additionRequest"/> <output name="output1" message="tns:additionResponse"/> </operation> <operation name="subtraction"> <input name="input2" message="tns:subtractionRequest"/> <output name="output2" message="tns:subtractionResponse"/> </operation> </portType> <binding name="NumbersOperationsBinding" type="tns:NumbersOperationsPortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="addition"> <soap:operation/> <input name="input1"> <soap:body use="literal"/> </input> <output name="output1"> <soap:body use="literal"/> </output> </operation> <operation name="subtraction"> <soap:operation/> <input name="input2"> <soap:body use="literal"/> </input> <output name="output2"> <soap:body use="literal"/> </output> </operation> </binding> <service name="NumbersOperationsService"> <port name="NumbersOperationsPort" binding="tns:NumbersOperationsBinding"> <soap:address location="http://localhost:8080/NumbersOperationsService/NumberService"/> </port> </service> <plnk:partnerLinkType name="NumbersOperations"> <!-- A partner link type is automatically generated when a new port type is added. Partner link types are used by BPEL processes. In a BPEL process, a partner link represents the interaction between the BPEL process and a partner service. Each partner link is associated with a partner link type. A partner link type characterizes the conversational relationship between two services. The partner link type can have one or two roles.--> <plnk:role name="NumbersOperationsPortTypeRole" portType="tns:NumbersOperationsPortType"/> </plnk:partnerLinkType> </definitions>
Here is the implementation of the webservice operations –
@WebService(serviceName = "NumbersOperationsService", portName = "NumbersOperationsPort", endpointInterface = "com.aurorite.websvcs.wsdl.numberoperationsvcs.numbersoperations.NumbersOperationsPortType", targetNamespace = "http://websvcs.aurorite.com/wsdl/NumberOperationSvcs/NumbersOperations", wsdlLocation = "META-INF/wsdl/NumberService/NumbersOperations.wsdl") @Stateless public class NumberService { Logger logger = Logger.getLogger("soa.aurorite.com.NumberService"); public com.aurorite.xml.schema.numberbase.OperationResultType addition(com.aurorite.xml.schema.numberbase.AdditionType part1) throws UnknownHostException { logger.info("Running this service at " + InetAddress.getLocalHost().getHostName() + " on port 8080"); com.aurorite.xml.schema.numberbase.OperationResultType result = new com.aurorite.xml.schema.numberbase.OperationResultType(); result.setProcessor(InetAddress.getLocalHost().getHostName()); try { result.setResult(part1.getNumber1() + part1.getNumber2()); } catch (Exception e){ result.setResult(0); } return result; //throw new UnsupportedOperationException("Not implemented yet."); } public com.aurorite.xml.schema.numberbase.OperationResultType subtraction(com.aurorite.xml.schema.numberbase.SubtractionType part1) throws UnknownHostException { logger.info("Running this service at " + InetAddress.getLocalHost().getHostName() + " on port 8080"); com.aurorite.xml.schema.numberbase.OperationResultType result = new com.aurorite.xml.schema.numberbase.OperationResultType(); result.setProcessor(InetAddress.getLocalHost().getHostName()); try { result.setResult(part1.getNumber1() - part1.getNumber2()); } catch (Exception e){ result.setResult(0); } return result; //throw new UnsupportedOperationException("Not implemented yet."); } }
Note that I’m returning the machine name in the response. This’ll help us to determine who actually processed a particular operation.
Now to the BPEL. We’ll create a simple process looking like this –
In the BPEL, we add these 2 namespace references –
xmlns:sref="http://docs.oasis-open.org/wsbpel/2.0/serviceref" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" <import namespace="http://docs.oasis-open.org/wsbpel/2.0/serviceref" location="ws-bpel_serviceref.xsd" importType="http://www.w3.org/2001/XMLSchema"/> <import namespace="http://schemas.xmlsoap.org/ws/2004/08/addressing" location="addressing.xsd" importType="http://www.w3.org/2001/XMLSchema"/>
And now the most important part – Adding the Service Endpoint Reference
<assign name="assign_endpoint"> <copy> <!--<from>ns2:doXslTransform('urn:stylesheets:wrap2serviceref.xsl', $EPRVariable.eprValue)</from>--> <from> <literal> <sref:service-ref> <wsa:EndpointReference> <wsa:Address>http://machine2:8080/NumbersOperationsService/NumberService</wsa:Address> <wsa:ServiceName PortName="NumbersOperationsPort" xmlns:serv="http://websvcs.aurorite.com/wsdl/NumberOperationSvcs/NumbersOperations">serv:NumbersOperationsService </wsa:ServiceName> </wsa:EndpointReference> </sref:service-ref> </literal> </from> <to partnerLink="NumberService"/> </copy> </assign>
The portname and Service name must match to the ones in target service.
I just like the helpful info you supply on your articles.
I will bookmark your weblog and test once more here frequently.
I am moderately sure I will be told plenty of new stuff proper here!
Good luck for the next!
You can use wso2 open esb to test the above wsdl web services as well. In addition wso2 open esb allows you to implement security for this web services and will give high performance. If you are interested on it you can can download it from wso2 website ( http://wso2.com/products/enterprise-service-bus/
) because wso2 open esb is free and Open Source
Nice Article.