Before someone decides to build grid services they should at least be familiar with basic grid service architecture and also that of statefull grid services if they plan to create asynchronous services and/or statefull services. To read more about grid service architecture and grid middleware to refresh your memory or get basic understanding please read some of the following basic information:
The Introduce toolkit is designed to support the three main steps of service development: 1) Creation of Basic Service Structure. The service developer describes at the highest level some basic attributes about the service such as service name and service namespace. Once the user has set these basic service configuration properties, Introduce will create the basic service implementation, to which the developer can then add application-specific methods and security options through the service modification steps. 2) Service Modification. The modification step allows the developer to add, remove, and modify service methods, properties, resources, service contexts, and service/method level security. In this step, the developer can create a strongly-typed service interface using well-defined, published schemas, which are registered in a system like the Mobius GME, as the type definitions of the input and output parameters of the service methods. One the operations are added to the service the developer will then be able to add the logic which implements the methods. 3) Deployment. The developer can deploy the service which has been created with Introduce to a Grid service container (e.g., a Globus or Tomcat service container). A service developer can access the functions required to execute these three steps through the Graphical Development Environment (GDE) of Introduce. The runtime support behind the GDE functionality is provided by the Introduce engine, which consists of the Service Creator, Service Synchronizer, and Service Deployer components. The toolkit provides an extension framework that allows Introduce to be customized and extended for custom service types and discovery of custom data types. In the following sections, we describe the software prerequisites, the Introduce Graphical Development Environment, the Introduce Engine, and the Introduce Extension Framework in greater detail.
- Java 1.5 or greater (http://www.java.sun.com)
- Apache Ant 1.6.5 or 1.7.0 (http://www.ant.apache.org)
- The Globus Toolkit Version 4.0.x (http://www.globus.org)
- Refactored GUI to be easier to use and manage services.
- Removed ServiceTasks JDOM dependecy to the services lib directory and moved it to the tools directory.
- Added abiilty for services to be undeployed
- Added ability to have resources persisted
- using XMLPersistanceHelper customized from globus
- Renamed some service files so that they all now start with the service name
- Moved constants file to common so that client and service can both use them
- Now using jaxmejs 0.5.2 with JAXME-77 patch applied
- Added ws-notification support as a resource framework option
- Added support for configuring resource framework options from a list of options
- Fixed problems with finding first letter upper cased methods for addition and removal
- Fixed problems when having introduce imported methods that have no package for the return type (void)
- Refactored the Resource framework to be one set of templates instead of three
- caused changes to the services.xsd to support the new way of describing the resource framework options as a list instead of one string
The Introduce Graphical Development Environment (GDE) can be used to create, modify, and deploy a grid service. It is designed to be very simple to use, enable using community accepted data types, and provide easy configuration of service metadata, operations, resources, and security. It also allows customized plug-ins to be added for such things as discovering data types from grid repositories and for creating custom service style design templates.
The Introduce GDE contains several screens and options for the service developer to 1) create a new service, 2) modify an existing service, 3) discover and use published data types in order to create strongly-typed service methods, and 4) deploy the service.
The service creation component, shown below, enables the developer to create a new grid service. Using the creation interface, the service developer can provide basic information about the service such as:
- Creation Directory
The creation directory is the location of which the grid service will be generated.
- Service Name
Service name is the name that will be used to generate the service. The service name must be a valid java identifier.
- Package Name
The package name is the base package to be used when generated the grid service source code.
The namespace is the namespace to be used when defining the WSDL of the service.
The developer also has the ability to add service extensions. A service extension is an Introduce plug-in (see Service Extensions), which is designed to add customizations to the service. For example, service extensions might add pre-defined operations, resources/resource properties, or security settings. They enable the development of custom service types with predefined methods, which must be implemented. They also enable Introduce to run the custom code implemented in the plug-in, which makes modifications to the underlying service being created. This capability allows the specialization of Introduce to support domain specific common scenarios, further abstracting the individual service developer from responsibilities related to the deployment of grid technologies in a production environment. Once the information has been entered and extensions, if any, have been selected, the user will select the create button. Once the creation button is selected the Introduce creation engine will begin generating the service. After the service is generated is will be compiled and the Modification component will be displayed.
Service modification can be performed on any new or previously modified Introduce generated service. The service developer can perform a series of operations in order to begin to customize the grid service or modify the existing grid service. The overall flow in the modification of a grid service is to first use the namespaces tab to be sure that all the data types that are desired to be used I the grid service have been selected and added to the service. Next the service can choose to either add/remove or modify operations, metadata in the form of resource properties, service properties, security setting, and service contexts. The following sections will describe in detail how each of the components of the modification viewer can be used to modify the grid service to achieve desired functionality. By selecting the "Modify Service" button on the main menu a prompt will apear to enable choosing the service to be modified. Once the desired directory containing the service to be modified is selected the modification viewer component will be launched. The modification viewer contains 6 main areas where modifications can occur on the main service:
The first task in the modification of a grid service is to discover the data types that are desired to be used as the input and output types of methods of the service and the data types for describing the resource properties of the service. Adding a data types to the service is equivalent to copying schemas into the schema location of the service and importing the schemas into the WSDL file so that the types can be referenced by the service. This is done via the "Types" tab of the Graphical Service Modification Environment. This tab shows the current types the service is using, and provides access to the data type discovery components (such as the Mobius GME), for selecting and configuring additional types. The "Select Type" frame enables several types of ways to locate data types and bring them into the service. Currently there are three main discovery mechanisms (GME, Globus, and File System) that come with introduce, however, this is extensible via the Discovery Extension described in the Extensions section. Once a set of data types from a namespace are brought into the service the user has the ability to describe how these data types will be mapped into there respective Java classes. This can, by default, be done automatically by Introduce via Axis. By default, Axis will create new java beans for each data type and also provide a serializer and deserializer for those objects. If for example, a set of objects already exist for this particular data types then a user can decide to provide there own classes and serialization/deserialization factories.
Using the GDE, developers can obtain the data types that they want to use for operation input parameters and return types from any data type discovery plug-in. Utilizing common and standard data types, which are defined outside of any application-specific service, enables the creation of strongly typed grid service interfaces. This increases service-to-service interoperability. Once a data type is chosen through the GDE, the data type definition is retrieved, written into the schema/<service_name> location of the service, and imported for use in the service WSDL description so that Java beans can be generated and the data types can be programmatically used.
The Introduce toolkit comes with a set of pre-installed discovery plug-ins, such as the Mobius GME and a basic file system browser, which can be used to locate and import schemas. The GME plug-in enables developers to browse, upload, and download schemas published in a GME. These schemas represent the valid data types which can be used during service creation. Using the GME plug-in, a developer can take a schema, create an editable view of the schema, and then submit the schema to the GME. If the namespace of the schema is not managed by the GME, to which the schema is submitted, the plug-in will attempt to add the namespace to the GME before submitting the schema. Once the schema has been uploaded, it can be used by anyone in the Grid through the Introduce toolkit. The GME plug-in browser window enables browsing through all the GME published types by namespace and schema name. It presents the user a quick view of the schema and the option to download the schema bundle. The schema bundle contains the schema and all other schemas which are referenced by that schema.
When importing a data types there are several options in where to acquire the data type definitions. Introduce is build in with the following data type definition tools, however, this is a pluggable piece of Introduce. Once a data type is imported using an import tool that data type can be customized for the generation of Java Beans. If you select data type on the left you will see in the lower left panel that the namespace and package name have been listing. This is called the namespace to package map. This will determine the package name of the Java Beans that get created for the data type. Feel free to alter the package name if the Introduce suggested package name does not work well.
- File System Data Type Importing The File System tab of the Import Data Types Panel enables the developer to load in schemata which contain data types they wish to use the service from the local filesystem. The developer can browse to choose the schema they wish to import, and the click the add button. Once the add button is clicked the schema and any locally included or imported schemata will be copied to the services schema location in theschema/<service name>directory.
- Global Model Exchange Data Type Importing The Global Model Exchange Data Type extension enables browsing for schemata from a remote grid service which is responsible for storing them. Introduce can connect to a GME and load in all the available namespaces the GME is storing schemata for. Once the developer selects a namespace the name drop down will be populated with all the available schema names for that schema. Once a namespace and name have been selected then user can select the add button and the schema and any imported schemata will be downloaded and imported into the service. The mainConfigurationmenu at at the top for the GDE will contain the ability for changing the location of the GME to use.
- Globus Data Types Importing The Globus Data Types extension enable the developer to import schema from the Globus toolkit into their service. There is a drop down containing a list of the available schemata from the current installation of the Globus Tooolkit. Once a namespace has been selected and the add button has been selected then the schema will be added to the service's available data types list.
Introduce will enable re-importing of a data type if the developer wants to re-import a particular schema which may have been modified or extended. In order to do this you must make sure the "Namespace Type Replacement Policy" configuration setting in the Introduce "Configuration-->Preferences" menu is set to "warn". Once this is done you can simply browse back to the data model and import it again.
Once a namespace and corresponding data types have been imported into the service each data type can be further customized. For a particular data type one can chose to use a Custom Java Bean that already exists instead of having Introduce create the java beans for the service. This can be accomplished by selecting the Configure Types tab in the Types tab and then the + button beside the Customize Bean label. This will drop down the customization panel for that particular data type. In this panel, to support using a custom bean for the selected data type definition, the developer must fill out the three fields: the classname of the bean to be used (make sure the package name above matches the package name being entered for the custom beans classname), the deserializer factory class, and the serializer factory class. For more information on using custom serialization or what it means to be a custom bean please refer to the most recent Globus documentation on type mapping.
The services tab of the GDE is the main tab for editing a service. It contains a tree which shows all the services or service contexts which are part of your service, their methods, and their resource properties. This tree is the main view of the services which will be deployed as part of a deployment of your introduce service. You have the ability to add new service contexts, add/remove/modify operations on a particular service, and add/remove/modify resource properties of a particular service.
Once in the tree view of the Services tab you can right click on any service and select the Edit button. This will pop up a window, like the image below, that will enable the user to configure the service context. From this pop up window the resource framework options can be added or removed, and service level security can be configured.
- CustomEnables the user to provide there own implantation of the resource class.
The service will only have one instance of the resource.
The resources created by this service will support the WS-Lifetime specification and therefore the service will implement the setTerminationTime operation as part of its wsdl.
The resource created by this service will automatically persist and resource properties and notification to the file system so that if the container is restarted they will come back to life.
The resource will implement SecureResource and therefore have the getServiceSecurityProvider so that it can provide a security descriptor for the particular instance of the resource.
The resource created by this service will automatically support he WS-Notification specification and therefore the service will implement the subscribe operation in its wsdl and the client will have operations to make subscriptions and utilize notifications.
- Resource Property Access
The resource will implement the getResourcePropterty, getResourceProperties and QueryResourceProperty operations and these methods will be exposed through the service's wsdl.
Introduce exposes the functionality of Globus GSI through a set of panels which enable the user to customize security for the entire service or specific methods on an service context. The user can choose any of the GSI configuration scenarios such as Transport Level Security with Integrity and Secure Communication with Privacy. Introduce also enables configuring a particular service, operation, or resource, for authorization. Introduce comes with capabilities to configure authorization using GridGrouper and/or Common Security Model, or a Custom PDP based authorization chain. Graphical panels will enable the user to describe an authorization policy which must be met in order to give access to the particular service or operation. For detailed knowledge of what the configuration options for Secure Conversation or Secure Credentials are please refer to documentation for the GSI framework.
The developer can add, remove, or modify operations on the service, using the "Operations" tab of the GDE Service Modification interface. For each operation, the developer needs to set the input parameters, return type, and any fault types that can be thrown from each service method. The security configuration of the operation should also be set if desired. The input and output types can be selected from the types tree on the left. This tree represents the available data types which can be used by this service. If any input parameter or output type is to be an array the array checkbox must be checked in the table on the right. Also, once an input parameter is added the name of the parameter is defaulted. This name can be edited by the developer by selected the cell in the name column and editing the text. There are two ways to add faults, either choose a type from the types tree which extends WSRF BaseFaultType or create a new fault which will tell Introduce to create you a new fault type which extends the BaseFaultType.
The implementation of a described operation may already exist in another class which is provided by a jar file. You can tell Introduce not to stub this methods server side implementation but instead call this provided method implementation directly in the class provided. In order to use this functionality the "Provided" checkbox must be selected and the Class name attribute must be filled out in the "Provider" tab. The class name attribute will point to the fully qualified class name of the class which implements this WSDL described operation. The jar file that contains the provided Class which implements this operation must also me copied into the lib directory of the service. This will ensure that the operation will be located at the time the operation is called on the service. For more information on this particular topic refer to the Globus Documentation on Operation Providers.
Operations can also be imported from other services. Importing an operation enables the service to implement the exact same operation signature. This enables the service to have an operation which has the exact same WSDL signature of the operation which is being imported. This would enable either client to invoke this operation on either service. Importing can be done in two ways: (1) from an Introduce generated service, or (2) from a WSDL file. For case 1, importing from an Introduce service, the developer would browse and select the Introduce generated service which contains the operation to be imported. Once the Introduce service is selected a list of services which contain this method will be available to select from. Select the service from which you want to import the operation. The methods signature will be imported and the developer will be prompted to make sure to copy over the WSDL and XSD files needed to import the method into the schema<service name> directory of the service. For case 2, if a method is described in another WSDL but the developer wants to implement this exact method from this WSDL. The developer must have the WSDL and corresponding XSD's in the schema/<service name> directory of the service. Then the developer will be able to browse those WSDL files and select the port type they wish to import the operation from. The importing of a method across services will assure not only that each service has completely protocol compatible methods but also that each service's method can be invoked by the same base client. This enables the notion of basic inheritance in grid services and is discussed further in the Introduce technical guide.
Service state information and metadata in the form of resource properties can be added, removed and configured via the "Metadata" tab of the GDE Service Modification interface. The metadata elements which are added to the service can be populated by a file statically or managed dynamically within the service. Also, these metadata entities can be registered with an index service so that users can use the metadata to locate the service. Once the "Metadata" tab is clicked the left panel will contain a list of available data types that can be used for metadata and the right will contain the list of currently chosen data types. By double-clicking on a data type in the left panel it will be added to the main service's metadata list. Any of the service's metadata can be initially populated from a file if desired. If this is chosen then once the service is started up in the container the file will be used to populate the particular metadata object in the service. Each metadata in the service can also be selected to be published to an index service. This will enable some or all of the metadata to be used in to locate the service via an index service.
A power user feature which can be enabled at modification time is the addition or removal of service contexts. A service context a sub-service or complimentary service which is used with the main service or some other service context. The service context is comprised of the service, resource, operations, and resource properties. So, in a sense, service context is exactly the same thing as the main service, except that it is not a singleton based resource and instances can be more dynamically created and or destroyed. Contexts can be added via the "Service Contexts" tab of the GDE Service Modification interface. Service contexts define additional of operations needed to support the desired service functionality. This is enabled by using WSRF capabilities of the Globus Toolkit. As an example, if an operation on the main service enables the user to query a database, that operation might create a resource in another context and return the handle to that context to the user as opposed to the full query result set. This secondary context can then enable the user to iterate through the query results. This is accomplished by operations or resource properties to this secondary service context which will be responsible for iteratively giving results to the user. It should be noted that multiple instances of these contexts can be created and executed concurrently; one for each query that comes in, for example. This style of grid service is supported by the WSRF specifications. Though the details of the WSRF-implementation of these concepts are abstracted away from developers its worth noting how they are realized, and this is described in detail in other sections. Introduce makes it easier for service developers to create such complex services, via the GDE, without having to fully understand the underlying service implementations. Anything that can be done to the main service, except service properties which are globally accessible can be added to a service context. For example, resource properties can be added and used to maintain state or for publishing metadata to an index service. Also, operations can be added to the service context and can also be implemented in the service itself or in the service's resource if they are acting on the state of the instance of the resource.
A Statefull Grid service is comprised of several key components which make it able to maintain state and enable a client to invoke the service several time under the same context. A statefull grid service is composed of the service, a resource home, and the resource type. This service organizaton can be used in many different scenarios. For, example, when an operation on the service is invoked the service can be implemented to handle that operation, or if the operation is addressing a particular resource instance in the service, the service can lookup the resource and call whatever might be necessary to call on the particular addressed resource. For assistance on how to develop services utilizing this technique please refer to the [Introduce Developers Guide]
Service properties are key value pairs which can be set at deployment time and are available to the server side implementation of the service at run time. This enables passing in configuration variables to the server side of the service at deployment. These key value pair properties can be declared in "Service Properties" tab of the GDE Service Modification interface. Once the "Service Properties" tab is clicked the main panel will show a table of the service properties. The bottom panel has an entry for which can be used to create a new service property. The properties will be confirmed and/or can be changed from there default values at service deployment time. The variables can then be accessed inside the user's implementation of the operations through the services ServiceConfiguration class. For example, if you add a property called foo under the service properties tab, and then save the service. Then go look at the source code for the <service package>.service.ServiceConfiguration.java class you will seee that it now has available methods for string getFoo() and void setFoo(string foo). These operations are now available to your service and can be used to pass properties into your service at deployment time as well as other users for configuring and sharing properties in your service. The <service package>.service.ServiceConfiguration.java contains a static method for obtaining an instance of itself called getConfiguration(). Any call to that from anywhere in the service will return the handle to the ServiceConfiguration instance and hence access to the service properties.
Services generated with Introduce 1.2 and higher support undeployment. The service, when deployed, creates a log file containing information about what was copied into the container. Utilizing this information the undeployment task of the service is able to determine what was copied to the container that is not used by any other service and it will remove it. This feature enables keeping the container from getting corrupted with left over jars and schema from deployments.
Introduce has the ability to help migrate a service to a newer version of Introduce. If the developer attempts to open a service generated with an older version of Introduce (1.0 and newer), Introduce will prompt the user to proceed with the migration process. The migration process is fully automated and when it is complete will report out to the developer what might be left for them to adjust based on there potentially custom changes or if there were any errors during the process.
When using Introduce to open a service for modification it will check the service to see which version of Introduce and its Extensions were used to create/modify the service. If those versions are different from those installed in the Introduce being used, it will prompt the user and notify them that the service needs upgrading. When prompted the user will have to decide to either:
- Upgrade: upgrade the service to the version that Introduce can properly work with it
- Open: attempt to have Introduce work with it without upgrading which is potentially dangerous and recommended.
- Close: do nothing to the service and do not proceed with the modification process
If the user chooses to upgrade the service the upgrade process will begin. Once finished, a report indicating the major changes and potential issues will be displayed to the user for their review. Once they are confident they have addressed any issues in the upgrade report, they can select the "Proceed" option and the Modification Viewer will be opened displaying the newly upgraded service. If the report warns them about potential modification they might need to make in order to finish the Upgrade process then the user can select the "Edit" button. This will enable them to halt the upgrade process while they make changes. In doing so, they can open the service up for modification at a later time and Introduce should be able to work with the service. If they are not confident in the changes and don't want to upgrade, they can select the "Roll Back" option to restore the service to its previous state.