Spent some time today to understand how socket adapter works , how to test composite as it can’t be done from EM for inbound socket adapter. Lets assume the below use case, we have fixed length separated file , say Employee Details coming in source over some TCP port say 12112. SOA composite will bind the incoming file using NXSD and accept the stream data , then it will perform certain operation and return ACK to same socket port with some predefined code. Below are the detailed implementation steps,
1. At first create a new socket adapter outbound connection pool from weblogic console.
Give the port no which should be free in your system, to check at your windows PC you can issue netstat -an | find "12112" from command-prompt, else you can download TCPView from http://technet.microsoft.com/en-in/sysinternals/bb897437.aspx, it has good gui.
By default KeepAlive property is set as false, you can change the same to true for better performance.
2. Next create a emp.dat file like below ,
fn111111ln111111232007-01-01100
fn211111ln211111232007-11-01200
fn311111ln311111232007-12-01300
And a fixed length NXSD file to read the same,
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:nxsd="http://xmlns.oracle.com/pcbpel/nxsd"
xmlns:tns="http://shrikworld.blogspot.in/ReadEmpDetails"
targetNamespace="http://shrikworld.blogspot.in/ReadEmpDetails"
elementFormDefault="qualified" attributeFormDefault="unqualified"
nxsd:version="NXSD" nxsd:stream="chars" nxsd:encoding="US-ASCII">
<xsd:element name="EmpDetails">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Emp" minOccurs="1" maxOccurs="unbounded" nxsd:style="array" nxsd:cellSeparatedBy="${eol}">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="FirstName" type="xsd:string" nxsd:style="fixedLength" nxsd:length="8"/>
<xsd:element name="LastName" type="xsd:string" nxsd:style="fixedLength" nxsd:length="8"/>
<xsd:element name="Age" type="xsd:int" nxsd:style="fixedLength" nxsd:length="2"/>
<xsd:element name="DOB" type="xsd:string" nxsd:style="fixedLength" nxsd:length="10"/>
<xsd:element name="Salary" type="xsd:int" nxsd:style="fixedLength" nxsd:length="3"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
Create another XSD file for sync response to socket request,
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://shrikworld.blogspot.in/response"
targetNamespace="http://shrikworld.blogspot.in/response"
elementFormDefault="qualified">
<xsd:element name="Response">
<xsd:annotation>
<xsd:documentation>
A sample element
</xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="Code" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
3. Now create a empty composite and drag-drop an inbound socket adapter, select Inbound Sync Req/Response from operation ,
Select the JNDI you created earlier at step#1.
Select request and response XSD that you created step#2,
Create request/response XSL for handshake like below and finish.
Now create a outbound file adapter to write the input data in the file.Drag and drop a BPEL component defining interface later.
Now go to the BPEL process and design like below,
It’s just any other BPEL process, screenshot of different activity,
Notice the last assign activity, here I’m setting ‘0x06’ to the response code, you can set any value.
4. Next step is important, here we’ll create request.xsl and reply.xsl.
There is a function socketReadWithXlation with that input data will be read from port and will be translated using the input message NXSD, so our request.xsl file look likes,
<xsl:template match="/">
<xsl:copy-of select="socket:socketReadWithXlation()" />
</xsl:template>
In sync response.xsl we need the response code that we set from BPEL process on step#3.We are going to use socketWrite function like below in the xslt,
<xsl:template match="//ns0:Response">
<xsl:variable name="temp">
<xsl:value-of select="/ns0:Response/ns0:Code"/>
</xsl:variable>
<xsl:variable name="var1" select="socket:socketWrite($temp, '','')"/>
<xsl:variable name="var2" select="socket:socketEndOutput()"/>
</xsl:template>
5. Now its time to test. First deploy the composite and you’ll notice that it can’t be tested from EM. You need a client program to push the data to the socket.
public class EmpClient {
public static void main(String[] args) {
try {
Socket socket;
final String HOST = "localhost";
final int PORT = 12112;
try {
socket = new Socket(HOST, PORT);
} catch (IOException ioe) {
System.out.println(">>>");
System.out.println(ioe.getMessage());
System.out.println(">>>");
throw ioe;
}
System.out.println("sending data: EmpDetails;");
OutputStream os = socket.getOutputStream();
byte[] b = "fn111111ln111111232007-01-01100\nfn211111ln211111232007-11-01200\nfn311111ln311111232007-12-01300".getBytes();
for (int i = 0; i < b.length; i++) {
os.write(b[i]);
}
os.flush();
socket.shutdownOutput();
System.out.println("receiving data");
BufferedReader soc_in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String successCode = soc_in.readLine();
System.out.println("Success Code: " + successCode);
socket.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
You might noticed I’m sending the same data from Java code with \n separator.When you run this program you should get below output,
Now check the flow from EM console,
So we are done! You can extend this scenario based on your requirement.
4 comments:
Hi Shreekanta,
I followed the above steps mentioned in the post. When I run the EmpClient.java program to test the socket adapter, I could not see any instance getting created in EM console (BPEL is not consuming message). And I could see the below error in logs folder.
Endpoint Activation Error.
AdapterFrameworkImpl::endpointActivation - Endpoint Activation Error.
Caused by: BINDING.JCA-12517
Endpoint Activation Error.
AdapterFrameworkImpl::endpointActivation - Endpoint Activation Error.
The Resource Adapter socket was unable to activate the endpoint oracle.tip.adapt
er.socket.SocketActivationSpec:{ReplyXslt=../Transformations/xsl/reply.xsl, Tran
sMode=XSLT, Xslt=../Transformations/xsl/request.xsl} due to the following reason
: javax.resource.ResourceException: javax.resource.spi.IllegalStateException: [C
onnector:199176]Unable to execute allocateConnection(...) on ConnectionManager.
A stale Connection Factory or Connection Handle may be used. The connection pool
associated with it has already been destroyed. Try to perform another lookup of
the Connection Factory eis/socket/FileSocketAdapter from JNDI and get a new Con
nection Handle.
Please correct the reported issue and redeploy the BPEL process.
Can you please help me in this.
Thanks,
Arun.
I really appreciate information shared above. It’s of great help. If someone want to learn Online (Virtual) instructor led live training in Oracle SOA, kindly contact us http://www.maxmunus.com/contact
MaxMunus Offer World Class Virtual Instructor led training on Oracle SOA. We have industry expert trainer. We provide Training Material and Software Support. MaxMunus has successfully conducted 100000+ trainings in India, USA, UK, Australlia, Switzerland, Qatar, Saudi Arabia, Bangladesh, Bahrain and UAE etc.
For Demo Contact us.
Nitesh Kumar
MaxMunus
E-mail: nitesh@maxmunus.com
Skype id: nitesh_maxmunus
Ph:(+91) 8553912023
http://www.maxmunus.com/
Great article for a newbie like me. Everything works fine but i am getting an error here,
I tried with my variable,
(this is reply.xsl)
But it says 'ns3 is used but not defined', so i used 'ns0' but it still gives me error.
If i write hard-coded value here,
Then this works fine, but i need to pass my bpel variable. Please help.
It is very good blog and useful for students and developer .
Oracle SOA Online Training
Post a Comment