Difference between revisions of "The Development Cycle"

From GCube System
Jump to: navigation, search
(A PortType Interface)
(A PortType Interface)
Line 139: Line 139:
 
</pre>
 
</pre>
  
All pretty standard, of course. To notice, however:
+
All pretty standard [http://www.w3.org/TR/wsdl|WSDL], of course. And yet notice what follows:
  
 
* we dedicate the WSDL to a single port-type (even though multiple port-types are admitted by the WSDL specs). This simplifies our building configuration and suggests than any form of sharing across port-types (type definition, messages, faults, etc.) be achieved through imports/includes.  
 
* we dedicate the WSDL to a single port-type (even though multiple port-types are admitted by the WSDL specs). This simplifies our building configuration and suggests than any form of sharing across port-types (type definition, messages, faults, etc.) be achieved through imports/includes.  
Line 183: Line 183:
 
As you can see:
 
As you can see:
  
* we have used the namespace ''http://acme.org/sample'' for our port-type.
+
* we have used the namespace http://acme.org/sample for our port-type.
 
* we have settled on the name ''Stateless'' for it, and used it twice. The first time to name the whole interface definition and a second time in the name ''StatelessPortType'' of the ''portType'' definition.
 
* we have settled on the name ''Stateless'' for it, and used it twice. The first time to name the whole interface definition and a second time in the name ''StatelessPortType'' of the ''portType'' definition.
 
* we have defined a single operation ''about'' for ''Stateless'', which takes and returns a string. The idea is to expect the name of the caller as input and produce some information about the port-type as output.
 
* we have defined a single operation ''about'' for ''Stateless'', which takes and returns a string. The idea is to expect the name of the caller as input and produce some information about the port-type as output.

Revision as of 22:50, 11 April 2008

Let us go through a quick tour of development with SampleService.

My First Profile

A good starting point with service development is its configuration. And a good starting point when configuring a service is the definition of its profile. The role and structure of gCube service profiles is described in detail elsewhere. Here we just show one of the smallest and yet perfectly well-formed profile a service may have:

<?xml version="1.0" encoding="UTF-8"?>
<Resource xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<ID></ID>
	<Type>Service</Type>
	<Profile>
		<Description>A very simple gCube Service</Description>
		<Class>Samples</Class>
		<Name>SampleService</Name>
		<Version>1.0</Version>
		<Packages>
			<Main>
				<Name>Main</Name>
				<Version>1.0</Version>
				<Dependencies>
					<Dependency>
						<Service>
							<Class>Samples</Class>
							<Name>SampleService</Name>
						</Service>
						<Package>Stubs</Package>
						<Version>1.0</Version>
						<Scope level="GHN"/>
						<Optional>false</Optional>
					</Dependency>
				</Dependencies>
				<GARArchive>org.acme.sample.gar</GARArchive>
				<PortType>
					<Name>acme/sample/stateless</Name>
					<WSDL>...</WSDL>
				</PortType>
			</Main>
			<Software>
				<Description>Describes port-type stubs</Description>
				<Name>Stubs</Name>
				<Version>1.0</Version>
				<Files><File>org.acme.sample.stubs.jar</File></Files>
			</Software>
		</Packages>
	</Profile>
</Resource>

By necessity, this profile reveals things yet to come. For the time being, be happy with a conceptual summary:

  • SampleService is a a particular type of gCube Resource, one of type Service. Like all gCube Resources has an ID, which it receives when it is formally registered with the infrastructure. Until then, SampleService does not have a proper identifier. No worries though, a temporary one will be generated by gCF at runtime.
  • The profile of SampleService specifies its Name and specifies its membership to a Class of functionally related gCube services. Classes are not pre-defined, and here we settle on Samples. A free-form Description and a Version complement the preliminary description of SampleService.
  • SampleService is physically comprised of Packages. A Main package identifies the main artefact to emerge from the build of the service, a GARArchive, and provides information about the service port-types, including their WSDLs' (here omitted for mercy). The profile unveils our initial plans for a single stateless port-type, which we name by identifying the relative part of the URI at which it will be accessible on the gHN (more on this soon).
  • Another Software component identifies the secondary build artefact of the service, its own stubs. The Main package depends always upon its stubs and this dependency must be explicitated.

Note: If the notion of build artefact is not obvious to you, bide your time for a little longer or jump ahead.

Save the profile in a file called profile.xml and place it in the etc folder of the service implementation:

|-SampleService
|--etc
|---profile.xml
|--src
|--schema
|
|-Dependencies
|--SampleService

A Tiny JNDI

Next we move to the configuration of the code itself, for which we use JNDI technology. Again, the details and granularity of JNDI configuration are discussed elsewhere. Here we simply notice that, while the JNDI configuration might contain any information which the code needs to consult at runtime, the gCF raises precise requirements against the existence and shape of some of that information. In particular, the configuration should at least contain the following information:

<?xml version="1.0" encoding="UTF-8"?>
<jndiConfig xmlns="http://wsrf.globus.org/jndi/config">

	<service name="acme/sample">
		<environment  name="configDir" value="@config.dir@"  type="java.lang.String" override="false" />
	</service>

</jndiConfig>

Essentially, the configuration must have a service section dedicated to information conceptually associated with the entire implementation, rather than more specific components yet to come. Furthermore, the service section must:

  • specify the name of the service. This is not particularly constrained but must distinguish SampleService from any other which may be deployed on the same gHN. As we already do with Java and URI namespaces, we can approach uniqueness through a hierarchical structure, here of /-separated strings. In our case, the name acme/sample will suffice as a unique identifier.
  • include an environment element which specifies the absolute path to the configuration folder of SampleService. Contrary to expectations, this is not our etc folder under the service location. It is in fact another configuration folder allocated to SampleService at the point of service deployment. This will become clearer later. For the time being, we use the wildcard @config.dir@ to abstract over the precise location of this yet-to-be folder, and leave to gCore the task of resolving it at the point of deployment.

Note: The wildcard @config.dir is surely convenient at this stage. It is in fact necessary for any real gCube service. This is because the service may be dynamically deployed on any gHN and the absolute path of the configuration folder depends on the file system of that gHN. During service development, that location is an absolute unknown.

So far, there is little in our configuration which is specific to SampleService. Indeed, the JNDI above can be considered as boilerplate for any gCube service. We will see shortly how to inject more information into the JNDI configuration, but until that moment this minimal configuration will suffice.

Save the configuration in a file called deploy-jndi-config.xml and place it in the etc folder of the service implementation:

|-SampleService
|--etc
|---profile.xml
|---deploy-jndi-config.xml
|--src
|--schema
|
|-Dependencies
|--SampleService


A PortType Interface

Enough configuration for now. Let us move to the definition of the WSDL interface for the first port-type we plan to add to SampleService. The general expectation is that all your interfaces will have this high-level structure:

<?xml version="1.0" encoding="UTF-8"?>
<definitions 
               xmlns:tns="..YOUR NAMESPACE.." targetNamespace="...YOUR NAMESPACE..." name="..SOME_NAME... "
               xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" >

	<types>
	   <xsd:schema targetNamespace=".....">
			<!-- REQUEST & RESPONSE TYPE DEFINITIONS -->
	    </xsd:schema>
	</types>
	
	<!-- MESSAGE DEFINITIONS  -->

	<portType name="...PORT_TYPE NAME...portType">
		<!--OPERATIONS DEFINITIONS -->
	</portType>

</definitions>

All pretty standard [1], of course. And yet notice what follows:

  • we dedicate the WSDL to a single port-type (even though multiple port-types are admitted by the WSDL specs). This simplifies our building configuration and suggests than any form of sharing across port-types (type definition, messages, faults, etc.) be achieved through imports/includes.
  • the name of the WSDL definitions does not play much of a role during development. Use anything that looks appropriate. Given that there is a one-to-one correspondence between WSDLs and port-types use, any informal name you may wish to give to the port-type.
  • the name of the portType also refers to the port-type, though this has a very important role during the build of the service. In particular, it must end in portType.

The WSDL of our first port-type illustrate these conventions:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns:tns="http://acme.org/sample" name="Stateless" targetNamespace="http://acme.org/sample"
    xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"  >

	<types>
		<xsd:schema targetNamespace="http://acme.org/sample">

			<xsd:element name="about" type="xsd:string"/>
			<xsd:element name="aboutResponse" type="xsd:string"/>

		</xsd:schema>
	</types>

	<message name="aboutInputMessage">
		<part name="request" element="tns:about"/>
	</message>
	<message name="aboutOutputMessage">
		<part name="response" element="tns:aboutResponse"/>
	</message>

	<portType name="StatelessPortType">
		    
             <operation name="about">
			<input message="tns:aboutInputMessage"/>
			<output message="tns:aboutOutputMessage"/>			
		</operation>

	</portType>
</definitions>

As you can see:

  • we have used the namespace http://acme.org/sample for our port-type.
  • we have settled on the name Stateless for it, and used it twice. The first time to name the whole interface definition and a second time in the name StatelessPortType of the portType definition.
  • we have defined a single operation about for Stateless, which takes and returns a string. The idea is to expect the name of the caller as input and produce some information about the port-type as output.

Hard to imagine a simpler port-type, really.

A Simple Implementation

Building & Deploying

Logging it

A Test Client