Access Keys:
Skip to content (Access Key - 0)

MMS


MMS 1.3 Developers Guide


[  Documentation  |   Developers Guide   ]


MMS Overview


The MMS Grid Service is a simple, stateless service, created with Introduce, which provides the capability to 1) annotate standard caGrid service metadata with semantic information from external metadata registries, and 2) generate standard caGrid data service metadata using information from those registries.

Service Operations Overview


The service exposes two main categories of operations. The first set of operations, described below in the Generating Domain Model Metadata section enables clients to generate caGrid standard Data Service metadata. The second category, described below in the Annotating Service Metadata section, is the the operation, annotateServiceMetadata, which provides clients the ability to augment a ServiceMetadata (standard caGrid service metadata) skeleton instance with the information extracted from metadata repository, such as the caDSR.

Generating Domain Model Metadata

There are four operations that take variations of information specifying what data is to be exposed by the Data Service for which the metadata is being created. Each operation throws an InvalidUMLProjectIndentifier if the Project  specified is not valid. The first operation, generateDomainModelForProject, takes only the project description and generates a model that describes the entire domain model being exposed for the project. The second, generateDomainModelForPackage, additionally takes an array of Strings that represent UML package names in the Project to expose. The method generates a model that describes exposing all UML Classes in UML Packages with a name specified in the array. Any associations to UML Classes outside of the specified packages are not exposed (i.e. they are excluded from the generated model). The third method, generateDomainModelForClasses, also takes an array of Strings that represent the fully qualified UML Class names to be exposed in the model. Any association between classes not specified is omitted. The final method, generateDomainModelForClassesWithExcludes, also takes an additional array of Strings that represent the fully qualified UML Class names to be exposed in the model, but also takes an array of UMLAssociationExcludes to be used to exclude specific associations from the model (in addition to the already excluded associations that reference classes not specified in the array of class names). The UMLAssociationExclude Class allows the client to specify a sourceRoleName, sourceClassName, targetRoleName, and targetClassName. Any UML Association that would otherwise be included in the computed subset of the DomainModel is omitted if it meets the criteria described by any of the UMLAssociationExcludes. The value of any attribute of the UMLAssociationExclude can be the wildcard "", which indicates it should match anything. As such, specifying an exclude with "" as the value for all attributes effectively omits all associations from the DomainModel. By using no wildcards, a single association can be omitted, and by using a combination of some values and some wildcards, groups of associations can be omitted. For example, specifying an exclude instance with a sourceClassName value of "gov.nih.nci.cabio.domain.Gene" and wildcards for all other attributes would effectively omit any associations from the DomainModel where gov.nih.nci.cabio.domain.Gene was the source of the association. Using these methods a client can generate Data Service metadata exposing any subset of Classes and Associations can be created.

Annotating Service Metadata

The caGrid common service metadata specifies information about a grid service and its operations. For more information on the model, consult the caGrid 1.3 metadata design document. The annotateServiceMetadata operation takes this model and populates the UML and semantically oriented components by querying the appropriate external metadata repository. Specifically, it populates the semantically annotated UML Class information (similar to the type used in Data Service Domain Model metadata) for each input and output type of every operation the service provides. It does this by examining the XML Qualified Name (QName), which is a namespace and name, of each type used in the signature of the operation and locating its UML equivalent in external metadata repository. In addition to the ServiceMetadata instance which should be annotated, the operation also takes an optional array of NamespaceToProjectMappping. This effectively acts as a hint to context to the MMS, used when determining the mapping from a QName to its UML counterpart. In other words, if a given Namespace is reused across multiple Projects in the external repository, this mapping can provide the context to the MMS as to which to use. If a given QName's Namespace has no such entry in the mapping, the MMS is expected to be able to uniquely resolve the project within its default metadata source (the mechanism by which it does this is implementation-specific, and should not concern the client). Note this allows a given model to be potentially annotated with metadata from multiple external repositories, as different XML Namespaces can be mapped to different metadata repositories.

When using an MMS with a single external metadata repository, in which there is a one to one mapping of QName to UML Class, there is no reason to provide a NamespaceToProjectMappping. However, the caGrid Metadata Introduce Extension is an example where this capability is leveraged. The caDSR Data Type Discovery component of Introduce allows one to add models (XML Schemas) to their project, by browsing the caDSR and selecting a Project/Package. When such a model is added, it notes its caDSR information (e.g. Project name and version). Later when the caGrid Metadata Introduce Extension uses the MMS to annotate the service's metadata, it reads this information and creates a series of NamespaceToProjectMappping which map each XML Schema's Namespace to the appropriate caDSR Project. The MMS then uses this information to ensure the correct metadata is associated with the operations which make use of types from those XML Schemas. As such, the NamespaceToProjectMappping array provides clients the ability to control the MMS behavior when there are multiple external metadata repositories supported and/or a given XML Schema Namespace ambiguously maps to multiple UML Models (i.e. multiple projects are reusing the same XML Schema).

MMS Object Model


The MMS service relies heavily on the standard caGrid Metadata Models for its operations, but has additional classes for specifying parameters to its operations, and advertising its capabilities via service metadata (ModelSourceMetadata). The actual model itself is generated automatically by Axis, from the XML Schemas used by the MMS. As such, the object model is serialized automatically by Axis when exchanged between client and service.

Model Source Metadata

As a general framework for creating and annotating caGrid service metadata, the MMS can be configured to communicate with nearly any external metadata repository. In order for clients to ascertain the metadata repositories available for a given MMS service, the MMS provides Model Source Metadata which can be retrieved by a client and interrogated for such information.

The Model Source Metadata contains a defaultSourceIdentifier and a collection of supported Model Sources, which describe the requirements and capabilities of the external metadata repositories. Each repository, a Model Source, is described by a SourceDescriptor in the Model Source Metadata. The Model Source is identified by its identifier, which is its unique name used to identify it in the MMS's operations. The Model Source is described by its description attribute, which is used solely for human readable presentation of the source. Each Model Source also has an optional collection of PropertyDescriptors, each of which describe a Property (a name value pair) available for use in UMLProjectIdentifers within the described external metadata repository. That is, the name of descriptor corresponds to the name that would be used in a Property. The PropertyDescriptor has two additional attributes: a description attribute which is used to describe what the Property represents, and a required boolean attribute which indicates whether or not UMLProjectIdentifer's for the given source are required to provide values for this Property.

Retrieving the Metadata

The MMS's Model Source Metadata can be retrieve either directly via the "getter" operation (getModelSourceMetadata), as illustrated below in the code examples, or via its WSRF Resource Property ({gme://caGrid.caBIG/1.0/org.cagrid.mms.domain}ModelSourceMetadata). The caGrid ResourcePropertyHelper is a convenience class which can be used to retrieve this document in XML form. Using the MMS client API directly is the preferred approach, as it leverages the MMS Object Model, but the Resource Property is provided such that the metadata can be registered to the Index Service, and suitable MMSs can be discovered based on their capabilities.

Relation to Service Operations

How Model Sources are Determined

The MMS operations described above all make direct use of UMLProjectIdentifiers. Every UMLProjectIdentifier must specify an identifier (and optional version), and may provide a sourceIdentifier. If a sourceIdentifier value is supplied, it must match exactly to the identifier of a SourceDescriptor in the service's supported Model Sources, or an InvalidUMLIdentifier exception will be thrown. The MMS uses this to identify the intended external repository. If no value is supplied, the Model Source with the identifier specified in the ModelSourceMetadata.defaultSourceIdentifier will be used to locate the appropriate external repository.

How UML Projects are Determined

In addition to how Model Sources are identified, as described above, UMLProjectIdentifiers are used to identify a UML Project within its identified Model Source. Minimally UMLProjectIdentifier must supply an identifier. As a best practice, ideally external metadata repositories would use this as a unique identifier for the UML Projects they maintain. However, if this is not the case, the UMLProjectIdentifier also allows an optional version which can be supplied to specify a particular version of a project. For some Model Sources, even this may not be sufficient to identify the project within the repository, in which case the UMLProjectIdentifier allows additional properties to be specified (via the additionalSourceProperty). Each Property in this list is effectively a name-value pair where the allowable property names are dependent upon the capabilities and requirements of the Model Source (some may not allow any additional properties). The information about what properties are allowed, what they represent, and whether or not they are required to be specified is all detailed in the Model Source Metadata via the PropertyDescriptors described above. For example, in the default caDSR Model Source, one of the additional properties that is supported is the publicID of the project of interest. The MMS will always use as much information as provided in a UMLProjectIdentifier to locate the desired project of interest. That is, if additional properties are specified that contradict the project's identifier and/or version, an InvalidUMLIdentifier exception will be thrown.

Migrating from the Deprecated caGrid caDSR Grid Service


caGrid versions 1.2 and earlier used a caDSR Grid Service which provided similar capability to the MMS, as well as the ability to query the service for information about the metadata registered in the caDSR. The latter functionality has been replaced by a caDSR-team maintained caDSR grid service. The former, is now provided via the more general MMS. Even though the MMS is more general and can work with a variety of external metadata registries (not just the caDSR), its use for clients intending to still leverage the caDSR is strikingly similar to the deprecated CaDSRServiceClient.

The default MMS distribution is configured with a single Model Source, which is the caBIG production caDSR. As described in the section on how Model Sources are Determined, this implies clients may omit any reference to model sources identifiers, and the caDSR will be used.

Note however, a discerning client should still explicitly specify the source when possible, to ensure the intended repository is leveraged if an additional registry is added.

The relevant operations of the CaDSRServiceClient have exactly the same names in the MMS, so migrating code to the MMS is fairly easy. The main changes are that whereas the existing methods leveraged the caDSR class model (gov.nih.nci.cadsr.umlproject.domain), namely the Project class, the new operations use the MMS-specific org.cagrid.mms.domain.UMLProjectIdentifier. This mapping is described below. The only other change is that the annotateServiceMetadata operation takes an additional parameter, the NamespaceToProjectMappping which is described above in the Annotating Service Metadata section and allows one to make use of the potentially multiple external registries or better control the Namespace to Project mapping the MMS performs.

caDSR Grid Service MMS Service
gov.nih.nci.cadsr.umlproject.domain.Project class org.cagrid.mms.domain.UMLProjectIdentifier class
shortName attribute identifier attribute
version attribute version attribute
gmeNamespace attribute gmeNamespace additional source property
longName attribute longName additional source property
publicID attribute publicID additional source property

Both the previous caDSR Grid Service and the MMS perform project identification as a "best match" effort, in that the external registry is consulted for a project matching every criteria that the client supplies (as long as one and only one project meet the criteria it is used, else an error is raised). The main difference however, is that the MMS now requires an identifier to be supplied, which is interpreted to be the caDSR Project's shortName. Additional qualifying properties can be used to identify the project, but a shortName (i.e. identifier) will always be required for the caDSR source; this is a slight change in behavior from the caDSR Grid Service.

Shown below is the default Model Source Metadata for the MMS using the caDSR as its sole metadata registry, in which the additional properties described above can be seen.

 <ns1:ModelSourceMetadata defaultSourceIdentifier="caDSR Production" xmlns:ns1="gme://caGrid.caBIG/1.0/org.cagrid.mms.domain">
  <ns1:SupportedModelSources>
   <ns1:Source description="The production instance of the National Cancer Institute's Cancer Data Standards Repository (caDSR)." identifier="caDSR Production">
    <ns1:SupportedProjectProperties>
     <ns1:PropertyDescriptor description="The gmeNamespace attribute of the caDSR Project." name="gmeNamespace" required="false"/>
     <ns1:PropertyDescriptor description="The longName attribute of the caDSR Project." name="longName" required="false"/>
     <ns1:PropertyDescriptor description="The publicID attribute of the caDSR Project." name="publicID" required="false"/>
    </ns1:SupportedProjectProperties>
   </ns1:Source>
  </ns1:SupportedModelSources>
 </ns1:ModelSourceMetadata>

Extending the MMS


This section is intended for developers interested in extending the MMS service side implementation for such reasons as adding an additional or alternate external metadata registry. Before attempting such an effort, interested parties should consult the MMS Design Guide and the configuration section of the MMS Administrator's Guide, which details how the service can be configured via Spring to add your custom implementation.

The primary point of extension of the MMS is the org.cagrid.mms.service.impl.MMS interface. The MMS is configured (via Spring) to load an implementation of this interface at service startup, and delegate all service operations appropriately to the implementation. The operations of this interface map directly to their same-named counterparts in the service's interface. The parameters of the operations are slightly different, as they make use of Java collections instead of the array-only support provided by Axis for the service's interface.

By default, the MMS is configured to load the org.cagrid.mms.service.impl.cadsr.CaDSRMMSImpl for its MMS implementation. This class can be consulted for an exemplar implementation of the MMS interface.

Code Examples


This section provides various examples of using the MMS client API. All examples use the default MMS implementation, which leverages with the caDSR as its external metadata registry; the patterns can easily be applied to other registries.

Prerequisites

To get started developing against the MMS APIs, your project will require the Java libraries found in the MMS project's ext/dependencies/jars directory, and those in its build/lib directory.

Developers using Ivy to integrate with the caGrid build artifacts may use the following line in their dependencies:

<dependency rev="1.3" org="caGrid" name="mms" conf="client"/>

Interrogating MMS Metadata

In this example, we will retrieve the Model Source Metadata of the MMS and print out information about its supported external metadata registries.

import java.rmi.RemoteException;

import org.apache.axis.types.URI.MalformedURIException;
import org.cagrid.mms.client.MetadataModelServiceClient;
import org.cagrid.mms.common.MetadataModelServiceI;
import org.cagrid.mms.domain.ModelSourceMetadata;
import org.cagrid.mms.domain.PropertyDescriptor;
import org.cagrid.mms.domain.SourceDescriptor;


public class DeveloperGuideExamples {

    public static void main(String[] args) {
        try {

            // instantiate the MMS interface by passing the Client constructor a
            // URL
            MetadataModelServiceI mms = new MetadataModelServiceClient(
                "http://mms.training.cagrid.org:8080/wsrf/services/cagrid/MetadataModelService");

            ModelSourceMetadata modelSourceMetadata = mms.getModelSourceMetadata();
            System.out.println("The MMS supports the following Model Sources:");
            for (SourceDescriptor modelSource : modelSourceMetadata.getSupportedModelSources().getSource()) {
                System.out.println("==================================================");
                System.out.println("\t" + modelSource.getIdentifier() + " : " + modelSource.getDescription());
                System.out.println("--------------------------------------------------");

                if (modelSource.getSupportedProjectProperties() != null) {
                    System.out.println("The following additional properties are supported:");
                    for (PropertyDescriptor property : modelSource.getSupportedProjectProperties()
                        .getPropertyDescriptor()) {
                        System.out.println("\t [" + (property.isRequired() ? "required" : "optional") + "] "
                            + property.getName() + " : " + property.getDescription());
                    }
                } else {
                    System.out.println("No additional properties are supported");
                }
                System.out.println("==================================================");

            }

            System.out.println("The default Model Source is: " + modelSourceMetadata.getDefaultSourceIdentifier());

        } catch (MalformedURIException e) {
            // TODO handle the case where the client is constructed with an
            // invalid URL
            e.printStackTrace();
            return;
        } catch (RemoteException e) {
            // TODO handle general errors, such as connection refused
            e.printStackTrace();
            return;
        }
    }
}

Running this example should yield output similar to the below:

The MMS supports the following Model Sources:
==================================================
	caDSR Production : The production instance of the National Cancer Institute's Cancer Data Standards Repository (caDSR).
--------------------------------------------------
The following additional properties are supported:
	 [optional] gmeNamespace : The gmeNamespace attribute of the caDSR Project.
	 [optional] longName : The longName attribute of the caDSR Project.
	 [optional] publicID : The publicID attribute of the caDSR Project.
==================================================
The default Model Source is: caDSR Production

Generating a Domain Model for an Entire Project

In this example we will generate a Domain Model for the entire caCORE 3.2 project. For this example we will leverage the generateDomainModelForProject operation.

import gov.nih.nci.cagrid.metadata.dataservice.DomainModel;

import java.rmi.RemoteException;

import org.apache.axis.types.URI.MalformedURIException;
import org.cagrid.mms.client.MetadataModelServiceClient;
import org.cagrid.mms.common.MetadataModelServiceI;
import org.cagrid.mms.domain.Property;
import org.cagrid.mms.domain.UMLProjectIdentifer;
import org.cagrid.mms.stubs.types.InvalidUMLProjectIndentifier;


public class DeveloperGuideExamples {

    public static void main(String[] args) {
        try {

            // instantiate the MMS interface by passing the Client constructor a URL
            MetadataModelServiceI mms = new MetadataModelServiceClient(
                "http://mms.training.cagrid.org:8080/wsrf/services/cagrid/MetadataModelService");

            // identify the UML Project of interest
            UMLProjectIdentifer project = new UMLProjectIdentifer();
            project.setIdentifier("caCORE 3.2");
            project.setVersion("3.2");
            
            // not specifying a Source Identifier, implies the MMS should use
            // its default; which is the same as explicitly specifying it as below 
            // project.setSourceIdentifier(mms.getModelSourceMetadata().getDefaultSourceIdentifier());
            
            // you may also specify additional source-specific properties to help identify the UML Project
            // Property p = new Property();
            // p.setName("publicID");
            // p.set_value("2528431");
            // project.setAdditionalSourceProperty(new Property[]{p});

            // generate a Domain Model for the whole project
            DomainModel domainModel = mms.generateDomainModelForProject(project);
            
            //TODO use the generated Domain Model

        } catch (MalformedURIException e) {
            // TODO handle the case where the client is constructed with an
            // invalid URL
            e.printStackTrace();
            return;
        } catch (InvalidUMLProjectIndentifier e) {
            // TODO handle the case where the metadata source being used to does
            // not recognize the specified UML Project
            e.printStackTrace();
            return;
        } catch (RemoteException e) {
            // TODO handle general errors, such as connection refused
            e.printStackTrace();
            return;
        }
    }
}

Generating a Domain Model for a Specific Package

Extending on the previous example, we can restrict the generated domain model to only contain a single package of the specified project. For this example, we will leverage the generateDomainModelForPackages operation, and pass an additional parameter to the operation; namely an array of package names we want to use from the given project. In this example we only include the caBIO package (gov.nih.nci.cabio.domain) of the project. The code below can be used in the program provided above, instead of where we previously used the generateDomainModelForProject operation.

    DomainModel domainModel = mms.generateDomainModelForPackages(project,
      new String[]{"gov.nih.nci.cabio.domain"});

Generating a Domain Model for a Specific Collection of Classes

We can restrict the generated domain model to only contain a specific collection of Classes of the specified project. For this example, we will leverage the generateDomainModelForClasses operation, and pass an additional parameter to the operation; namely an array of class names we want to use from the given project. In this example we only include the Gene and Taxon Classes of the caBIO package (gov.nih.nci.cabio.domain). The code below can be used in the program provided above, instead of where we previously used the generateDomainModelForProject operation.

    String classNames[] = new String[]{"gov.nih.nci.cabio.domain.Gene", "gov.nih.nci.cabio.domain.Taxon"};
    DomainModel domainModel = mms.generateDomainModelForClasses(project, classNames);
While the example explicitly specifies the full class names, if you have those classes on your classpath, you can alternatively import them and use something like Gene.class.getName()

Generating a Domain Model for a Specific Collection of Classes, Excluding Associations

Extending on the example above, we can restrict the generated domain model to only contain a specific collection of Classes of the specified project, and rather than including all of their associations, we specify that some not be visible. For this example, we will leverage the generateDomainModelForClassesWithExcludes operation, and pass an additional parameter to the operation; namely an array of UMLAssociationExclude which identify associations to exclude from the model. In this example we only include the Gene, Chromosome, Taxon, and Tissue classes of the caBIO package (gov.nih.nci.cabio.domain), and will specify that two sets of associations should be excluded. The first exclude (exclude1) specifies that the association between Chromosome and Gene where the source role name is "chromosome" and the target role name is "geneCollection" should be excluded; this should be a single association as we have explicitly specified all parameters. The second exclude (exclude2) specifies that all associations where Tissue is the source class should be excluded, as we have used wildcards (*) for every parameter besides the source class name. The code below can be used in the program provided above, instead of where we previously used the generateDomainModelForProject operation.

    String classNames[] = new String[]{
        "gov.nih.nci.cabio.domain.Gene",
        "gov.nih.nci.cabio.domain.Chromosome",
        "gov.nih.nci.cabio.domain.Taxon",
        "gov.nih.nci.cabio.domain.Tissue"};
    UMLAssociationExclude exclude1 = new UMLAssociationExclude(
        "gov.nih.nci.cabio.domain.Chromosome",
        "chromosome",
        "gov.nih.nci.cabio.domain.Gene",
        "geneCollection");
    UMLAssociationExclude exclude2 = new UMLAssociationExclude(
        "gov.nih.nci.cabio.domain.Tissue",
        "*", "*", "*");
    UMLAssociationExclude associationExcludes[] =
        new UMLAssociationExclude[]{exclude1, exclude2};
    DomainModel domainModel = mms.generateDomainModelForClassesWithExcludes(
        project, classNames, associationExcludes);
Last edited by
Clayton Clark (1170 days ago) , ...
Adaptavist Theme Builder Powered by Atlassian Confluence