SharingData: Developing a Java client and service to share data among tasks

This tutorial walks you through how to develop a client application and service to share data among all tasks in a session. The data is shared by all invocations of tasks within the same session. You learn how to use different data objects for input, output, and common data.

About this task

In this tutorial, you will complete these tasks:
  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

Procedure

  1. Build the sample client and service.

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

    1. Build the sample client and service on Windows
      1. Compile with the .bat file by changing to the %SOAM_HOME%\version\samples\Java\SharingData directory under IBM® Spectrum Symphony Developer Edition and running the .bat file:
        build.bat
      2. Compile with the Ant build file.
        Note: IBM Spectrum Symphony supports Ant 1.6.0 or higher for building Java™ samples in the IBM Spectrum Symphony Developer Edition package.
        Change to the %SOAM_HOME%\version\samples\Java\SharingData directory and run the command:
        ant
      3. Compile in Eclipse.

        To compile in Eclipse, see Using Eclipse as your development environment.

    2. Build the sample client and service on Linux®:
      1. Change to the conf directory under the directory in which you installed IBM Spectrum Symphony Developer Edition.
      2. Set the environment:
        • (csh) source cshrc.soam
        • (bash) . profile.soam
      3. Compile with the Makefile or with the Ant build file:
        • To compile with the Makefile, change to the $SOAM_HOME/version/samples/Java/SharingData directory and run the make command:
          make
          
        • To compile with the Ant build file, change to the $SOAM_HOME/version/samples/Java/SharingData directory and run the build command:
          ant
          
          Note: IBM Spectrum Symphony supports Ant 1.6.0 or higher for building Java samples in the IBM Spectrum Symphony Developer Edition package.
  2. 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 %SOAM_HOME%\version\samples\Java\SharingData directory.

  3. Add the application.

    When you add an application through the cluster management console, 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 cluster management consoled, 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 your application profile XML file, then click Continue
      For SampleApp, you can find your profile in the following location:
      • Windows: %SOAM_HOME%\version\samples\Java\SharingData\SharingDataJava.xml
      • Linux: $SOAM_HOME/version/samples/Java/SharingData/SharingDataJava.xml

      The Service Package location window displays.

    5. Browse to the created service package and select it, then, select Continue.
      • Windows: %SOAM_HOME%\version\samples\Java\SharingData\SharingDataServiceJavaPackage.jar
      • Linux: $SOAM_HOME/version/samples/Java/SharingData/SharingDataServiceJavaPackage.zip

      The Confirmation window displays.

    6. Review your selections, then click Confirm.

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

    7. Click Close.

      The window closes and you are now back in the cluster management console. Your new application is displayed as enabled.

  4. Run the sample client and service.

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

    1. Run the sample client and service on Windows, run the client application from the command line:
      %SOAM_HOME%\version\samples\Java\SharingData\RunSharingDataClient.bat
    2. Run the sample client and service on Linux.
      Run the client application:
      $SOAM_HOME/version/samples/Java/SharingData/RunSharingDataClient.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.

  5. Walk through the code.

    Review the sample code to learn how you can create a client and service that uses data.

    1. Locate the code samples
      Table 1. Code samples
      Operating System Files Location of code sample
      Windows Client %SOAM_HOME%\version\samples\Java\SharingData\src\com\platform\symphony\samples\SharingData\client\SharingDataClient.java
      Input, output, and data objects %SOAM_HOME%\version\samples\Java\SharingData\src\com\platform\symphony\samples\SharingData\common\MyInput.java

      %SOAM_HOME%\version\samples\Java\SharingData\src\com\platform\symphony\samples\SharingData\common\MyOutput.java

      %SOAM_HOME%\version\samples\Java\SharingData\src\com\platform\symphony\samples\SharingData\common\MyCommonData.java

      Service %SOAM_HOME%\version\samples\Java\SharingData\src\com\platform\symphony\samples\SharingData\service\SharingDataService.java
      Application profile The service required to compute the input data along with additional application parameters are defined in the application profile:

      %SOAM_HOME%\version\samples\Java\SharingData\sharingDataJava.xml

        Output directory %SOAM_HOME%\version\samples\Java\SharingData
      Linux Client $SOAM_HOME/version/samples/Java/SharingData/src/com/platform/symphony/samples/SharingData/client/SharingDataClient.java
      Input, output, and data objects $SOAM_HOME/version/samples/Java/SharingData/src/com/platform/symphony/samples/SharingData/common/MyInput.java

      $SOAM_HOME/version/samples/Java/SharingData/src/com/platform/symphony/samples/SharingData/common/MyOutput.java

      $SOAM_HOME/version/samples/Java/SharingData/src/com/platform/symphony/samples/SharingData/common/MyCommonData.java

      Service $SOAM_HOME/version/samples/Java/SharingData/src/com/platform/symphony/samples/SharingData/service/SharingDataService.java
      Application profile The service required to compute the input data along with additional application parameters are defined in the application profile:

      $SOAM_HOME/version/samples/Java/SharingData/sharingDataJava.xml

       

      Output directory

      $SOAM_HOME/version/samples/Java/SharingData
    2. Ensure you have the following prerequisites:
      • Ensure you have installed and started IBM Spectrum Symphony Developer Edition.
      • You should also have completed the following tutorials:
        • Your First Synchronous IBM Spectrum Symphony Java Client
        • Your First IBM Spectrum Symphony Java Service
    3. Understand what the sample does.

      The client creates a session with common data, sends 10 input messages with Hello Grid!! through IBM Spectrum Symphony to the service and retrieves the output synchronously.

      The service accesses the common data in onSessionEnter() and stores it in the service container to be accessed during each task invocation. The service then takes input data sent by the client and returns the input data along with Hello Client !!.

    4. Understand when to use common data.

      Use common data when the same data is shared among all tasks in a session. You only need to store the data once, and all tasks in a session can access it.

      Common data is useful for passing data from a client to a service. The service loads the data when the session is created.

      IBM Spectrum Symphony attempts to use the same service instance for all tasks in a session. A service instance is made available to other sessions only when session workload completes, a session is closed or aborted, or when another session of higher priority is assigned the service instance.

    5. Prepare common data in your client:
      1. Declare and implement the Message object.
        In this tutorial, different classes represent input and output. In addition, we are using an additional class to represent common data.
        Common data objects
      2. Use the common data object when creating a session
      3. As in the synchronous client tutorial, initialize the client and connect to the application. Then, create your session to group tasks.

        When creating a session, use the common data object to pass data from the client application to the service.

        In SharingDataClient.java, we create a session and pass in the session attributes including the common data object:
        ...
        // Set up our common data to be shared by all task invocations within this session
                        MyCommonData commonData = new MyCommonData("Common Data To Be Shared");
        
                        // Set up session attributes
                        SessionCreationAttributes attributes = new SessionCreationAttributes();
                        attributes.setSessionName("mySession");
                        attributes.setSessionType("ShortRunningTasks");
                        attributes.setSessionFlags(Session.SYNC);
                        attributes.setCommonData(commonData);
                                        // Create a synchronous session
                        Session session = null;
                        try
                        {
                            session = connection.createSession(attributes);
        ...
        
        
      4. Continue with your client as usual.
        Now you can proceed the same way as in the synchronous client tutorial:
        • Send input data to be processed
        • Retrieve output
        • Close the session
        • Close the connection
        • Catch exceptions
        • Uninitialize
    6. Access common data in your service.
      1. Define a service container and get data from the session.

        As in the basic service tutorial, first define a service container. Then retrieve the common data from the session sent by the client by implementing onSessionEnter() before your invoke call.

        onSessionEnter() is called once for the duration of the session. The corresponding pair is onSessionLeave().

        In SharingDataService.java, we inherited from the ServiceContainer class, and implemented onSessionEnter() to get common data and store it for later use with the session context.
        ...
        public class SharingDataService extends ServiceContainer
        {
            SharingDataService()
            {
                super();
            }
        
            /**
             * The middleware triggers the invocation of this handler to bind the Service 
             * Instance to its owning session when common data is provided by the Client.
             * 
             * If any common data is available for the associated session, it
             * should be accessed in the developer's implementation of this method.
             * Default implementation of this handler does nothing.
             */
            public void onSessionEnter(SessionContext sessionContext) throws SoamException
            {
                // get the current session ID (if needed)
                m_currentSID = sessionContext.getSessionId();
                
                // populate our common data object
                m_commonData = (MyCommonData)sessionContext.getCommonData();
            }
        ...
        
        
      2. Process the input.
        In this example, we use the common data in our invoke call by formatting the output string. We then set our output message as usual to send common data back with each of the replies.
        ...
        public void onInvoke (TaskContext taskContext) throws SoamException
            {
                // We simply echo the data back to the client
                MyOutput myOutput = new MyOutput();
        
                // estimate and set our runtime
                Date date = new Date();
                myOutput.setRunTime(date.toString());
        
                // get the input that was sent from the client
                MyInput myInput = (MyInput)taskContext.getTaskInput();
        
                // echo the ID
                myOutput.setId(myInput.getId());
        
                // setup a reply to the client
                StringBuffer sb = new StringBuffer();
                        sb.append("Client sent : ");
                sb.append(myInput.getString());
                sb.append("\nSymphony replied : Hello Client !! with common data (\);
                sb.append(m_commonData.getString());
                sb.append("\") for session(");
                sb.append(m_currentSID);
                sb.append(")");
                myOutput.setString(sb.toString());
        
                // set our output message
                taskContext.setTaskOutput(myOutput);
            }
        
      3. Perform any data cleanup.
        After processing the input, use the onSessionLeave() call to free the data for the session. onSessionLeave() is called once for every session that is created. In this example, we do not perform any operations in onSessionLeave().
        ...
        public void onSessionLeave() throws SoamException
            { 
                // We get a chance to do any cleanup for anything we may have done 
                // in the onSessionEnter( ) method
            }
        ...
        
      4. Run the container and catch exceptions.
        As with the basic service, run the container in the service main and catch exceptions.
        ...
         public static void main(String args[])
            {
                // Return value of our service program
                int retVal = 0;
                try
                {
                    // Create the container and run it
                    SharingDataService myContainer = new SharingDataService();
                    myContainer.run();
                }
                catch (Exception ex)
                {
                    // Report exception
                    System.out.println("Exception caught:");
                    System.out.println(ex.toString());
                    retVal = -1;
                }
        
                // NOTE: Although our service program will return an overall 
                // failure or success code it will always be ignored in the 
                // current revision of the middleware. 
                // The value being returned here is for consistency.
                System.exit(retVal);
            } 
        ...