Tutorial 2: Catching a SOAP message with Axis TCPMonitor
In this tutorial, you use AXIS TCPMonitor (tcpmon) utility to monitor the SOAP messages between an application and the Encyclopedia volume. You configure TCPMonitor to listen at a port for an incoming message to the Encyclopedia volume. You direct the client application to send a request message to the port to which TCPMonitor listens.
TCPMonitor intercepts the message, displays the SOAP message in the request panel, then resends the message to the Encyclopedia volume. When the Encyclopedia volume responds, TCPMonitor intercepts the message, displays the SOAP response in the response panel, and resends the message to the client application.
TCPMonitor logs each request-response message pair. You can view a message pair by choosing an entry row in the top panel. You can also remove an entry, edit and resend a message, and save a message pair to a file.
Figure 20‑9 shows a request-response message pair in TCPMonitor.
Figure 20‑9 TCPMonitor, displaying a request-response message pair
You perform the following tasks:
*Configure and run TCPMonitor
*Redirect a client SOAP request to TCPMonitor
*View a SOAP message in TCPMonitor
To complete this exercise, you need access to the following resources:
*Archive files in \Actuate3\ServerIntTech3\Web Services\Examples\Axis Client\lib, including:
*com.actuate.schemas (idapi.jar)
*org.apache.axis.utils.tcpmon.class (axis.jar)
*Other related JAR files
Task 1: Configure and run TCPMonitor
This task uses the graphical interface of the TCPMonitor utility. This utility is in the org.apache.axis.utils package in axis.jar. You can also run TCPMonitor from the command line using the following syntax:
java org.apache.axis.utils.tcpmon [listenPort targetHost targetPort]
1 Open a command prompt window.
2 At the command prompt, type:
set CLASSPATH=C:\Actuate3\ServerIntTech3\Web Services\Examples\Axis Client\lib\*
Press Enter.
3 At the command prompt, type:
java org.apache.axis.utils.tcpmon
Press Enter.
TCPMonitor—Admin appears.
4 In TCPMonitor—Admin:
*In Listen Port #, type:
8080
*Select Listener.
*In Target Hostname, type:
localhost
*In Target Port #, type:
8000
TCPMonitor—Admin looks like the one in Figure 20‑10.
Figure 20‑10 TCPMonitor—Admin, showing the settings
5 Choose Add.
The Port 8080 tab appears.
If a firewall message appears about blocked ports, select the option to unblock the ports.
6 Choose Port 8080.
TCPMonitor—Port 8080 appears, as shown in Figure 20‑11.
7 To view the SOAP messages in indented XML format, select XML Format.
8 To change the split pane layout to a left-right panel view instead of the default, top-bottom panel view, choose Switch Layout.
Figure 20‑11 TCPMonitor—Port 8080
Task 2: Creating an IDAPI SOAP login application
In this task, you create a Java application to login to iHub using Java that generates a SOAP message. If you have access to the IDAPI training files, you can copy the necessary Java files from the IDAPI student DVD or download package.
1 Navigate to or create the \ActuateTraining3\IDAPI\source directory. and create a new file called ActuateAPIEx.java. Open the file for editing and create an interface that extends com.actuate.schemas.ActuateAPI and includes the get and set methods for a SOAP header, as shown in the following code:
public interface ActuateAPIEx extends com.actuate.schemas.ActuateAPI {
public void setAuthId(java.lang.String authId);
public void setLocale(java.lang.String locale);
public void setTargetVolume(java.lang.String targetVolume);
public void setConnectionHandle(java.lang.String connectionHandle);
public void setDelayFlush(java.lang.Boolean delayFlush);
public java.lang.String getAuthId();
public java.lang.String getLocale();
public java.lang.String getTargetVolume();
public java.lang.String getConnectionHandle();
public java.lang.Boolean getDelayFlush();
 
// @return Call object with the SOAP Header element set
public org.apache.axis.client.Call getCall();
}
2 In the \ActuateTraining3\IDAPI\source directory, create a new file called ActuateAPILocatorEx.java. Open the file for editing and create an interface that extends com.actuate.schemas.ActuateAPILocator and implements the ActuateEx interface to construct the soap header after locating the iHub server, as shown in the following code:
import javax.xml.rpc.Call;
import javax.xml.rpc.ServiceException;
import org.apache.axis.message.SOAPHeaderElement;
 
public class ActuateAPILocatorEx
extends com.actuate.schemas.ActuateAPILocator
implements ActuateAPIEx {
private java.lang.String authId = "";
private java.lang.String locale = "en_US";
private java.lang.String targetVolume;
private java.lang.String targetServer;
private java.lang.String connectionHandle;
private java.lang.Boolean delayFlush;
org.apache.axis.client.Call call = null;
 
/**
* Constructor for ActuateAPILocatorEx
*/
public ActuateAPILocatorEx() {
super();
}
 
/**
* Create call object and add Actuate's SOAP Header
*/
public Call createCall() throws ServiceException {
call = (org.apache.axis.client.Call) super.createCall();
if (null != authId)
call.addHeader(new SOAPHeaderElement(null, "AuthId", authId));
if (null != locale)
call.addHeader(new SOAPHeaderElement(null, "Locale", locale));
if (null != targetVolume)
call.addHeader(
new SOAPHeaderElement(null, "TargetVolume", targetVolume));
if (null != connectionHandle)
call.addHeader(
new SOAPHeaderElement(
null,
"ConnectionHandle",
connectionHandle));
if (null != targetServer)
call.addHeader(
new SOAPHeaderElement(
null,
"TargetServer",
targetServer));
if (null != targetVolume)
call.addHeader(
new SOAPHeaderElement(null, "DelayFlush", delayFlush));
return call;
}
 
/**
* Returns the authId.
* @return java.lang.String
*/
public java.lang.String getAuthId() {
return authId;
}
 
/**
* Get previously created call object
*/
public org.apache.axis.client.Call getCall() {
if (null == call) {
try {
createCall();
} catch (ServiceException e) {
}
}
return call;
}
 
/**
* Returns the connectionHandle.
* @return byte[]
*/
public String getConnectionHandle() {
return connectionHandle;
}
 
/**
* Returns the delayFlush.
* @return java.lang.Boolean
*/
public java.lang.Boolean getDelayFlush() {
return delayFlush;
}
 
/**
* Returns the locale.
* @return java.lang.String
*/
public java.lang.String getLocale(){
return locale;
}
 
/**
* Returns the targetVolume.
* @return java.lang.String
*/
public java.lang.String getTargetVolume(){
return targetVolume;
}
 
/**
* Returns the targetServer
* @return java.lang.String
*/
public java.lang.String getTargetServer(){
return targetServer;
}
 
/**
* Sets the authId.
* @param authId The authId to set
*/
public void setAuthId(java.lang.String authId){
this.authId = authId;
}
 
/**
* Sets the connectionHandle.
* @param connectionHandle The connectionHandle to set
*/
public void setConnectionHandle(java.lang.String connectionHandle) {
this.connectionHandle = connectionHandle;
}
 
/**
* Sets the delayFlush.
* @param delayFlush The delayFlush to set
*/
public void setDelayFlush(java.lang.Boolean delayFlush) {
this.delayFlush = delayFlush;
}
 
/**
* Sets the locale.
* @param locale The locale to set
*/
public void setLocale(java.lang.String locale) {
this.locale = locale;
}
 
/**
* Sets the targetVolume.
* @param targetVolume The targetVolume to set
*/
public void setTargetVolume(java.lang.String targetVolume) {
this.targetVolume = targetVolume;
}
 
/**
* Sets the targetServer
* @param targetServer The targetServer to set
*/
public void setTargetServer(java.lang.String targetServer) {
this.targetServer = targetServer;
}
}
3 In the \ActuateTraining3\IDAPI\source directory, create a new file called Arguments.java. Open the file for editing and create a class to parse command line arguments, including the server URL, as shown in the following code:
import java.util.Vector;
import java.util.Enumeration;
import java.util.NoSuchElementException;
 
public class Arguments{
// default server settings
String serverURL = null;
String username = null;
String password = null;
boolean embeddedDownload = false;
 
Vector arguments = new Vector();
Enumeration enumeration;
 
Arguments(String args[]){
try {
// check each argument if it's '-h http://something'
// then take them as option
for (int i = 0; i < args.length; i++){
if (args[i].startsWith("-")){
char c = args[i].charAt(1);
switch (c){
case 'h' :
case 'H' :
serverURL = args[++i];
break;
case 'u' :
case 'U' :
username = args[++i];
break;
case 'p' :
case 'P' :
password = args[++i];
break;
case 'e' :
case 'E' :
embeddedDownload = true;
break;
case '?' :
printUsage();
System.exit(0);
break;
}
} else {
arguments.add(args[i]);
}
}
enumeration = arguments.elements();
}
catch (Exception e){
printUsage();
System.exit(0);
}
}
 
String getArgument(){
String result = null;
try{
result = (String) enumeration.nextElement();
}
catch (NoSuchElementException e){
printUsage();
System.exit(0);
}
return result;
}
 
String getOptionalArgument(String defaultValue){
String result = null;
try {
result = (String) enumeration.nextElement();
}
catch (NoSuchElementException e){
}
return (result != null) ? result : defaultValue;
}
 
static String usage = "java ClassName [options] ...\n";
static String commonUsage =
"Common options are: \n"+
" -h hostname SOAP endpoint, default 'http://localhost:8000'\n"+
" -u username specify username, default 'Administrator'\n"+
" -p password specify password, default ''\n"+
" -? print this usage\n"+
"\n";
 
static void printUsage(){
System.out.println(usage);
System.out.println(commonUsage);
}
 
String getURL(){
return serverURL;
}
 
String getUsername(){
return username;
};
 
String getPassword(){
return password;
};
 
/**
* Returns the embeddedDownload.
* @return boolean
*/
public boolean isEmbeddedDownload(){
return embeddedDownload;
}
}
4 In the \ActuateTraining3\IDAPI\source directory, create a new file called AcController.java. Open the file for editing and create a class to control the client work flow by calling methods from the Arguments and ActuateEx classes, as shown in the following code:
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.net.MalformedURLException;
import java.rmi.RemoteException;
import java.util.Calendar;
import javax.xml.rpc.ServiceException;
import com.actuate.schemas.*;
 
public class AcController implements java.io.Serializable {
// control variables
public String authenticationId = null;
public String username = "Administrator";
private String password = "";
 
// server settings
public String actuateServerURL = "http://localhost:8000/";
 
// proxy operation
public ActuateSoapBindingStub proxy;
public ActuateAPIEx actuateAPI;
 
/**
* No-argument Constructor
*/
public AcController() throws MalformedURLException, ServiceException {
actuateAPI = new ActuateAPILocatorEx();
setActuateServerURL(actuateServerURL);
}
 
/**
* Constructor accepting serverURL as a parameter
*/
public AcController(String serverURL)
throws MalformedURLException, ServiceException {
actuateAPI = new ActuateAPILocatorEx();
setActuateServerURL(serverURL);
}
 
/**
* Create a new call object that can be used to send SOAP
* message to actuate server
* @return Call
* @throws ServiceException
*/
public org.apache.axis.client.Call createCall() throws ServiceException {
org.apache.axis.client.Call call =
(org.apache.axis.client.Call) actuateAPI.createCall();
call.setTargetEndpointAddress(this.actuateServerURL);
return call;
}
 
/**
* Login to actuate server with username and password
* Return true if login success
*/
public boolean login() {
boolean success = true;
com.actuate.schemas.Login request = new com.actuate.schemas.Login();
request.setPassword(password);
request.setUser(username);
try {
actuateAPI.setAuthId(null);
com.actuate.schemas.LoginResponse response = proxy.login(request);
authenticationId = response.getAuthId();
actuateAPI.setAuthId(authenticationId);
} catch (java.rmi.RemoteException e) {
// login failed
success = false;
}
return success;
}
 
/**
* Sets the ActuateServerURL
* @param serverURL The actuate server url to set
*/
public void setActuateServerURL(String serverURL)
throws MalformedURLException, ServiceException {
if ((proxy == null) || !serverURL.equals(actuateServerURL)) {
if (serverURL != null)
actuateServerURL = serverURL;
System.out.println("Setting server to " + actuateServerURL);
proxy = (ActuateSoapBindingStub)
actuateAPI.getActuateSoapPort(
new java.net.URL(actuateServerURL));
}
}
 
/**
* Sets the password.
* @param password The password to set
*/
public void setPassword(String password) {
if (password == null)
password = "";
this.password = password;
}
 
/**
* Sets the username.
* @param username The username to set
*/
public void setUsername(String username) {
if (username == null)
return;
this.username = username;
}
 
/**
* Returns the password.
* @return String
*/
public String getPassword() {
return password;
}
 
/**
* Returns the username.
* @return String
*/
public String getUsername() {
return username;
}
}
5 In the \ActuateTraining3\IDAPI\source directory, create a new file called AcLogin.java. Open the file for editing and create a class that uses the IDAPI AcController.login method to connect with iHub and return a message, as shown in the following code
/* This program demonstrates a login to an Encyclopedia volume as Administrator: outputs a success message confirming the login or, if an error occurs, a usage statement to the console.
*/
import com.actuate.schemas.*;
 
public class AcLogin {
public static final String usage = "Usage:\n"+
" java AcLogin [options]\n";
 
public static void main(String[] args) {
// set command line usage
Arguments.usage = usage;
// get command line arguments
Arguments arguments = new Arguments(args);
try {
// login to actuate server
AcController actuateControl = new AcController(arguments.getURL());
actuateControl.setUsername(arguments.getUsername());
actuateControl.setPassword(arguments.getPassword());
if (actuateControl.login()) {
System.out.println("Congratulations! You have successfully logged into Encyclopedia volume as "+actuateControl.getUsername());
} else {
System.out.println("Please try again.\n Usage:\n"+" java AcLogin [options]\n");
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
6 Save and close all files.
Task 3: Redirect a client SOAP request to TCPMonitor
In this task, you run a Java application from the command line, redirecting the program to send an Encyclopedia volume request to the port where TCPMonitor listens. After you type each command at the command prompt, press Enter.
1 Open another command prompt window.
2 At the command prompt, type:
cd C:\ActuateTraining3\IDAPI
3 At the command prompt, type:
mkdir build
4 Add the Axis necessary Axis libraries from you Server Integration Technology installation directory and the new classes to the classpath using a command similar to the following:
set CLASSPATH=C:\Actuate3\ServerIntTech3\Web Services\Examples\Axis Client\lib\*;C:\ActuateTraining3\IDAPI;C:\ActuateTraining3\IDAPI\source;C:\ActuateTraining3\IDAPI\build;
5 Compile the specified Java application by typing the following command:
javac -d build source/AcLogin.java source/AcController.java source/Arguments.java source/ActuateAPIEx.java source/ActuateAPILocatorEx.java
6 Run the Java application by typing the following command:
java AcLogin -h http://localhost:8080
The Java application writes the following messages, shown in Figure 20‑12, to the command prompt window when you successfully log into the Encyclopedia volume.
Figure 20‑12 Message indicating that the login operation succeeded
Task 4: View a SOAP message in TCPMonitor
In this task, you examine the details of the SOAP request and response messages resulting from a successful Encyclopedia volume login operation.
1 In the left panel of TCPMonitor, examine the following elements of the SOAP login request message:
*In HTTP header, notice that SOAPAction contains a set of double quotation marks. The Encyclopedia volume uses this setting to identify a SOAP message.
*In the SOAP envelope, examine the SOAP and XML Schema namespace URIs.
*In the SOAP header, notice the locale tag.
*In the SOAP body, examine the login tag with references to the
*http://schemas.actuate.com/actuate11 namespace, the <User> attribute, and the <Password> attribute.
2 In the right panel of TCPMonitor, examine the following parts of the body of the SOAP login response message, shown in Figure 20‑13, from the Encyclopedia volume:
*Examine the <ACTU:LoginResponse> tag.
*Examine the <AuthId> tag. A subsequent request for the current session must send this encrypted, authenticated token.
*Notice the <AdminRights> tag. This tag indicates that the user is the Administrator.
*Notice the <FeatureOptions> tag. This tag indicates available iHub features as attributes in a eight-element string array.
Figure 20‑13 TCPMonitor, displaying the SOAP login response message
Figure 20‑14 Example of a request-response message pair in TCP Monitor