SampleApp: Your first synchronous Symphony Java client

Goal

This tutorial guides you through the process of building, packaging, deploying, and running the sample client and service. It then walks you through the sample client application code.

You will learn the minimum amount of code that you need to create a synchronous client.

At a glance

  1. Build the sample client and service

  2. Package the sample service

  3. Add the application

  4. Run the sample client and service

  5. Walk through the code

Build the sample client and service

On Windows

Compile with the .bat file

You can build client application and service samples at the same time.

Change to the %SOAM_HOME%\4.1\samples\Java\SampleApp directory and run the .bat file:
build.bat

Compile with the Ant build file

You can build client application and service samples at the same time.

Change to the %SOAM_HOME%\4.1\samples\Java\SampleApp directory and run the command:
ant

Compile in Eclipse

To compile in Eclipse, see "Symphony plug-in for Eclipse" in the Application Development Guide.

On Linux

You can build client application and service samples at the same time.

  1. Change to the conf directory under the directory in which you installed Symphony DE.
  2. Set the environment:
    • For csh, enter

      source cshrc.soam
    • For bash, enter

      . profile.soam
  3. Compile with the Makefile or with the Ant build file.
    • Compile with the Makefile:

      Change to the $SOAM_HOME/4.1/samples/Java/SampleApp directory and run the make command:
      make
    • Compile with the Ant build file:

      Change to the $SOAM_HOME/4.1/samples/Java/SampleApp directory and run the build command:
      ant

Package the sample service

You must package the files required by your service to create a service package. When you built the sample, the service package was automatically created for you.

Your service package SampleServiceJavaPackage.jar is in the following directory:
%SOAM_HOME%\4.1\samples\Java\SampleApp

Add the application

When you add an application through the DE PMC, you must use the Add Application wizard. This wizard defines a consumer location to associate with your application, deploys your service package, and registers your application. After completing the steps with the wizard, your application should be ready to use.

  1. In the DE PMC, click Symphony Workload > Configure Applications.

    The Applications page displays.

  2. Select Global Actions > Add/Remove Applications.

    The Add/Remove Application page displays.

  3. Select Add an application, then click Continue.

    The Adding an Application page displays.

  4. Select Use existing profile and add application wizard. Click Browse and navigate to your application profile.
  5. Select your application profile xml file, then click Continue

    For SampleApp, you can find your profile in the following location:

    • Java

      • Windows—%SOAM_HOME%\4.1\samples\Java\SampleApp\SampleAppJava.xml

      • Linux—$SOAM_HOME/4.1/samples/Java/SampleApp/SampleAppJava.xml

    The Service Package location window displays.

  6. Browse to the created service package and select it, then, click Continue.
    • Java

      • Windows—%SOAM_HOME%\4.1\samples\Java\SampleApp\SampleServiceJavaPackage.jar

      • Linux—$SOAM_HOME/4.1/samples/Java/SampleApp/SampleServiceJavaPackage.zip

    The Confirmation window displays.

  7. Review your selections, then click Confirm.

    The window displays indicating progress. Your application is ready to use.

  8. Click Close.

    The window closes and you are now back in the Platform Management Console. Your new application is displayed as enabled.

Run the sample client and service

On Windows

To run the service, you run the client application. The service a client application uses is specified in the application profile.

Run the client application.
  • From the command-line:

%SOAM_HOME%\4.1\samples\Java\SampleApp\RunSyncClient.bat

You should see output as work is submitted to the system.

The client starts and the system starts the corresponding service. The client displays messages indicating that it is running.

On Linux

To run the service, you run the client application. The service a client application uses is specified in the application profile.

Run the client application:

$SOAM_HOME/4.1/samples/Java/SampleApp/RunSyncClient.sh

You should see output as work is submitted to the system.

The client starts and the system starts the corresponding service. The client displays messages indicating that it is running.

Walk through the code

Review the sample client application code to learn how you can create a synchronous client application.

Locate the code samples


Operating System

Files

Location of Code Sample

Windows

Client

%SOAM_HOME%\4.1\samples\Java\SampleApp\src\com\platform\symphony\samples\SampleApp\client\SyncClient.java

Input and output objects

%SOAM_HOME%\4.1\samples\Java\SampleApp\src\com\platform\symphony\samples\SampleApp\common\MyInput.java

%SOAM_HOME%\4.1\samples\Java\SampleApp\src\com\platform\symphony\samples\SampleApp\common\MyOutput.java

Service code

%SOAM_HOME%\4.1\samples\Java\SampleApp\src\com\platform\symphony\samples\SampleApp\service\MyService.java

Application profile

The service required to compute the input data along with additional application parameters are defined in the application profile:

%SOAM_HOME%\4.1\samples\Java\SampleApp\SampleAppJava.xml

Output directory

%SOAM_HOME%\4.1\samples\Java\SampleApp\

Linux

Client

$SOAM_HOME/4.1/samples/Java/SampleApp/src/com/platform/symphony/samples/SampleApp/client/syncClient.java

Input and output objects

$SOAM_HOME/4.1/samples/Java/SampleApp/src/com/platform/symphony/samples/SampleApp/common/MyInput.java

$SOAM_HOME/4.1/samples/Java/SampleApp/src/com/platform/symphony/samples/SampleApp/common/MyOutput.java

Service code

$SOAM_HOME/4.1/samples/Java/SampleApp/src/com/platform/symphony/samples/SampleApp/service/MyService.java

Application profile

The service required to compute the input data along with additional application parameters are defined in the application profile:

$SOAM_HOME/4.1/samples/Java/SampleApp/SampleAppJava.xml

Output directory

$SOAM_HOME/4.1/samples/Java/SampleApp/


What the sample does

The client application sample sends 10 input messages through Symphony to the service with the data “Hello Grid!!”. The client blocks to receive messages synchronously.

The service takes the input data sent by the client and returns it with the additional data “Hello Client !!”.

Synchronous client structure

Before developing your client code, implement input and output objects that implement java.io.Serializable. Then, create your Symphony client.

Implement input and output objects

Implement the MyInput class

The myInput class acts as input to the service. In MyInput.java, we implement methods to set and access the data, such as the message string and task ID.

The input object must implement java.io.Serializable. Making the object serializable means that Java knows how to deconstruct the object so that it can be passed through the network to the service. This also means that Java knows how to reconstruct the object when it is received by the service.

...
public class MyInput implements Serializable
{
    //=========================================================================
    //  Constructors
    //=========================================================================
    public MyInput()
    {
        super();
        m_id = 0;
    }
    public MyInput(int id, String string)
    {
        super();
        m_id = id;
        m_string = string;
    }
    //=========================================================================
    //  Accessors and Mutators
    //=========================================================================
    
    public int getId()
    {
        return m_id;
    }
    public void setId(int id)
    {
        m_id = id;
    }
    public String getString()
    {
        return m_string;
    }
    public void setString(String string)
    {
        m_string = string;
    }
...

Implement the MyOutput class

The myoutput object is the result of the computation of input to the service, and is returned to the client by the service.

In MyOutput.java, we implement methods to set and access the output data, such as the message string, task ID, and run time that is returned from the service. Similar to the input object, the output object must implement java.io.Serializable.

...
public class MyOutput implements Serializable{
    //=========================================================================
    //  Constructor
    //=========================================================================
    public MyOutput()
    {
        super();
        m_id = 0;
    }
    //=========================================================================
    //  Accessors and Mutators
    //=========================================================================
    public int getId()
    {
        return m_id;
    }
    public void setId(int id)
    {
        m_id = id;
    }
    public String getRunTime()
    {
        return m_runTime;
    }
    public void setRunTime(String runTime)
    {
        m_runTime = runTime;
    }
    public String getString()
    {
        return m_string;
    }
    
    public void setString(String string)
    {
        m_string = string;
    }
...

Initialize the client

In SyncClient.java, when you initialize, you initialize the Symphony client infrastructure. You initialize once per client.

Important:

Initialization is required. Otherwise, API calls fail.

...
SoamFactory.initialize();
...

Connect to an application

A connection establishes a context for your client and workload. When you connect to an application:

  • Application attributes defined in the application profile are used to provide context such as which service to use, session type, and any additional scheduling or application parameters.

  • A connection object is returned.

The application name in the connection must match that defined in the application profile.

The default security callback encapsulates the callback for the user name and password. In Symphony DE, there is no security checking and login credentials are ignored —you can specify any user name and password. However, when using your client on the grid with Platform Symphony, you need a valid user name and password.

...
// Set up application specific information to be supplied to Symphony
            String appName="SampleAppJava";
            // Set up application authentication information using the default security provider
            DefaultSecurityCallback securityCB = new DefaultSecurityCallback("Guest", "Guest");
            Connection connection = null;
            try
            {
                // Connect to the specified application
                connection = SoamFactory.connect(appName, securityCB);
                // Retrieve and print our connection ID
                System.out.println("connection ID=" + connection.getId());
...
finally
            {
                // Mandatory connection close
                if (connection != null)
                {
                    connection.close();
                    System.out.println("Connection closed");
                }
                                 }
...
Important:

The creation and usage of the connection object must be scoped in a try-finally block. The finally block, with the connection.close() method, ensures that the connection is always closed whether exceptional behavior occurs or not. Failure to close the connection causes the connection to continue to occupy system resources.

Create a session to group tasks

A session is a way of logically grouping tasks that are sent to a service for execution. The tasks are sent and received synchronously.

...
 // Set up session attributes
                SessionCreationAttributes attributes = new SessionCreationAttributes();
                attributes.setSessionName("mySession");
                attributes.setSessionType("ShortRunningTasks");
                attributes.setSessionFlags(Session.SYNC);
                // Create a synchronous session
                Session session = null;
                try
                {
                    session = connection.createSession(attributes);
...
                finally
                {
                    // Mandatory session close
                    if (session != null)
                    {
                        session.close();
                        System.out.println("Session closed");
                    }
                }
...

When creating a synchronous session, you need to specify the session attributes by using the SessionCreationAttributes object. In this sample, we create a SessionCreationAttributes object called attributes and set three parameters in the object.

The first parameter is the session name. This is optional. The session name can be any descriptive name you want to assign to your session. It is for informational purposes, such as in the command line interface.

The second parameter is the session type. The session type is optional. You can leave this parameter blank and system default values are used for your session.

The third parameter is the session flag, which we specify as Session.SYNC. This indicates to Symphony that this is a synchronous session.

We pass the attributes object to the createSession() method, which returns the created session.

Important:

Similar to the connection object, the creation and usage of the session (sending and receiving data) must be scoped in a try-finally block. The finally block, with the session.close() method, ensures that the session is always closed, whether exceptional behavior occurs or not. Failure to close the session causes the session to continue to occupy system resources.

Send input data to be processed

In this step, we create 10 input messages to be processed by the service. When a message is sent, a task input handle is returned. This task input handle contains the ID for the task that was created for this input message.

...
// Now we will send some messages to our service
                    int tasksToSend = 10;
                    for (int taskCount = 0; taskCount < tasksToSend; taskCount++)
                    {
                        // Create a message
                        MyInput myInput = new MyInput(taskCount, "Hello Grid !!");
                        // Set task submission attributes
                        TaskSubmissionAttributes taskAttr = new TaskSubmissionAttributes();
                        taskAttr.setTaskInput(myInput);
                        // Send it
                        TaskInputHandle input = session.sendTaskInput(taskAttr);
                        // Retrieve and print task ID
                        System.out.println("task submitted with ID : " + input.getId());
                                                    }
...

Retrieve output

The call fetchTaskOutput() blocks until the output for all tasks is retrieved. If there is output to retrieve, getTaskOutput() gets the output

Important:

Results are not sent back in order. If order of results is important, the client application must sort the results.

...
// Now get our results - will block here until all tasks retrieved
                    EnumItems enumOutput = session.fetchTaskOutput(tasksToSend);
                    // Inspect results
                    TaskOutputHandle output = enumOutput.getNext();
                    while (output != null)
                    {
                        // Check for success of task
                        if (output.isSuccessful())
                        {
                            // Get the message returned from the service
                            MyOutput myOutput = (MyOutput)output.getTaskOutput();
                            // Display content of reply
                            System.out.println("\nTask Succeeded [" +  output.getId() + "]");
                            System.out.println("Your Internal ID was : " + myOutput.getId());
                      System.out.println("Estimated runtime was recorded as : " + myOutput.getRunTime());
                      System.out.println(myOutput.getString());
                        }
                        else
                        {
                            // Get the exception associated with this task
                            SoamException ex = output.getException();
                            System.out.println("Task Failed : ");
                            System.out.println(ex.toString());
                        }
                        output = enumOutput.getNext();
                                                                }
 ...

Catch exceptions

Any exceptions thrown take the form of SoamException. Catch all Symphony exceptions that occurred in the client application, service, and system.

The sample code in Retrieve output catches exceptions of type SoamException.

Uninitialize

Always uninitialize the client at the end of all API calls. If you do not call uninitialize, the client stays in an undefined state and resources used by the client are held indefinitely.

Important:

Once you uninitialize, all objects become invalid. For example, you can no longer create a session or send an input message.

...
SoamFactory.uninitialize();
...