ABSTRACT
This article provides information about using HTTP as a replacement of RMI which has been deprecated from IBM Sterling Integrator version 5260.
INTRODUCTION
Using the RMI adapter present in IBM Sterling integrator multiple use case can be executed. One typical use case is to execute a business process using the RMI via java code and getting back the result. Since RMI adapter has been deprecated since IBM Sterling Integrator version 5260, this article aims to provide an alternate approach of using the HTTP server adapter to execute a business process and get back the result.
SAMPLE USE CASE
The use case here is to upload a zip file to IBM Sterling integrator and return the updated zip file with one additional document added to it.
USING THE RMI ADAPTER IN IBM STERLING INTEGRATOR 5250
A zip file is passed as a primary document to business process via Java RMI code. The business process then creates a document of its process data using DOMtoDoc service and subsequently using JavaTask service is used to update the zip file with the document created in previous step. This zip is returned via RMI.
Additionally the java code be used to get the WORKFLOW_ID of the business process which was executed and the status of the business process.
Artifacts required
1.Java code to invoke RMI
2. RMI IIOP Adapter
3.Business Process on the SI
Please find attached the artifacts
1.Java Code
|
package com.ibm.test;
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.security.PublicKey; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream;
import javax.rmi.PortableRemoteObject;
import com.sterlingcommerce.woodstock.services.rmiiopadapter.IBusinessProcessProxy; import com.sterlingcommerce.woodstock.services.rmiiopadapter.InvokedBusinessProcessDetails; import com.sterlingcommerce.woodstock.services.rmiiopadapter.KeyValuePair; import com.sterlingcommerce.woodstock.services.rmiiopadapter.RMIIOPAdapterDocument; import com.sterlingcommerce.woodstock.services.security.adapter.SITrustedCertHolder;
public class RMITest { static final String INVOKED_BP = "TEST_RMI" ; static final String INVOKER_NAME_ELEM = "Invoke_BP" ; static final String BP_NAME = "TEST_RMI" ; static final String SBI_HOSTNAME = "hostname" ; static final int SBI_PORT = 11014 ; static final String SBI_CERT_NAME = "RMIClient" ; static final String SBI_CERT_FILENAME = "./config/cert.cer" ; public static void main(String[] args) throws Exception { RMIIOPAdapterDocument pd_docs = null ; KeyValuePair[] kvp_list = null ; InvokedBusinessProcessDetails ibpd = null ; String filenames = "data\\tracking.zip" ; IBusinessProcessProxy proxy = getSBIProxy(SBI_HOSTNAME, SBI_PORT); SITrustedCertHolder cert = new SITrustedCertHolder(SBI_CERT_NAME, getPublicKey(SBI_CERT_FILENAME)); try { pd_docs = createRMIDocument(filenames) ; kvp_list = createRMIKeyValuePair(INVOKER_NAME_ELEM, INVOKED_BP) ; ibpd = proxy.runBPDocParmsWait(BP_NAME, pd_docs, kvp_list, cert) ; String running_bp_id = ibpd.getBusinessProcessID(); String running_status = proxy.getBusinessProcessStatus(running_bp_id, cert) ; RMIIOPAdapterDocument resultdoc = ibpd.getDocument(); System.out.println("BP ID is "+running_bp_id+" status = "+running_status) ; list_zip(resultdoc.getBody()) ; byte[] pc = extract_zip(resultdoc.getBody(),"ProcessContext",true) ; // Dump out the ProcessContext if(pc == null) { System.out.println("ProcessContext not found") ; } else { System.out.println("\nContents of ProcessData\n\n"+new String(pc)) ; } } catch (Exception e) { System.out.println("Exception encountered "+e.getMessage()) ; } } private static void list_zip(byte[] body) throws IOException { ByteArrayInputStream bais = new ByteArrayInputStream(body) ; ZipInputStream zip = new ZipInputStream(bais) ; ZipEntry entry ; int count=1; while ((entry = zip.getNextEntry()) != null) { String name = (String)entry.getName() ; System.out.println("Zip Entry #"+Integer.toString(count)+" "+name) ; count++ ; } zip.close(); } private static byte[] extract_zip(byte[] body, String searchname, boolean partial) throws IOException { ByteArrayInputStream bais = new ByteArrayInputStream(body) ; ZipInputStream zip = new ZipInputStream(bais) ; ZipEntry entry ; while ((entry = zip.getNextEntry()) != null) { String name = (String)entry.getName() ; boolean found=false ; if(partial) { found = name.startsWith(searchname+"_") ; } else { found = name.equals(searchname) ; } if(found) { ByteArrayOutputStream outstream = new ByteArrayOutputStream(); byte[] b = new byte[8192] ; int cnt = 0 ; while ((cnt=zip.read(b,0,8192)) > 0) { outstream.write(b,0,cnt); } zip.close(); return outstream.toByteArray(); } } zip.close(); return null ; } private static final IBusinessProcessProxy getSBIProxy(String hostname, int jndi_port) { try { Registry registry = LocateRegistry.getRegistry(hostname, jndi_port); Object obj = registry.lookup("IIOPBusinessProcessProxy");
// Narrow the retrieved object to the interface for Invoking Business Processes IBusinessProcessProxy proxy = (IBusinessProcessProxy) PortableRemoteObject.narrow(obj, IBusinessProcessProxy.class);
return proxy; } catch (Exception e) { e.printStackTrace(); } return null; } public static PublicKey getPublicKey(String aFileName) { PublicKey sbi_cert = null; try { byte[] publicKeyBytes = getFileContent(aFileName); // get the public key CertificateFactory certificateFactory = CertificateFactory.getInstance("X509"); Certificate certificate = certificateFactory.generateCertificate(new ByteArrayInputStream(publicKeyBytes)); sbi_cert = certificate.getPublicKey(); } catch (Exception e) { e.printStackTrace(); } return sbi_cert; } public static byte[] getFileContent(String aFileName) throws Exception { if (aFileName == null || aFileName.length() == 0) throw new Exception("Invalid file name"); return toByteArray(new File(aFileName)); } public static byte[] toByteArray(File file) throws Exception { try { FileInputStream fileInputStream = new FileInputStream(file); FileChannel channel = fileInputStream.getChannel(); ByteArrayOutputStream out = new ByteArrayOutputStream(); channel.transferTo(0, channel.size(), Channels.newChannel(out)); fileInputStream.close(); return out.toByteArray(); } catch (Exception e) { e.printStackTrace(); throw new Exception("Exception occurred reading a file : " + e.getMessage()); } } private static RMIIOPAdapterDocument createRMIDocument(String zipfilename) throws Exception { RMIIOPAdapterDocument pd_docs = new RMIIOPAdapterDocument(); File file = new File(zipfilename);
FileInputStream fis = new FileInputStream(file); ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buf = new byte[32768]; for (int readNum; (readNum = fis.read(buf)) != -1;) { bos.write(buf, 0, readNum); } bos.flush(); pd_docs.setName("ZippedDocs"); pd_docs.setBody(bos.toByteArray()); bos.close(); fis.close(); return pd_docs ; } private static KeyValuePair[] createRMIKeyValuePair(String invoker_name_element, String sbi_invoked_bp) throws Exception { KeyValuePair[] kvp_list = new KeyValuePair[1]; KeyValuePair kvp = new KeyValuePair(invoker_name_element, sbi_invoked_bp); kvp_list[0] = kvp; return kvp_list; } }
|
2.Business Process
|
<process name="TEST_RMI"> <sequence name="Sequence Start"> <operation name="Assign"> <participant name="AssignService"/> <output message="AssignServiceTypeInputMessage"> <assign to="." from="*"></assign> <assign to="." from="DOMToDoc(/,'ProcessContext')"></assign> </output> <input message="inmsg"> <assign to="." from="*"></assign> </input> </operation>
<operation name="ZipIt"> <participant name="TEST_JavaTask"/> <output message="JavaTaskInputMessage"> <assign to="." from="*"></assign> <assign to="javaSrc">import java.util.*; import java.io.*; import org.apache.commons.io.IOUtils; import com.sterlingcommerce.woodstock.workflow.* ; import java.util.zip.*; ArrayList list = wfc.getDocRefs() ; boolean found = false ; String sci = null ; String[] sciObjectID ; ZipEntry entry ; ByteArrayOutputStream outstream = new ByteArrayOutputStream(); InputStream instream ; ZipOutputStream zip = new ZipOutputStream(outstream); for (int i = 0;i < list.size(); i++) { String item = (String)list.get(i).toString(); String tokens[] = item.split("=") ; sciObjectID = tokens[1].split(" "); sci = sciObjectID[0] ; String name = tokens[0] + "_" + sci ; Document d = wfc.getDocByRef(sci) ; instream = d.getBodyInputStream() ; zip.putNextEntry(new ZipEntry(name)) ; byte[] b = new byte[32768] ; int bytesread ; while((bytesread = instream.read(b)) != -1) { zip.write(b,0,bytesread); } instream.close() ; zip.closeEntry() ; } zip.close() ; Document newDocument = new Document() ; newDocument.setBody(outstream.toByteArray()) ; outstream.close() ; wfc.putPrimaryDocument(newDocument) ; wfc.setBasicStatus(WFCBase.SUCCESS); return Integer.toString(WFCBase.SUCCESS);</assign> </output> <input message="inmsg"> <assign to="." from="*"></assign> </input> </operation>
</sequence> </process>
|
3. RMI IIOP Adapter

4.Sample Result
|
BP ID is 6052 status = Success Zip Entry #1 PrimaryDocument_hostname:node1:1559c0023cd:24244 Zip Entry #2 ProcessContext_hostname:node1:1559c0023cd:24272
Contents of ProcessData
<?xml version="1.0" encoding="UTF-8" standalone="no"?><ProcessData><PrimaryDocument SCIObjectID='hostname:node1:1559c0023cd:24244'/> <WFD_NAME>TEST_RMI</WFD_NAME> <Invoke_BP>TEST_RMI</Invoke_BP> </ProcessData>
|
USING THE HTTP SERVER ADAPTER IN IBM STERLING INTEGRATOR
In 5260 RMI adapter has been deprecated. HTTP server adapter can be used as an alternative to achieve the same use case.
Few modifications listed below needs to be done to the existing business process.
1.Modify the business process to add HTTP respond service so that response can be returned.
2.Modify the business process to add BPMetaDataInfoService so that WORKFLOW_ID can be included in the process data.
Further a HTTP server adapter needs to be configured with a URI that invokes this business process. This URI can be invoked from java code and the same use case can be achieved.
Multiple URI can be configured for multiple use cases. Also HTTP features like Basic Authentication and SSL can be used for secure requirements.
Artifacts required
1.Java code to invoke HTTP URI
2.HTTP Server Adapter
3.Business Process on the SI
Please find attached the artifacts
1.Java Code
|
package com.ibm.test;
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream;
public class HttpTest { static final String SI_HOST = "http://hostname"; static final String SI_HTTP_SERVER_PORT = "14095"; static final String SI_URI = "/poc"; public static void main(String[] args) throws NoSuchAlgorithmException, KeyManagementException { try { URL url = new URL(SI_HOST + ":" + SI_HTTP_SERVER_PORT + SI_URI); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoOutput(true); connection.setDoInput(true); connection.setUseCaches(false); connection.setRequestProperty("Content-Type", "multipart/form-data"); String fileName = "data\\tracking.zip"; File file = new File(fileName); FileInputStream fis = new FileInputStream(file); DataOutputStream dos = new DataOutputStream (connection.getOutputStream()); byte[] buf = new byte[32768]; for (int readNum; (readNum = fis.read(buf)) != -1;) { dos.write(buf, 0, readNum); } dos.flush(); dos.close(); fis.close(); InputStream is = connection.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int read = 0; while ((read = is.read(buffer, 0, buffer.length)) != -1) { baos.write(buffer, 0, read); } byte[] body = baos.toByteArray(); list_zip(body); byte[] pc = extract_zip(body,"ProcessContext",true) ; if(pc == null) { System.out.println("ProcessContext not found") ; } else { System.out.println("\nContents of ProcessData\n\n"+new String(pc)) ; } is.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private static void list_zip(byte[] body) throws IOException { ByteArrayInputStream bais = new ByteArrayInputStream(body) ; ZipInputStream zip = new ZipInputStream(bais) ; ZipEntry entry ; int count=1; while ((entry = zip.getNextEntry()) != null) { String name = (String)entry.getName() ; System.out.println("Zip Entry #"+Integer.toString(count)+" "+name) ; count++ ; } zip.close(); } private static byte[] extract_zip(byte[] body, String searchname, boolean partial) throws IOException { ByteArrayInputStream bais = new ByteArrayInputStream(body) ; ZipInputStream zip = new ZipInputStream(bais) ; ZipEntry entry ; while ((entry = zip.getNextEntry()) != null) { String name = (String)entry.getName() ; boolean found=false ; if(partial) { found = name.startsWith(searchname+"_") ; } else { found = name.equals(searchname) ; } if(found) { ByteArrayOutputStream outstream = new ByteArrayOutputStream(); byte[] b = new byte[8192] ; int cnt = 0 ; while ((cnt=zip.read(b,0,8192)) > 0) { outstream.write(b,0,cnt); } zip.close(); return outstream.toByteArray(); } } zip.close(); return null ; } }
|
2.Modified Business Process
|
<process name="POC_TEST_BP"> <sequence name="Sequence Start"> <operation name="1"> <participant name="BPMetaDataInfoService"/> <output message="Xout"> <assign to="." from="*"></assign> </output> <input message="Xin"> <assign to="." from="*"></assign> </input> </operation> <operation name="Assign"> <participant name="AssignService"/> <output message="AssignServiceTypeInputMessage"> <assign to="." from="*"></assign> <assign to="." from="DOMToDoc(/,'ProcessContext')"></assign> </output> <input message="inmsg"> <assign to="." from="*"></assign> </input> </operation>
<operation name="ZipIt"> <participant name="POC_JavaTask"/> <output message="JavaTaskInputMessage"> <assign to="." from="*"></assign> <assign to="javaSrc">import java.util.*; import java.io.*; import org.apache.commons.io.IOUtils; import com.sterlingcommerce.woodstock.workflow.* ; import java.util.zip.*; ArrayList list = wfc.getDocRefs() ; boolean found = false ; String sci = null ; String[] sciObjectID ; ZipEntry entry ; ByteArrayOutputStream outstream = new ByteArrayOutputStream(); InputStream instream ; ZipOutputStream zip = new ZipOutputStream(outstream); for (int i = 0;i < list.size(); i++) { String item = (String)list.get(i).toString(); String tokens[] = item.split("=") ; sciObjectID = tokens[1].split(" "); sci = sciObjectID[0] ; String name = tokens[0] + "_" + sci ; Document d = wfc.getDocByRef(sci) ; instream = d.getBodyInputStream() ; zip.putNextEntry(new ZipEntry(name)) ; byte[] b = new byte[32768] ; int bytesread ; while((bytesread = instream.read(b)) != -1) { zip.write(b,0,bytesread); } instream.close() ; zip.closeEntry() ; } zip.close() ; Document newDocument = new Document() ; newDocument.setBody(outstream.toByteArray()) ; outstream.close() ; wfc.putPrimaryDocument(newDocument) ; wfc.setBasicStatus(WFCBase.SUCCESS); return Integer.toString(WFCBase.SUCCESS);</assign> </output> <input message="inmsg"> <assign to="." from="*"></assign> </input> </operation> <operation name="HttpRespond"> <participant name="HttpRespond"/> <output message="HttpRespondInputMessage"> <assign to="doc-has-headers">false</assign> <assign to="." from="*"></assign> </output> <input message="inmsg"> <assign to="." from="*"></assign> </input> </operation> </sequence> </process>
|
3.HTTP Server Adapter

4.Sample Result
|
Zip Entry #1 PrimaryDocument_hostname:node1:155958e9760:5145 Zip Entry #2 ProcessContext_hostname:node1:155958e9760:5160
Contents of ProcessData
<?xml version="1.0" encoding="UTF-8" standalone="no"?><ProcessData><PrimaryDocument SCIObjectID='hostname:node1:155958e9760:5145'/> <b2b-protocol>http</b2b-protocol> <transport-instance-id>POC_HTTP_SERVER_HttpServerAdapter_node1</transport-instance-id> <transport-session-id>Tue Jun 28 02:15:33 EDT 2016:7</transport-session-id> <http-request-uri>/poc</http-request-uri> <SyncModeBP>false</SyncModeBP> <BPDATA><WORKFLOW_ID>3163</WORKFLOW_ID> <WFD_ID>4608</WFD_ID> <WFD_VERSION>2</WFD_VERSION> <WFD_NAME>POC_TEST_BP</WFD_NAME> <WFD_DESCRIPTION>V2</WFD_DESCRIPTION> <WFD_STATE>ACTIVE</WFD_STATE> <WFD_STATUS>SUCCESS</WFD_STATUS> <WFD_TYPE>NORMAL</WFD_TYPE> <WFD_PRIORITY>4</WFD_PRIORITY> <WFD_PERSISTENCE_LEVEL>FULL</WFD_PERSISTENCE_LEVEL> <WFD_LIFE_SPAN>2880 Minute(s)</WFD_LIFE_SPAN> <WFD_STORAGE_TYPE>DEFAULT</WFD_STORAGE_TYPE> <WFD_RECOVERY_LEVEL>DEFAULT</WFD_RECOVERY_LEVEL> <WFD_DOC_TRACKING_FLAG>false</WFD_DOC_TRACKING_FLAG> <WFD_DEADLINE_INTERVAL>-1</WFD_DEADLINE_INTERVAL> <WFD_EVENT_LEVEL>NONE</WFD_EVENT_LEVEL> </BPDATA> </ProcessData>
|