Socket Server Adapter

The Socket Server adapter receives TCP requests from trading partners by using perimeter services.

Socket Server Adapter Overview

The Socket Server adapter provides a Transmission Control Protocol (TCP) endpoint. You can read and write data over this TCP endpoint. The Socket Server adapter can handle both standard connections as well as Secure Sockets Layer (SSL) connections, with authentication, and verification of the SSL protocol handled by the Sterling B2B Integrator keystore. The type of connection (Clear or SSL) is set in the adapter configuration.

You have the option of performing the read and write operations either by invoking a business process containing the Sterling B2B Integrator Socket Read service and Socket Write service or by invoking a custom Java implementation.

The following table provides an overview of the Socket Server adapter:

System name Socket Server Adapter
Graphical Process Modeler (GPM) categories Not in the GPM.
Description This adapter receives TCP requests from trading partners using Perimeter services.
Business usage A business user uses this adapter to monitor TCP connections from TCP clients and to perform activities such as sending or receiving data over the socket. A business user can also implement their own protocol using this adapter.
Usage example A trading partner connects to the Sterling B2B Integrator Socket Server adapter and sends a document for processing. The processed response is sent back to the remote trading partner using the Socket Server adapter.
Preconfigured? No
Requires third-party files? No
Platform availability All supported Sterling B2B Integrator platforms.
Related services None
Application requirements A TCP client at the external trading partner's location which connects to the Sterling B2B Integrator Socket Server adapter. When this adapter is configured with a non-local mode Perimeter server, the Perimeter server must be installed and running. This Perimeter server is typically installed in a DMZ environment, separated from Sterling B2B Integrator by a firewall. For more information on installing and running the Perimeter server see Perimeter Services.
Initiates business processes? Yes
Invocation This adapter is not used in a business process.
Business process context considerations A business process using the Socket Server adapter should not be configured to automatically resume. The Socket Server adapter requires an established session which will not exist if the business process is set to automatically resume.
Returned status values None
Restrictions None
Persistence level System Default
Testing considerations The debug information for this adapter can be found in the Socket Server adapter log files.

Configuring the Socket Server Adapter

To configure the Socket Server adapter, you must specify field settings in the user interface service configuration:

Field Description
Name Name for the service in Sterling B2B Integrator. Required.
Description Description of the service. Required.
Select a Group Selection or creation of the group for this service. Optional.
Socket Server Port Port number that the Socket Server adapter should bind to and listen for connection requests. Required.
Perimeter Server Selection of a local-mode perimeter server for this service. Entries in this list are created in a separate user interface. For more information see Perimeter Services. Required.
Min Threads Tuning parameter that indicates the range of threads available for handling events to improve performance. This parameter must be less than or equal to the Max Threads value. For more information on performance see the Performance and Tuning Guide. Required.
Max Threads Tuning parameter that indicates the range of threads available for handling events to improve performance. This parameter must be greater than or equal to the Min Threads value. For more information on performance see the Performance and Tuning Guide. Required.
Transfer Buffer Size Specifies the size in bytes for the buffer used when transferring data over the socket. Required.
Character Encoding Character encoding that can be specified to interpret the data that is sent across so that it can be placed into the process data. Optional.
On Connect Specifies the action to be taken when a client connects to this server. Required.
Custom Class Name Qualified name of the custom code class that must be invoked on connect from a client. Required. (only if Invoke Custom Code is selected).
Select Business Process Business process which must be executed when a client connects to this server. Required. (only if Invoke Business Process is selected).
Run as user Username used to run the business process. Required. (only if Invoke Business Process is selected).
Secure Sockets Layer (SSL) Indicates whether you are using SSL. Required.
Key Certificate Passphrase Password that protects the server key certificate. Used to encrypt and decrypt messages. Required. (only if SSL option is set to Must).
Key Certificate (System Store) Private key and certificate for server authentication. Used to encrypt and decrypt messages. Required. (only if SSL option is set to Must).
CA Certificates Certificate used to validate the certificate of a TCP client. This is the public key certificate. If no CA certificate is chosen, client authentication is not performed. Optional.

Using the Sterling B2B Integrator Socket Adapter

The Sterling B2B Integrator Socket adapter provides a means to expose a Transmission Control Protocol (TCP) endpoint and also to connect to a TCP endpoint from Sterling B2B Integrator. These capabilities allow you to specify services that perform read and write operations over a TCP Socket. You can use services in a business process to perform the read and write operations. For the server side, options are provided to either invoke a business process that contains the read and write services or invoke a custom Java implementation (that performs the read and write). On the client side, you must invoke a business process to perform these same operations.

Below is the list of adapters and services used in conjunction with the Sterling B2B Integrator Socket adapter.

Note: These adapters work through a Perimeter Server instance. For more information see Perimeter Services.

Adapters

  • Socket Server adapter
  • Socket Client adapter

Services

  • Socket Read service
  • Socket Write service
  • Socket Close service
  • Socket Connect service

Invoking a Business Process

The Sterling B2B Integrator Socket Server adapter gives you the option to invoke a business process when a remote TCP Client connects onto the Socket Server adapter.

The business process name is configured as a part of Sterling B2B Integrator Socket Server adapter configuration.

The business process must reference the Socket Read service, the Socket Write service, and the Socket Close service to perform the read, write, and close of the socket, respectively.

The Socket Close service is needed to close the connection at the end of read and write. If you do not include the Socket Close service in the business process, it would leave the connection open and degrade the performance of the machine by utilizing the system resources.

Note: The Socket Server business processes by using Socket Read, Socket Write, and Socket Close services cannot be resumed or restarted once they are closed.

Sample Business Process

This business process uses both the Socket Read and Socket Write services. The Socket Write service reads the data from the node testNode and writes it over the socket. The Socket Read service reads 100 bytes of data from the socket into the document with name SocketData.

<process name = "SocketServerBP"> 
  <sequence>
<assign to="testNode">Its a nice day today.. have a good day</assign>
       <operation name="Socket Write Service">
      <participant name="SWS"/>
      <output message="SocketWriteServiceTypeInputMessage">
<assign to="NodeToRead" from="/ProcessData/testNode/text()"></assign>   
 <assign to="ResponseTimeout">30</assign>  
        <assign to="DelayWaitingOnIO">20</assign>  
        <assign to="." from="*"></assign>
      </output>
      <input message="inmsg">
        <assign to="." from="*"></assign>
      </input>
    </operation>

  <operation name="Socket Read Service">
      <participant name="SRS"/>
      <output message="SocketReadServiceTypeInputMessage">
        <assign to="." from="*"></assign>
        <assign to="DelayWaitingOnIO">30</assign>  
        <assign to="ResponseTimeout">30</assign>  
        <assign to="BytesCount">100</assign>
        <assign to="DocumentName">SocketData</assign>
      </output>
      <input message="inmsg">
        <assign to="." from="*"></assign>
      </input>
    </operation>

<operation name="SocketCloseServiceType">
      <participant name="SClose1"/>
      <output message="SocketCloseServiceTypeInputMessage">
      <assign to="." from="*"></assign>
      </output>
      <input message="inmsg">
        <assign to="." from="*"></assign>
      </input>
    </operation>
<onFault>
      <operation name="SocketCloseServiceType">
        <participant name="SocketClose"/>
        <output message="SocketCloseServiceTypeInputMessage">
          <assign to="." from="*"></assign>
        </output>
        <input message="inmsg">
          <assign to="." from="*"></assign>
        </input>
      </operation>

    </onFault>
  </sequence>
</process>

Invoking Java Custom Code

Writing Code

Sterling B2B Integrator exposes the ISocketServer_onConnect interface to allow you to introduce custom code. Custom implementations must implement this interface and override the interface method(s).

The following separate jars are provided for you to add in the classpath to compile your implementation:
  • This is the location of the jar file:

    <install>/isocketserver/jars

  • This is the location of the documentation for the interface:

    <install>/isocketserver/docs/socketserverdocs.jar

  • This is the location of the updates for the jar file:

    <install>/installed_data/hotfix/components/socketserver/socketserver.jar

To write code using Eclipse:
  1. Right-click Project, select Properties.
  2. Select Java Build Path from the list.
  3. Click the libraries tag, select Add External JARs.
  4. Select socketserver.jar, and then click OK.
The interface definition is the following:
com.servername.services.socketserver.interfaces.ISocketServer_onConnect
The interface method is the following:
public void onConnect(HashMap<String, Object> map)
The HashMap that is passed contains the following objects:
  • SOCKET_INPUT_STREAM
  • SOCKET_OUTPUT_STREAM
  • SESSION_ID
  • SOCKET_SERVER_INSTANCE

These parameters are used in the custom code to read and write data from the socket.

Sample code below shows you how to use these parameters. There are two approaches that can be used to read or write data to the socket.
  1. INPUT and OUTPUT Streams
  2. Socket Server Instance

Using the INPUT and OUTPUT Streams

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import com.servername.services.socketserver.interfaces.ISocketServer_onConnect;

public class TestSocket_OnConnectImpl implements ISocketServer_onConnect {
	@Override
	public void onConnect(HashMap<String, Object> map) {
		InputStream inputFromSocket = (InputStream) map
				.get(ISocketServer_onConnect.SOCKET_INPUT_STREAM);
		OutputStream outputToSocket = (OutputStream) map
				.get(ISocketServer_onConnect.SOCKET_OUTPUT_STREAM);
		String dataToWrite = "This is the data that I will write over socket";
		try {
			outputToSocket.write(dataToWrite.getBytes()); //Write data over the socket
			outputToSocket.flush();
		} catch (IOException e) {
			System.out.println("Exception while writing....");
		}
		byte[] arr = new byte[100];
		while (true) {
			try {
				int bytesRead = inputFromSocket.read(arr);//Read data from the socket
				if (bytesRead == -1)
					break;
				System.out.println("Read " + bytesRead + "bytes of data" + arr);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		try {
			inputFromSocket.close();
			outputToSocket.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

Using the Socket Server Instance

Note: Along with the socketserver.jar, the following jars need to be added to the classpath:
  • install/jar/asset/<version>/asset.jar
  • install/jar/platform_asi/<version>/platform_asi.jar
  • install/jar/platform_afc/<version>//platform_afc.jar
install/jar/asset/<version>/asset.jar 
install/jar/platform_asi/<version>/platform_asi.jar
install/jar/platform_afc/<version>//platform_afc.jar
import java.util.HashMap;
import com.servername.services.socketcommon.services.SocketCloseRequest;
import com.servername.services.socketcommon.services.SocketReadRequest;
import com.servername.services.socketcommon.services.SocketResponse;
import com.servername.services.socketcommon.services.SocketWriteRequest;
import com.servername.services.socketserver.interfaces.ISocketServer_onConnect;
import com.servername.services.socketserver.server.SocketServer;
import com.servername.workflow.Document;

public class TestForReflectionModified implements ISocketServer_onConnect{
	@Override
	public void onConnect(HashMap<String, Object> inputMap) {
		SocketServer socketServer = (SocketServer) inputMap.get("SOCKET_SERVER_INSTANCE");
		if (null != socketServer) {
			String sessionId = (String)inputMap.get("SESSION_ID");
			System.out.println("Session id [" + sessionId + "]");			
			SocketReadRequest readRequest = prepareSocketReadRequest(sessionId);// Read Operation
			SocketResponse response = null;
			try{
				response = (SocketResponse) socketServer.read(readRequest);
				if (null != response) {					
					System.out.println("SocketReadResponse Response [" + response.isSuccess() + "]");
					//To print the data read - In case data is written to dataNode
					System.out.println("Data read is [" + response.getResults().get("SocketDataRead") + "]");
					//In case data is read into document
					Document document = response.getDoc();
					System.out.println("Document is [ " + document + "]");
				}
			}catch (Exception e) {
				e.printStackTrace();
			}
			
			SocketWriteRequest writeRequest = prepareSocketWriteRequest(sessionId);//Write Operation
			SocketResponse writeResponse = null;
			try {
				writeResponse = (SocketResponse) socketServer.write(writeRequest);
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (null != writeResponse) {				
					System.out.println("SocketWriteResponse Response [" + writeResponse.isSuccess() + "]");					
			}
			
			SocketCloseRequest closeRequest = prepareSocketCloseRequest(sessionId);
			SocketResponse closeResponse = null;
			
			try {
				closeResponse = (SocketResponse) socketServer.close(closeRequest);
			} catch (Exception e) {
				e.printStackTrace();
			}
			if (null != closeResponse) {
				System.out.println(" SocketCloseResponse isSuccess [" +  closeResponse.isSuccess() + "]");
			}
		} else {
			System.out.println("socket server object is null");
		}
	}
	
	/*
	 * This method composes the request for read operation
	 * The parameters that need to be set are 
	 * 1.sessionId,
	 * 2.dataNode or documentName . In case both are null, data is read into the primary document
	 * 3.byteCount/endOfData - One of them is mandatory.
	 * 4.putAsPrimary and readIntoDoc - set as per requirement of reading into dataNode/document
	 * The below example demonstrates for data being read into dataNode , byteCount = 15
	 */
	private SocketReadRequest prepareSocketReadRequest(String sessionId){
		boolean putAsPrimary = false;
		boolean readIntoDoc = false;
		//Data can be read into dataNode or document.. If both are null then data is read into document
		String docName = null;
		String dataNode = "testNode";
		SocketReadRequest readRequest = new SocketReadRequest();
		readRequest.setSessionId(sessionId);
		readRequest.setDelayWaitingOnIO(-1);
		readRequest.setResponseTimeout(20);
		// Either Bytes to Read or End of Data must be provided
		readRequest.setBytesCnt(15);
		readRequest.setDataNode(dataNode);
		/* Do this if data must be read into a document
			putAsPrimary = false;
			readIntoDoc = true;
			readRequest.setDocName(docName);
			Do this if data must be read into primary document
			putAsPrimary = true;
			readIntoDoc = true;	*/
		readRequest.setPutAsPrimary(putAsPrimary);
		readRequest.setReadIntoDoc(readIntoDoc); // Data is read into DataNode
		return readRequest;
	}
	
	/*
	 * This method composes the request for the write operation
	 * The parameters that need to be set are
	 * 1.sessionId
	 * 2.dataToWrite - The data that needs to be written across the socket
	 */
	private SocketWriteRequest prepareSocketWriteRequest(String sessionId){	
		SocketWriteRequest writeRequest = new SocketWriteRequest();
		 //Set the data for writing 
		 writeRequest.setDataToWrite("This is the data written for testing");
		 writeRequest.setSessionId(sessionId); 
		 return writeRequest;
	}
	
	/*
	 * This method composes the request for the close operation
	 * The parameters that need to be set are
	 * 1.sessionId
	 * 
	 */
	private SocketCloseRequest prepareSocketCloseRequest(String sessionId){
		SocketCloseRequest closeRequest = new SocketCloseRequest();
		closeRequest.setSessionId(sessionId);
		return closeRequest;
	}
}