Listing 4:

sendJMSMessage() method of XMLHTTP2SIB servlet

private String sendJMSMessage(String type, HttpServletRequest request)
throws IOException {
	String selector = null;
	try {
MessageProducer producer =
	session.createProducer(requestQueue);
BytesMessage outMessage = session.createBytesMessage();
// send request body only when actually have one
if (type.equals("POST") || type.equals("PUT")) {
	    ServletInputStream sis = request.getInputStream();
	    byte[] body = new byte[sis.available()];
	    sis.read(body);
	        	outMessage.writeBytes(body);
	      	}
// set the message type per the incoming request
outMessage.setStringProperty("SIB_HTTP_METHOD", type);
// set the HTTP headers in the message
Enumeration enum = request.getHeaderNames();
while (enum.hasMoreElements()) {
	String name = (String)enum.nextElement();
	String transformedName = XMLHTTPUtil.fixName(name);
	outMessage.setStringProperty(
    		"SIB_HTTP_HEAD_"+transformedName,
    		request.getHeader(name));
}
// set the HTTP parameters on the message
enum = request.getParameterNames();
while (enum.hasMoreElements()) {
	String name = (String)enum.nextElement()
		outMessage.setStringProperty(
			"SIB_HTTP_PARM_"+name,
			request.getParameter(name));
}
// set the pathInfo on the message
String pathInfo = request.getPathInfo();
String URItail = null;
if (pathInfo != null) URItail =
    	request.getPathInfo().substring(1);
outMessage.setStringProperty("SIB_PathInfo", URItail);

	      // send the message
	      producer.send(outMessage);
	      selector = "JMSCorrelationID ='" +
		  outMessage.getJMSMessageID() + "'";
	      producer.close();
	} catch (JMSException e) {
...
	}
	return selector;
}

Listing 5:

getJMSResponse() method of XMLHTTP2SIB servlet
private HTTPOutput getJMSResponse (String selector, HttpServletResponse response){
byte [] realResponse = null;
      HTTPOutput output = null;
	try {
MessageConsumer consumer =
	session.createConsumer(responseQueue,
	selector);
Message message = consumer.receive();
	     	output = new HTTPOutput();
output.setReturnCode(
	Integer.parseInt(message.getJMSType()));
BytesMessage theMessage = (BytesMessage) message;
realResponse =
	new byte[(int)theMessage.getBodyLength()];
theMessage.readBytes(realResponse);
output.setResponse(realResponse);
// get headers
Enumeration enum = message.getPropertyNames();
 Vector header = new Vector();
 output.setHeader(header);
while (enum.hasMoreElements()){
	String name = (String) enum.nextElement();
	if (name.startsWith("SIB_HTTP_HEAD_")) {
		String[] headerEntry = new String[2];
		header.add(headerEntry);
		headerEntry[0] = name.substring(14);
		headerEntry[1] = 
       	message.getStringProperty(name);
	}
}
consumer.close();
	} catch (JMSException e) {
...
	}
	return output;
}

Listing 6:

Message Driven Bean skeleton
public class XMLHTTPMDB implements javax.ejb.MessageDrivenBean,
	javax.jms.MessageListener {
	// the connection factory and queue names
 	private final static String
JMSCF_JNDI_NAME = "java:comp/env/MDBCF";
 	private final static String
JMSQ_JNDI_NAME = "java:comp/env/MReply";
 	// the JMS connection information
	private Destination queue = null;
	private Connection connection = null;
	private Session session = null;

	// the root of the URI used to send the HTTP request
	private String default_URI_Root = null;

	// getMessageDrivenContext and setMessageDrivenContext not shown

	public void ejbCreate() {
try {
	InitialContext context = new InitialContext();
	default_URI_Root = ((String)
	context.lookup(
			"java:comp/env/Default_URI_Root"));
	ConnectionFactory factory = (ConnectionFactory)
		context.lookup(JMSCF_JNDI_NAME);
	queue = (Destination) context.lookup(JMSQ_JNDI_NAME);
	connection = factory.createConnection();
	session = connection.createSession(false,
    	Session.AUTO_ACKNOWLEDGE);
} catch (NamingException e) {
	...
} catch (JMSException e) {
	...
}
	}

	public void ejbRemove() {
try {
	connection.close();
} catch (JMSException e) {
	...
}
	}
}

Listing 7:

onMessage() method of XMLHTTPMDB MDB
public void onMessage(javax.jms.Message msg) {
	StringBuffer url = null;
	byte[] body = null;
	String type = null;
	Vector header = new Vector();
	BytesMessage byteMsg = (BytesMessage) msg;
	try {
// retrieve the HTTP method, message body
type = msg.getStringProperty("SIB_HTTP_METHOD");
body = new byte[(int) byteMsg.getBodyLength()];
byteMsg.readBytes(body);
// form new target URL
url = new StringBuffer(default_URI_Root);
if (msg.getStringProperty("SIB_PathInfo") != null)
	url.append(
		'/'+msg.getStringProperty("SIB_PathInfo"));
boolean haveParm = false;
Enumeration enum = msg.getPropertyNames();
// HTTP parameters, headers
while (enum.hasMoreElements()){
	String name = (String) enum.nextElement();
	if (name.startsWith("SIB_HTTP_PARM_")) {
		if (haveParm) {
			url.append('&');
		} else {
			haveParm = true;
			url.append('?');
		}
		url.append(
			name.substring(14)+
			"="+msg.getStringProperty(name));
	} else if (name.startsWith("SIB_HTTP_HEAD_")) {
		String[] headerEntry = new String[2];
		header.add(headerEntry);
		headerEntry[0] = name.substring(14);
		headerEntry[1] = msg.getStringProperty(name);
	}
}
	} catch (JMSException x) {
...
	}
	// send the HTTP request
	HTTPOutput theOutput = sendHTTPRequest(
url.toString(), type, body, header);
	// send back the reply via JMS
	try {
MessageProducer queueSender =
	session.createProducer(queue);
BytesMessage outMessage = session.createBytesMessage();
// set the status code
int status = theOutput.getReturnCode();
outMessage.setJMSType(Integer.toString(status));
// write the body
if (theOutput.getResponse() != null) {
	outMessage.writeBytes(theOutput.getResponse());
        	}
     // set the correlation ID 
        	outMessage.setJMSCorrelationID(msg.getJMSMessageID());
        	// insert the response headers
        	Vector headerVec = theOutput.getHeader();
        	if ((headerVec != null) && (headerVec.size() > 0)) {
        for (int i=0; i < headerVec.size(); i++) {
        	String[] entry = (String[]) headerVec.get(i);
        	   outMessage.setStringProperty(
			"SIB_HTTP_HEAD_"+
			XMLHTTPUtil.fixName(entry[0]), entry[1]);
	     }
}
// send the response message
queueSender.send(outMessage);
	} catch (JMSException e) {
e.printStackTrace();
	}
}

Listing 8:

sendHTTPRequest method of XMLHTTPMDB MDB
private HTTPOutput sendHTTPRequest(String outboundURL, String method,
byte[] body, Vector header){
	URLConnection conn = null;
	HttpURLConnection hConn = null;
	OutputStream os = null;
	URL url = null;
	HTTPOutput output = new HTTPOutput();

	// send the HTTP request
	try {
url = new URL(outboundURL);
conn = url.openConnection();
conn.setDoInput(true);
// put the headers in the request
for (int i=0; i < header.size(); i++) {
	String[] entry = (String[]) header.get(i);
	conn.setRequestProperty(
    	XMLHTTPUtil.unfixName(entry[0]), entry[1]);
}

hConn = (HttpURLConnection) conn;
System.out.println("method: "+hConn.getRequestMethod());
hConn.setRequestMethod(method);
// ensure that send body only if needed
if (method.equals("POST") || method.equals("PUT")) {
	conn.setDoOutput(true); 
	os = hConn.getOutputStream();
	if (body != null) os.write(body);
}
	} catch (IOException ex) {
...
	}
	// retrieve HTTP response
	int returnCode = 999;
	try {
// get the content and status
InputStream is = conn.getInputStream();
returnCode = hConn.getResponseCode();
int avail = is.available();
byte[] response = new byte[avail];
is.read(response,0,avail);
output.setResponse(response);

// get the headers
Map headerMap = conn.getHeaderFields();
Set headSet = headerMap.keySet();
Object[] headName = headSet.toArray();
Vector headerVec = new Vector();
output.setHeader(headerVec);
for (int i=0; i < headName.length; i++) {
	String name = (String)headName[i];
	if (name != null) {
		String[] entry = new String[2];
		headerVec.add(entry);
		entry[0] = name;
		entry[1] = conn.getHeaderField(name);
	}
}
is.close();
	} catch (IOException ex) {
try { // get the return code when no InputStream
	returnCode = hConn.getResponseCode();
} catch (IOException ex2) {
	...
}
	}
	output.setReturnCode(returnCode);
	return output;
}

Listing 9:

Original POST request
POST /XMLHTTP/XMLHTTP2SIB/dofuss?xyz=nub&fuzz=bust HTTP/1.1
Content-Type: text/xml; charset=utf-8
Accept: text/*
Cache-Control: no-cache
Pragma: no-cache
A-FAKE-HEADER: WHATEVER-YOU-WANT
User-Agent: Java/1.4.2
Host: localhost
Connection: keep-alive
Content-Length: 179

<?xml version="1.0" encoding="UTF-8"?>
   <GetAccountPositions xmlns="http://test.com/GetAccountPositions">
      <requestData>
         <pdw8_id>10221477</pdw8_id>
      </requestData>
   </GetAccountPositions>

Listing 10:

New POST request sent to service provider
POST /FakeXMLHTTPService/FakeService/dofuss?fuzz=bust&xyz=nub HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 179
Content-Type: text/xml; charset=utf-8
User-Agent: Java/1.4.2
Accept: text/*
Cache-Control: no-cache
A-FAKE-HEADER: WHATEVER-YOU-WANT
Pragma: no-cache

<?xml version="1.0" encoding="UTF-8"?>
   <GetAccountPositions xmlns="http://test.com/GetAccountPositions">
      <requestData>
         <pdw8_id>10221477</pdw8_id>
      </requestData>
   </GetAccountPositions>

Listing 11:

Original response
HTTP/1.1 200 OK
Content-Language: en-US
Set-Cookie: my-cookie=my value
Transfer-Encoding: chunked
Date: Fri, 30 Sep 2005 21:47:43 GMT
XYZ-RQF: zipper

<?xml version="1.0" encoding="UTF-8"?>
   <AccountPositions xmlns="http://test.com/AccountPositions">
      <reponseData>
         <pdw8_id>10221477</pdw8_id>
      </reponseData>
   </AccountPositions>

Listing 12:

Response returned to requester
HTTP/1.1 200 OK
Set-Cookie: my-cookie=my value
Transfer-Encoding: chunked
Date: Fri, 30 Sep 2005 21:47:43 GMT
Content-Language: en-US
XYZ-RQF: zipper

<?xml version="1.0" encoding="UTF-8"?>
   <AccountPositions xmlns="http://test.com/AccountPositions">
      <reponseData>
         <pdw8_id>10221477</pdw8_id>
      </reponseData>
   </AccountPositions>