h3. Completed StockManager Service
This tutorial expands upon a completed StockManager service from the Develop an Advanced caGrid Analytical Service tutorial. If you have not completed the tutorial, a [identifiers:completed StockManager service|^StockManager - Phase 3.zip] is also available for download. {note}
The completed StockManager Service is built through Phase 3 of the tutorial. To use the service, simply unzip it to an empty directory.
{note}
h3. Deploy Transfer
The StockManager service takes in a symbol and returns a chart. Since the chart is binary data (i.e., an image), the service uses Transfer to return the chart. Transfer must be deployed to the same container to which the invoking grid service is deployed. Since the StockManager service will be deployed to the non-secure Tomcat container, Transfer will also be deployed to the same container.
Deploy Transfer:
{noformat}
%> cd %CAGRID_LOCATION%/projects/transfer
%> ant -Dno.deployment.validation=true deployTomcat
{noformat}
h1. Adding Identifiers to an Analytical Service
----
Several steps are involved in adding identifiers to the StockManager Service. The basic outline involves adding the createIdentifer operation in Introduce, implementing the operation, and deploying the service to a container. However, several data types and JARs from the identifier's framework will need to be added in order for the service to use them.
h2. Step 1: Import Data Types
----
To begin, data types that will be used by the StockManager service first need to be imported.
# Copy *c:%CAGRID_LOCATION%\projects\identifiers-namingauthority-gridsvc\schema\IdentifiersNAService* (containing the IdentifiersNAServiceTypes.xmd and org.cagrid.identifiers.namingauthority.xmd files) to *C:\StockManager\schema*.
# Next, import the data types into the StockManager service through Introduce:
## Start Introduce:
{noformat}
%> cd CAGRID_LOCATION
%> ant introduce
{noformat}
## Open the StockManager service by selecting "Modify Service" and then browsing to the StockManager directory.
## Select the *Types* tab.
## In the panel on the right, select the *Add/Remove* tab.
## Within this tab, select the *File System* tab.
### Browse to the C:%CAGRID_LOCATION%\projects\identifiers-namingauthority-gridsvc\schema\IdentifiersNAService directory and select the file "org.cagrid.identifiers.namingauthority.xsd".
### Click *Add*.
### The identifier data types have now been added on the left.
\\
{center} !Adding Identifiers to an Analytical Service1.PNG!{center}
\\
3. *Save* the service.
h2. Step 2: Create the getIdentifier Method
----
Now that the data types have been added, we can use Introduce to add a new method using these data types to the service.
# Select the *Services* tab.
# Select "StockPortfolioManager (Service Context)", and then click *Add Method* on the right.
# Enter "getIdentifier" for the *Method Name*.
# Enter "Returns an identifier for the portfolio" in the *Method Description* field.
# Click the *Output* tab.
# Double-click "String" from the list on the left under "Data Types".
\\
{center} !Adding Identifiers to an Analytical Service2.PNG!{center}
\\
7. Click *Done*.
8. *Save* the service.
You should now see the "getIdentifer" method added on the left under "StockPortfolioManager (Service Context)."
\\
{center} !Adding Identifiers to an Analytical Service3.PNG!{center}
\\
h2. Step 3: Add the Necessary JARs to the Project Library
----
Since the createIdentifier operation has been created and the service has been saved, Introduce has generated all of the required code for the operation to work as the grid service operation. Next, the operation needs to be implemented by adding the actual code for the operation. Before this can be done, however, the necessary JARs need to be added to the project library for the StockManager service. The JARs are dependencies of the naming authority.
# Open %CAGRID_LOCATION%/projects/identifiers-client/ext/dependencies/impl/jars.
# Copy the following jars to the location "%>StockManager/lib":
#* caGrid-identifiers-namingauthortiy-1.4.jar
#* caGrid-Identifiers-NAService-client-1.4-dev.jar
#* caGrid-Identifiers-NAService-common-1.4-dev.jar
#* caGrid-Identifiers-NAService-stubs-1.4-dev.jar
# Open Eclipse.
# Import the StockManager project:
#* Select *File* and then *Import...*
#* Select *Existing Projects into Workspace* and click *Next*.
#* Browse to the location of the StockManager service and click *Finish*.
# Add the jars to the project library:
#* Right-click on the StockManager project from the Package Explorer window on the left and select *Properties*.
#* Select *Java Build Path* from the left panel in the properties window.
#* Select the *Libraries* tab and then click *Add JARs...*
#* Browse to StockManager/lib and add all of the listed JARs.
#* Click *OK* to close the properties window.
h2. Step 4: Implement the method
----
With the JARs added to the StockManager service library, the operation can now be implemented.
# In a text editor or Eclipse, open the following file:
#* %StockManager%/src/org/cagrid/introduce/tutorial/stockmanager/portfolio/service/StockPortfolioManagerImpl.java
# Add the following imports:
{code}
import gov.nih.nci.cagrid.identifiers.client.IdentifiersNAServiceClient;
import namingauthority.IdentifierData;
import namingauthority.KeyData;
import namingauthority.KeyNameData;
{code}
3. Locate the *getIdentifier* method.
* *Replace*:
{code:java}
//TODO: Implement this autogenerated method
throw new RemoteException("Not yet implemented");
{code}
* *With this*:
{code:java}
//get the portfolio data
org.cagrid.introduce.tutorial.stockmanager.portfolio.service.globus.resource.StockPortfolioManagerResource resource = null;
try {
//get the currently addressed resource
resource = getResourceHome().getAddressedResource();
} catch (Exception e1) {
throw new RemoteException("Unable to locate resource: " + e1.getMessage());
}
//get that resource instance's portfolio
Portfolio port = resource.getPortfolio();
//get NA service URL
String identifiersNAServiceURL = "https://identifiers-na.training.citih.osumc.edu:8443/wsrf/services/cagrid/IdentifiersNAService";
try{
Map<String,String> symbolQuoteMap = getSymbolQuoteMap(port);
Set<String> keySet = symbolQuoteMap.keySet();
String[] symbols = keySet.toArray(new String[keySet.size()]);
String[] quotes = new String[ keySet.size() ];
for (int i = 0; i<keySet.size(); i++) {
quotes[i] = symbolQuoteMap.get(symbols[i]);
}
String[] keys = new String[] { "SYMBOLS", "QUOTES" };
String[][] values = new String[][]{ symbols, quotes };
KeyNameData[] kvs = new KeyNameData[ keys.length ];
for( int i=0; i < keys.length; i++) {
KeyData kd = new KeyData();
kd.setValue(values[i]);
kvs[i] = new KeyNameData(kd, keys[i]);
}
IdentifierData id = new IdentifierData(kvs);
IdentifiersNAServiceClient client =
new IdentifiersNAServiceClient(identifiersNAServiceURL);
URI identifier = client.createIdentifier(id);
String identifierString = identifier.toString();
return identifierString;
}
catch (MalformedURIException e) {
throw new RemoteException(e.getMessage());
}
}
private Map<String,String> getSymbolQuoteMap(Portfolio port) {
//return a generated portfolio instance
Symbols symbols = port.getSymbols();
String[] symbolsArray = symbols.getSymbol();
org.cagrid.introduce.tutorial.tools.beans.PortfolioInstance portfolioInstance = org.cagrid.introduce.tutorial.tools.PortfolioManager.generatePortfolioInstance(port);
Quotes quotes = portfolioInstance.getQuotes();
Quote[] quoteArray = quotes.getQuote();
Map<String, String> symbolQuoteMap = new HashMap();
for (int i = 0; i < symbolsArray.length; i++) {
symbolQuoteMap.put(symbolsArray[i],quoteArray[i].getQuote());
}
return symbolQuoteMap;
}
}
{code}
h2. Step 5: Implement a Test
----
With the operation implemented, the next step is to test the service. To do this, the Introduce-generated client will be modified to invoke the service operation. By adding a call with getIdentifier operation in the client main method, an identifier will be created for the portfolio and then displayed.
# Open: %STOCKMANAGER%/src/org/cagrid/introduce/tutorial/stockmanager/client/StockManagerClient.java
# Add the following:
{code:java}
import org.cagrid.introduce.tutorial.stockmanager.portfolio.client.StockPortfolioManagerClient;
{code}
# Then, after:
{code:java}
try {
// talking to this one should die
System.out.println(org.cagrid.introduce.tutorial.tools.QuoteTools.PortfolioInstance2String(portfolio2.getPortfolioQuote()));
System.out.println("FAILED: should not have been able to get here. Portfolio 2 should have been destroyed");
} catch (Exception e) {
System.out.println("WORKED: should get here because the second portfolio was destroyed as it should have been");
}
{code}
*Add*:
{code:java}
//request an identifier for the portfolio and display it
String identifierURL = portfolio1.getIdentifier();
System.out.println("Portfolio 1 Identifier: " + identifierURL);
{code}
4. *Delete* the following:
{code:java}
// now i can use the destroy method to remove the first
// portfolio because i am done with it
System.out.println("Destroying Portfolio 1");
portfolio1.destroy();
{code}
5. *Save* the file.
h2. Step 6: Build and Deploy the Service
----
1. In a terminal, change directory to the service and run ant all:
{noformat}
%> cd STOCKMANAGER_LOCATION
%> ant all
{noformat}
If ant does not return a BUILD SUCCESSFUL make sure you do not have a typo in the client implementation file.
2. Deploy the project in a command prompt:
{noformat}
%> cd STOCKMANAGER_LOCATION
%> ant \-Dno.deployment.validation=true deployTomcat
{noformat}
h2. Step 7: Verify
----
To recap, the createIdentifier operation has been created and implemented, a test for the operation has been added to the client, and the service has been deployed to a container. To verify that the service is running, start the Tomcat container:
{noformat}
%> cd CATALINA_HOME\bin
%> startup.bat
{noformat}
Once the container is started, verify that the service is running by accessing the grid service URL in a browser: [http://localhost:8080/wsrf/services/cagrid/StockManager].
*You should see the following:*
{center} !Adding Identifiers to an Analytical Service4.PNG!{center}
Next, run the client to verify that the StockManager is able to create identifers:
{noformat}
%> cd STOCKMANAGER_LOCATION
%> ant runClient
{noformat}
You should see an output similar to the following:
\\
{center} !Adding Identifiers to an Analytical Service5.PNG!{center}
\\
Here you can see that the identifier is displayed for your use. A [identifiers:completed StockManager service that uses identifiers|^StockManager - ID.zip] has been provided if you would like to work with identifiers without going through this tutorial. To use the service, complete the prerequisites and deploy the service to a container.