5.9. A slightly less simple client

We will now split the previous client into two client applications: a client in charge of creating the resource, and a client in charge of invoking the add operation in the instance service. The first client writes the endpoint reference of the new resource to a file, which will later be read by the second client.

5.9.1. The creating client

The first client expects at least one parameter from the command line: the factory service's URI. A second parameter, with the name of the file where the EPR must be written to, can also be specified. If it isn't, then it will be saved to a file called epr.txt.

package org.globus.examples.clients.FactoryService_Math;

import java.io.BufferedWriter;
import java.io.FileWriter;

import org.apache.axis.message.addressing.Address;
import org.apache.axis.message.addressing.EndpointReferenceType;
import org.globus.examples.services.core.factory.impl.MathQNames;

import org.globus.examples.stubs.MathService_instance.MathPortType;
import org.globus.examples.stubs.MathService_instance.service.MathServiceAddressingLocator;
import org.globus.examples.stubs.Factory.service.FactoryServiceAddressingLocator;
import org.globus.examples.stubs.Factory.FactoryPortType;
import org.globus.examples.stubs.Factory.CreateResource;
import org.globus.examples.stubs.Factory.CreateResourceResponse;
import org.globus.wsrf.encoding.ObjectSerializer;

public class ClientCreate {

	static final String EPR_FILENAME = "epr.txt";

	public static void main(String[] args) {
		FactoryServiceAddressingLocator factoryLocator = new FactoryServiceAddressingLocator();
		MathServiceAddressingLocator instanceLocator = new MathServiceAddressingLocator();

		try {
			String factoryURI = args[0];
			String eprFilename;
			
			if(args.length==2)
				eprFilename=args[1];
			else
				eprFilename=EPR_FILENAME;
			
			EndpointReferenceType factoryEPR, instanceEPR;
			FactoryPortType mathFactory;
			MathPortType math;
			
			1
			factoryEPR = new EndpointReferenceType();
			factoryEPR.setAddress(new Address(factoryURI));
			mathFactory = factoryLocator.getFactoryPortTypePort(factoryEPR);

			CreateResourceResponse createResponse = mathFactory
					.createResource(new CreateResource());
			instanceEPR = createResponse.getEndpointReference();

			2
			String endpointString = ObjectSerializer.toString(instanceEPR,
					MathQNames.RESOURCE_REFERENCE);
			FileWriter fileWriter = new FileWriter(eprFilename);
			BufferedWriter bfWriter = new BufferedWriter(fileWriter);
			bfWriter.write(endpointString);
			bfWriter.close();
			System.out.println("Endpoint reference written to file "
					+ eprFilename);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

[Note]

This file is $EXAMPLES_DIR/org/globus/examples/clients/FactoryService_Math/ClientCreate.java.

1

As in the previous client, here we obtain a reference to the factory's portType and use it to invoke the createResource operation, that returns and endpoint reference to the new resource.

2

This block of code writes the endpoint reference to a file. We use the Globus-supplied class ObjectSerializer, which creates an XML representation of the EPR. Note that we need to specify the QName of the root element of the XML file. We can choose any name we want but, for clarity, it is best to choose a QName inside our service's namespace. The QName we're using is declared in the MathQNames interface:

public static final QName RESOURCE_REFERENCE = new QName(NS,
		"MathResourceReference");

Now compile the client:

javac \
-classpath ./build/stubs/classes/:$CLASSPATH \
org/globus/examples/clients/FactoryService_Math/ClientCreate.java
java \
-classpath ./build/stubs/classes/:$CLASSPATH \
org.globus.examples.clients.FactoryService_Math.ClientCreate \
http://127.0.0.1:8080/wsrf/services/examples/core/factory/MathFactoryService

If all goes well, you should see the following:

Endpoint reference written to file epr.txt

Let's take a look inside the epr.txt file:

<ns1:MathResourceReference xsi:type="ns2:EndpointReferenceType"
    xmlns:ns1="http://www.globus.org/namespaces/examples/core/MathService_instance"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:ns2="http://schemas.xmlsoap.org/ws/2004/03/addressing">
 
    <ns2:Address xsi:type="ns2:AttributedURI">
    http://127.0.0.1:8080/wsrf/services/examples/core/factory/MathService
    </ns2:Address>
 
    <ns2:ReferenceProperties xsi:type="ns2:ReferencePropertiesType">
        <ns1:MathResourceKey>24156236</ns1:MathResourceKey>
    </ns2:ReferenceProperties>
    
    <ns2:ReferenceParameters xsi:type="ns2:ReferenceParametersType"/>

</ns1:MathResourceReference>

Notice how the endpoint reference does, in fact, include the instance service's URI and the resource's key. Note that you will almost certainly get a different key in your resource.

5.9.2. The adding client

This client expects two arguments from the command line. The first argument is a service's URI or the name of a file containing and endpoint reference. The client is implemented to recognize both formats since, in the next chapters, we will use this client again to interact with singleton services (where we only need the service's URI, without a resource key, to address the service). The second argument is the value we wish to add.

package org.globus.examples.clients.MathService_instance;

import java.io.FileInputStream;

import org.apache.axis.message.addressing.Address;
import org.apache.axis.message.addressing.EndpointReferenceType;

import org.globus.examples.stubs.MathService_instance.GetValueRP;
import org.globus.examples.stubs.MathService_instance.MathPortType;
import org.globus.examples.stubs.MathService_instance.service.MathServiceAddressingLocator;
import org.globus.wsrf.encoding.ObjectDeserializer;
import org.xml.sax.InputSource;

public class ClientAdd {

	public static void main(String[] args) {
		MathServiceAddressingLocator instanceLocator = new MathServiceAddressingLocator();

		try {
			int value = Integer.parseInt(args[1]);
			EndpointReferenceType instanceEPR;

			if (args[0].startsWith("http")) {
				1
				// First argument contains a URI
				String serviceURI = args[0];
				// Create endpoint reference to service
				instanceEPR = new EndpointReferenceType();
				instanceEPR.setAddress(new Address(serviceURI));
			} else {
				2
				// First argument contains an EPR file name
				String eprFile = args[0];
				// Get endpoint reference of WS-Resource from file
				FileInputStream fis = new FileInputStream(eprFile);
				instanceEPR = (EndpointReferenceType) ObjectDeserializer
						.deserialize(new InputSource(fis),
								EndpointReferenceType.class);
				fis.close();
			}

			3
			// Get PortType
			MathPortType math = instanceLocator
					.getMathPortTypePort(instanceEPR);

			// Perform addition
			math.add(value);

			// Access value
			System.out
					.println("Current value: " + math.getValueRP(new GetValueRP()));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

[Note]

This file is $EXAMPLES_DIR/org/globus/examples/clients/MathService_instance/ClientAdd.java.

1

If the user specifies a URI, then we create the instance's EPR simply by creating a new EndpointReferenceType object and setting it's URI to the one passed as a parameter.

2

If the user specifies a file, then we create the instance's EPR by reading the XML file using the Globus-supplied ObjectDeserializer class.

3

Finally, we use the instance EPR to obtain a reference to the MathPortType. We use this portType to invoke the add operation with the value specified in the second parameter of the client.

Now, compile and run the client:

javac \
-classpath ./build/stubs/classes/:$CLASSPATH \
org/globus/examples/clients/MathService_instance/ClientAdd.java
java \
-classpath ./build/stubs/classes/:$CLASSPATH \
org.globus.examples.clients.MathService_instance.ClientAdd \
epr.txt \
10

If all goes well, you should see the following:

Current value: 10

If you run the adder client several times using the same EPR file, you will be able to observe how the value in the resource keeps getting bigger and bigger.

Current value: 20
Current value: 30