Admin Web Service client tutorial

Goal

This tutorial walks you through an example of Java client application code that changes the priority of specified sessions via the Admin Web Service interface. This tutorial was prepared for users that are already familiar with Web Services.

For information about Web Service concepts, refer to the Web Service clients section of the Application Development Guide in the Knowledge Center.

At a glance

  1. About client - server interactions

  2. Review and understand the example

Prerequisites

  • JDK 1.4 or higher (for Java development)

  • Third-party WSDL - client stub generating tool that complies with the following standards:

    • WSDL 1.1

    • SOAP 1.1

    • Web Service Security UsernameTokenProfile 1.0 (defined in WS-Security 1.0 specification (UsernameToken part only); refer to http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd.)

    The following tools have been tested for Java and .NET:

    • Java: Axis2 0.93

    • .NET: Microsoft WSE version 3.0

About client - server interactions

To better understand how the client connects to the Symphony, let’s look at the sequence of events from start-up.

  1. When EGO starts up, it launches the service controller.

  2. The service controller starts the session director server as a service.

  3. Upon startup, the session director listens for incoming connections from clients. The session director also registers with EGO as a client and uses its connection URL as the client description.

  4. The Symphony client opens a connection to EGO.

  5. The Symphony client retrieves the connection URL to session director by passing the session director client name in an API call to EGO and retrieving the client description (connection URL).

  6. The Symphony client connects to the session director.

Steps for developing Symphony Web Service clients

Here is a suggested high-level methodology for developing Web Service clients.

General development sequence

  1. Read the WSDL documentation to understand the API.

  2. Use the appropriate tool (that supports the required specifications) to generate language-specific binding.

  3. Use the generated code to write the client application.

Symphony-specific development sequence

  1. Find where the Session Director is running.

  2. Log on to the cluster and obtain a credential.

  3. Use the Session Director's Admin API calls.

Review and understand the example

We will review an example of client code to show how you can create a Java client application that modifies the session priority for a given application. The Java client code in this example is representative of the code you would use to access the proxy stub generated from Axis2.

Locate the documentation

You can access additional documentation such as the Web Services WSDL Reference, Java API Reference, the Platform Symphony Reference, and the Error Reference from the Platform Symphony or Symphony DE Knowledge Centers.

Windows

  • From the Start menu, select Programs > Platform Computing > Symphony Developer Edition 4.1.0 > Developer Knowledge Center

Linux

  • $SOAM_HOME/docs/symphonyde/4.1/index.html

What the example does

Using this tutorial, you do the following:

  • List all the applications registered with Symphony

  • List all the sessions with the specified application

  • Change the priority of all the sessions with the specified tag

  • List all the open sessions again to demonstrate that the priority has changed

  • Handle session director failover.

Step 1: Initialize the client

Create an EGO client object by calling the EGOclient constructor and passing the EGO Web Service Gateway URL as an input argument. Use the initializePorts() method to set up a connection to each web service interface (port) that is required for this tutorial.

The session director (one per cluster) is responsible for authenticating clients and processing their requests. For the client to connect to the session director, it must know its URL. To get the session director's URL, pass the client name "SD_ADMIN" to the locate() method of the egoClient object. This method connects to the EGO web service gateway and retrieves all the client information associated with the session director including its URL, which is stored in the client description property of the ClientInfo object. The session director URL is in the form of domain name and port number. For more information about the locate() method, refer to the Web Services WSDL Reference in the Knowledge Center.

Prepend the communication protocol (http://) to the URL to complete it. Create a new proxy object and initialize it with the session director URL. This sets up a connection to the session director via a web service interface (port).

...
public void initialize(String egoUrl) throws Exception 
{
    egoClient = new EGOclient(egoUrl);
    egoClient.initializePorts();
    String sdLocate = locateSD();
    if(0 == sdLocate.length())
    {
        throw new Exception("Cannot get the SD location successfully. Check if the URL 
        of Web Service Gateway <" + egoUrl + "> is valid and the state of Web Service
        Gateway is <STARTED>.");
    }
    String sdUrl="http://" + sdLocate;
   
    System.out.println(sdUrl);
    soamStub = new SoamPortTypeStub(null, sdUrl);
}
...
...
public String locateSD() 
{    String SdUrl="";    ClientInfo[] cinfos = egoClient.locate("SD_ADMIN");    if(null != cinfos)    {        if (cinfos.length > 0) 
        {        SdUrl = cinfos[0].getClientDescription();        }    }    return SdUrl;}
...

Step 2: List all the applications registered with Symphony

To view a list of all registered applications, we pass an empty string to the viewApp() method.

For the client to interact with Symphony, it must first be authenticated by the session director. This requires that the client present a security credential. To acquire the credential, set up the security header using the setSecurityHeader() method. The logon method uses a plain text username and password that are sent over an SSL-enabled connection. The method returns the encrypted credential, which is stored in security document securityDoc. For more information about the logon() method, refer to the Web Services WSDL Reference in the Knowledge Center.

The following XML snippet demonstrates how the actual security header with username and password would appear on the wire.

<oas:Security xmlns:oas="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext
-1.0.xsd">
<wsse:wsse:UsernameToken
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secex
t-1.0.xsd">
  <wsse:Username>Admin</wsse:Username><wsse:Password
 wsse:Type="wsse:PasswordText">Admin</wsse:Password>
  </wsse:wsse:UsernameToken>
</oas:Security>
...

Since the Symphony admin Web Service uses document-style binding, the SdViewAppDocument and SdViewAppResponseDocument classes represent the XML documents that are exchanged between the Web Service and the client. The viewAppReq and resp classes represent the data.

An object of type SdViewAppDocument (viewAppReqDoc) and securityDoc, which has been initialized with the encrypted credential, is passed to the local proxy method, sdViewApp(). The Web Service returns the list of registered applications and the result is printed out to the console using the overloaded print() method.

public void viewApp(String appName) throws RemoteException 
{
    setSecurityHeader();
    SdViewAppDocument viewAppReqDoc = SdViewAppDocument.Factory
    .newInstance();
    SdViewAppDocument.SdViewApp viewAppReq = viewAppReqDoc
    .addNewSdViewApp();
    viewAppReq.setAppName(appName);
    SdViewAppResponseDocument respDoc = soamStub.sdViewApp(viewAppReqDoc,
    securityDoc);
    SdViewAppResponseDocument.SdViewAppResponse resp = respDoc
    .getSdViewAppResponse();
    AppAttribute[] appVector = resp.getAppAttrVector().getItemArray();
    for (int i = 0; i < appVector.length; i++) 
    {
        print(appVector[i]);
    }
}
...
 public void setSecurityHeader()
    {
        String creds = egoClient.logon("Admin", "Admin", null);
        String credential = egoClient.logon(null, null, creds);
        securityDoc = SecurityDocument.Factory.newInstance();
        Security securityReq = securityDoc.addNewSecurity();
        securityReq.setCredential(credential);
    }
...

Step 3: List all the sessions associated with a specific application

To view a list of all sessions associated with a specific application, we pass the application name and a string ("0") for session ID to the viewSession() method.

Set up the security document securityDoc by calling the setSecurityHeader() method; see Step 2: List all the applications registered with Symphony.

Create the request document viewSessionReqDoc and its associated request message object viewSessionReq. Initialize the viewSessionReq object with the application name and session ID that, in this case, is set to "0" to denote all sessions.

Call the local proxy method sdViewSession() and pass the request document viewSessionReqDoc and securityDoc as input arguments. The Web Service returns a list of all open sessions including session attributes, which is printed out to the console using the overloaded print() method.

...
public void viewSession(String appName, String sessionId) throws RemoteException
{
    setSecurityHeader();
    SdViewSessionDocument viewSessionReqDoc = SdViewSessionDocument.Factory
    .newInstance();
    SdViewSessionDocument.SdViewSession viewSessionReq = viewSessionReqDoc
    .addNewSdViewSession();
    viewSessionReq.setAppName(appName);
    viewSessionReq.setSessionId(Long.parseLong(sessionId));
    String filter="state=\"open\"";
    viewSessionReq.setFilter(filter);
    SdViewSessionResponseDocument respDoc = soamStub.sdViewSession(
    viewSessionReqDoc, securityDoc);
    SdViewSessionResponseDocument.SdViewSessionResponse resp = respDoc
    .getSdViewSessionResponse();
    SessionAttribute[] sessionVector = resp.getSessionAttrVector()
    .getItemArray();
    if (sessionVector.length > 0) 
    {
        for (int i = 0; i < sessionVector.length; i++) 
        {
            print(sessionVector[i]);
        }
    } 
    else 
    {
        System.out.println("No sessions found.");
    }
}
...

Step 4: Change the priority of all the sessions with the specified tag

The modSession() method accepts four input arguments: application name, session ID, session tag, priority. All these input arguments, with the exception of session ID, are provided as arguments when you run the main() program. The session ID is initialized to 0 to indicate to the middleware that you want to modify the priority for sessions that share the specified session tag.

Set up the security document securityDoc by calling the setSecurityHeader() method; see Step 2: List all the applications registered with Symphony.

Create the request document modSessionReqDoc and its associated request message object modSessionReq. Initialize the modSessionReq object with the application name, session ID, session tag, and the new priority.

Call the local proxy method sdModSession() and pass the request document modSessionReqDoc and securityDoc as input arguments. The Web Service modifies the priority
...
public void modSession(String appName, String sessionId, String filter,
String attrs) throws RemoteException 
{
    setSecurityHeader();
    SdModSessionDocument modSessionReqDoc = SdModSessionDocument.Factory
    .newInstance();
    SdModSessionDocument.SdModSession modSessionReq = modSessionReqDoc
    .addNewSdModSession();
    modSessionReq.setAppName(appName);
    modSessionReq.setSessionId(Long.parseLong(sessionId));
    modSessionReq.setFilter(filter);
    modSessionReq.setModStr(attrs);
    SdModSessionResponseDocument respDoc = soamStub.sdModSession(
    modSessionReqDoc, securityDoc);
    SdModSessionResponseDocument.SdModSessionResponse resp = respDoc
    .getSdModSessionResponse();
}
...

Step 5: Handle session director failover

If the system is configured for the session director to fail over on different hosts, the Web Service client has to be written in a way to ensure that the request is sent to the correct session director URL. In the following example, code has been added to the example from step 3 to handle session director failover situations.

First, we initialize the retry variable so that a reconnection to the session director is attempted up to three times. The sdViewSession() method is called and if it succeeds, the variable is reset to zero and the loop exits. If the method call fails, relocateSD() makes an attempt to find the new host that the session director is running on. If the URL is found, it is passed to the soamStub object and the sdViewSession() method call is attempted again; otherwise, a RemoteException is thrown indicating that the session director cannot be found.

    ...
    setSecurityHeader();
    SdViewSessionDocument viewSessionReqDoc =
    SdViewSessionDocument.Factory.newInstance();
    SdViewSessionDocument.SdViewSession viewSessionReq =
    viewSessionReqDoc.addNewSdViewSession();
    viewSessionReq.setAppName(appName);
    viewSessionReq.setSessionId(str2sessionId(sessionId));
    int retry = 3; //retry 3 times
    while(retry > 0)
    {
        try 
        {
            SdViewSessionResponseDocument respDoc = 
            soamStub.sdViewSession(viewSessionReqDoc,securityDoc);
            retry = 0;
        }
        catch(java.rmi.RemoteException re) 
        {
            reLocateSD();
            if (soamStub == null) 
            {
                throw re;
            } 
            else
            {
                retry--;
            }
        }
    }
    SdViewSessionResponseDocument.SdViewSessionResponse resp =
    respDoc.getSdViewSessionResponse();
    SessionAttribute[] sessionVector = resp.getSessionAttrVector().getItemArray();
...
public void reLocateSD()
{
    String sdUrl="http://" + locateSD();
    soamStub = new SoamPortTypeStub(null, sdUrl);
}
    ...