5.3. The factory service

We begin by implementing the factory service. The WSDL file for the factory service is very simple, as we only have a single operation createResource with no parameters and that returns an endpoint reference.

[Note]

you should be able to read the file and recognize that there is, indeed, a single operation createResource with no parameters and returning an endpoint reference. If not, this might be a good time to review Section A.1, “...write a WSDL description of your WSRF stateful Web service”.

<?xml version="1.0" encoding="UTF-8"?>
<definitions name="FactoryService"
    targetNamespace="http://www.globus.org/namespaces/examples/core/FactoryService" 1
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:tns="http://www.globus.org/namespaces/examples/core/FactoryService"
    xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" 2
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">


<!--============================================================

                      T Y P E S
                      
  ============================================================-->
<types>
<xsd:schema targetNamespace="http://www.globus.org/namespaces/examples/core/FactoryService"
    xmlns:tns="http://www.globus.org/namespaces/examples/core/FactoryService"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">

	3
	<xsd:import
	    namespace="http://schemas.xmlsoap.org/ws/2004/03/addressing"                
	    schemaLocation="../../ws/addressing/WS-Addressing.xsd" />


	<!-- REQUESTS AND RESPONSES -->

	<xsd:element name="createResource">
		<xsd:complexType/>
	</xsd:element>
	<xsd:element name="createResourceResponse">
	<xsd:complexType>
		<xsd:sequence>
			<xsd:element ref="wsa:EndpointReference"/>
		</xsd:sequence>
	</xsd:complexType>
	</xsd:element>
        
</xsd:schema>
</types>


<!--============================================================

                       M E S S A G E S
                      
  ============================================================-->
<message name="CreateResourceRequest">
	<part name="request" element="tns:createResource"/>
</message>
<message name="CreateResourceResponse">
	<part name="response" element="tns:createResourceResponse"/>
</message>



<!--============================================================

                       P O R T T Y P E
                      
  ============================================================-->
4
<portType name="FactoryPortType">

	<operation name="createResource">
		<input message="tns:CreateResourceRequest"/>
		<output message="tns:CreateResourceResponse"/>
	</operation>

</portType>

</definitions>

[Note]

This file is $EXAMPLES_DIR/schema/examples/FactoryService/Factory.wsdl.

1

The factory service's target namespace is http://www.globus.org/namespaces/examples/core/FactoryService.

2

The service's createResource operation returns an endpoint reference, a structure that is part of the WS-Addressing specification. We need to declare the WS-Addressing namespace.

3

We also need to import the WS-Addressing Schema file, which contains the definition of the endpoint reference structure (wsa:EndpointReference)

4

Our portType, FactoryPortType, has a single operation createResource.

Since we have added a new interface, we need to map the new WSDL namespaces to Java packages (as described in Section 3.1.3, “Namespace mappings”)

http\://www.globus.org/namespaces/examples/core/FactoryService=
                                     org.globus.examples.stubs.Factory
http\://www.globus.org/namespaces/examples/core/FactoryService/bindings=
                                     org.globus.examples.stubs.Factory.bindings
http\://www.globus.org/namespaces/examples/core/FactoryService/service=
                                     org.globus.examples.stubs.Factory.service
[Note]

These three lines must be present in $EXAMPLES_DIR/namespace2package.properties.

Now, we have to write the Java implementation of the factory service. This will be a single Java class, with a single createResource method:

public class MathFactoryService {

	/* Implementation of createResource Operation */
	public CreateResourceResponse createResource(CreateResource request)
			throws RemoteException {

	}
}
[Note]

This is part of file $EXAMPLES_DIR/org/globus/examples/services/core/factory/impl/MathFactoryService.java.

Inside this method, we will perform three steps:

  1. Retrieve the resource home.

  2. Use the resource home to create a new resource.

  3. Create the endpoint reference we will return to the client. This EPR must contain the instance service's URI and the new resource's key.

In the following snippet of code we perform steps 1 and 2:

ResourceContext ctx = null;
MathResourceHome home = null;
ResourceKey key = null;
try {
	ctx = ResourceContext.getResourceContext();
	home = (MathResourceHome) ctx.getResourceHome();
	key = home.create();
} catch (Exception e) {
	throw new RemoteException("", e);
}

If we succeed in retrieving the resource home, then the key variable will contain the resource's identifier, which we'll use to construct the endpoint reference:

EndpointReferenceType epr = null;

try {
	URL baseURL = ServiceHost.getBaseURL();
	String instanceService = (String) MessageContext
			.getCurrentContext().getService().getOption("instance");
	String instanceURI = baseURL.toString() + instanceService;
	// The endpoint reference includes the instance's URI and the resource key
	epr = AddressingUtils.createEndpointReference(instanceURI, key);
} catch (Exception e) {
	throw new RemoteException("", e);
}

Notice how we have to create a new endpoint reference (of type EndpointReferenceType) using the instance server's URI (instanceURI) and the resource's identifier (key). Finally, the only thing left to do is to 'box' the EPR inside a CreateResourceResponse object and return it.

CreateResourceResponse response = new CreateResourceResponse();
response.setEndpointReference(epr);
return response;
[Note]

Remember from the information box How document/literal bindings affect our parameters in Section 3.2, “Step 2: Implementing the service in Java” that whenever one of our operations returns a complex type (such as an endpoint reference), it is 'boxed' inside a stub class.

[Note]

Now is a good moment to review Figure 5.3, “Sequence diagram for resource creation”.