Scenario
Automatic code generation from within eclipse and the ability to debug Symphony services are two of the new features in Symphony 4.0.

An eclipse plug-in is provided that eases the task of application coding where client and service code must be written or adapted for the Symphony API. The plug-in automates some of the coding effort, thereby reducing or eliminating errors. Once the Java project wizard has created a framework of generated code, all that is needed is to add the application logic. The plug-in also provides access to the Symphony DE Platform Management Console from within eclipse.

The service replay debugger allows the replay of actual events that occurred in a service instance when the application ran in Symphony. In the Symphony environment, the Service Instance Manager (SIM) will start a service instance and drive all of the actions that occur on the service. The Service Replay Debugger can capture these actions in a file, along with the original data that was passed to the service at each stage. This feature allows the service to be run from this event file, no longer requiring a SIM to drive the service actions. With the Service Replay Debugger, the service binary can be run directly from a command line, debugger, or integrated development environment (IDE).

Below is a scenario that combines both features. It documents the steps required to produce a Symphony Monte Carlo application that estimates the value of Pi. Then shows how to debug the Symphony service to find an error in the code.

Further information on these features can be found in the Symphony DE Developers Guide.

Steps
1. Launch eclipse
2. Install the eclipse plug-in as per the instructions on the developer guide.
3. Create a new Symphony project using the Symphony wizard.
Select File->New->Project->Wizard->Symphony (generated code)
The Symphony Wizard launches.

4. Symphony application identification page

Symphony Application Name: MyMonteCarloPi
Package Name: com.platform.monte.carlo.pi

Select "Next"


5. Client and Service class page

Client class name: MyPiClient
Client type: sync

Service class name: MyPiService

Select "Next"

6. New Message page

Select the Add button to add a new message class.
Message class name: MyPiMessage

Then select the "Edit" button to add some members to the message class.

Select the "Add" button to add the first member.
Code:
double numberOfSimulations
Select the "Add" button to add the second member.
Code:
double numberOfHits
Select "OK" and then "Next".


7. Java project page

Project Name: MyPiApplication
Select "Finish" to complete the wizard.

This will generate the skeleton code for the Symphony Client and Service.

8. Add client application logic for sending workload to grid

Add the following import statement to MyPiClient.java
Code:
import com.platform.monte.carlo.pi.message.*;
Add the following code to the main function in MyPiClient.java. Replace the generated code between line 57 and line 82.
Code:
 // Now we will send some messages to our service
   int tasksToSend = 10;
   
   //Add the following code replacing the generated code.
                   
   double totalSimulations = 10000000;
   double numberOfSimulationsPerTask = totalSimulations / tasksToSend;
                   
   for (int taskCount = 0; taskCount < tasksToSend; taskCount++)
   {
       // Create a message
       MyPiMessage myInput = new MyPiMessage();
       myInput.setnumberOfSimulations(numberOfSimulationsPerTask);
                       
       // Set task submission attributes
       TaskSubmissionAttributes taskAttr = new TaskSubmissionAttributes();
       taskAttr.setTaskInput(myInput);
       TaskInputHandle input = session.sendTaskInput(taskAttr);
       
       // Retrieve and print task ID
       System.out.println("task submitted with ID : " + input.getId());
    }
    
    // Now get our results - will block here until all tasks retrieved
    EnumItems enumOutput = session.fetchTaskOutput(tasksToSend);
9. Add service logic

Add the following import statement to MyPiService.java

import com.platform.monte.carlo.pi.message.*;
import java.util.*;

Add the following member variable to MyPiService class.
[CODE] private Random seed;[CODE]

Add the following code to onInvoke method.
Code:
 // get input
   MyPiMessage myMsg = new MyPiMessage();
   taskContext.populateTaskInput(myMsg);
           
   double hits = 0;
   double simulations = myMsg.getnumberOfSimulations();
       
   double x, y;
   Random Rnd = new Random(seed.nextLong());
     
   for (int i = 0; i < simulations; i++) 
   {
       x = Rnd.nextDouble();
       y = Rnd.nextDouble();
       hits += ((x * x + y * y) <= 1) ? 1 : 0;
   }
   
   myMsg.setnumberOfHits(hits);
   
   // set output (which is returned to client)
   taskContext.setTaskOutput(myMsg);
10. Deploy The Service

In eclipse select Symphony->Symphony Operations->Create Deployment Package.

Complete the dialog box as follows:


Package Name: MyPiService
Package Path: c:\eclipse\workspace\MyPiApplication\bin

Main Service Class: com.platform.monte.carlo.pi.monte.carlo.pi.service .MyPiService

Select “Create and Validate Service Package”
Select “Finish”

11. Deploy the Application

Now we need to register the application and deploy the package.

Select Symphony->Add/Remove Application
Select “Add an application”
Select “Create New Profile”

Application Name: MyMonteCarloPi
Select “Continue”
Service name: MyPiService

Service Package: c:\eclipse\workspace\MyPiApplication\bin\MyPiServi ce.zip

Select “Continue”

Use the default session type

Select “Continue”

Select “Confirm”

12. Run the application

Run the client application from within eclipse.

You will get the following error message generated:
Code:
Task Failed : 
   com.platform.symphony.soam.SoamException: Domain <SOAM>: session manager received in Session with ID <1> for task with ID <1> from SIM with ID <ee66fa16-ffff-ffff-c000-005056c00008-4052-6032>, SIM process ID <5964>, Service with ID <eeab68ea-ffff-ffff-c000-000000000000-2056-5964>, Service process ID <1388>, executed on host <Simon>, for Application <MyMonteCarloPi> which contains following error description <Domain <SOAM>: An unknown exception was caught.>. Check SIM log. Fix the application.
There is a problem with our service. We need to debug it in order to find out what the problem is.

13. Debug the service

Select Symphony->Symphony Operations->Configure Application Debug Settings.

Select “Advanced Configuration”


And in the service definition section select “Error Handling”. Set the “Current Debug Setting” to be “Enable full debug – Always write to the debug file”. When we run the service an event file will be generated. We can use this file to debug the service directly in eclipse.


Select “Save”


Run the client application in eclipse.


Navigate to the following directory:


C:\SymphonyDE\DE40\work\serl\MyMonteCarloPi\MyPiSe rvice


In this directory there will be a set of .bat and .serl files. One pair of for each CPU/core that you have on the machine you are using. The .bat file is used to set the environment variables. The .serl file is the event file. Exit eclipse.


Launch a command prompt. Navigate to the directory containing the files. Run the .bat file. Launch eclipse from the command prompt.


Debug the service from within eclipse. Select the “Environment” tab in the “Debug” dialog. Import the environment variables defined after running the .bat file using the “Select…” button.


Set a break point at the start of the onInvoke method and step through the code.


When you get to the following line:
Code:
 Random Rnd = new Random(seed.nextLong());
Notice that the variable seed is null. This is the problem. To fix the bug replace:
Code:
private Random seed;
with
Code:
 private Random seed = new Random();
14. Redeploy the service

After the code has been fixed we need to redeploy the service.


Select Symphony -> Create Deployment Package

Select “Create and Validate Service Package”

Select “Deploy the Package”

15. Complete the Client Code

Lets complete the client. We need the code that will aggregate the data returned from the tasks submitted to the grid to give us the value of Pi.

Replace the code after the call to fetchTaskOutput with the code below.
Code:
 double hits = 0;
               
   // Inspect results
   TaskOutputHandle output = enumOutput.getNext();
   while (output != null)
   {
       // Check for success of task
       if (output.isSuccessful())
       {
           MyPiMessage myOutput = new MyPiMessage();
           output.populateTaskOutput(myOutput);
           hits += myOutput.getnumberOfHits();
           System.out.println("\nTask Succeeded [" +  output.getId() + "]");
       }
       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();
   }
                       
   hits = 4 * hits / totalSimulations;
   System.out.println("Estimated Value of Pi " + hits);
Now rerun the client application and you should see output similar to the following:
Code:
 Connection ID=8bef80d8-ffff-ffff-c000-005056c00008-5424-2372
   Session ID:602
   task submitted with ID : 1
   task submitted with ID : 2
   task submitted with ID : 3
   task submitted with ID : 4
   task submitted with ID : 5
   task submitted with ID : 6
   task submitted with ID : 7
   task submitted with ID : 8
   task submitted with ID : 9
   task submitted with ID : 10
   
   Task Succeeded [1]
   Task Succeeded [2]
   Task Succeeded [3]
   Task Succeeded [4]
   Task Succeeded [5]
   Task Succeeded [6]
   Task Succeeded [7]
   Task Succeeded [8]
   Task Succeeded [9]
   
   Task Succeeded [10]
   Estimated Value of Pi 3.1426904
   Session closed
   Connection closed
   All Done !!