MobyServlet Secondary Articles

Sections

What are secondary articles?

Secondary articles are defined by the MOBY-S specification as inputs to a service that are not part of the service signature, but affect the behaviour of the program. For example, a BLAST program may have a primary input article of "DNASequence", and we can search for services that take DNASequence as input. The service may handle BLASTing against any of several databases though: the target database could be configured through a secondary article (rather than creating 10 services for the 10 databases). A Secondary article may be of the folowing types:

How do I specify them in the @mobyService annotation?

The general syntax for specifying a secondary article is:
name:type:defaultValue:[min,max]
Where ":[min,max]" is optional, and if specified, either min or max can be excluded to produce an unlimited range at one end. In the case of the String secondary article type, [min,max] is instead interpreted as an enumeration of choices (see the example below).
Suppose you are writing a BLAST service, and you'd like to allow the user to specify: The annotation for the BLAST service might look like this:
@mobyService(name="CoolBlast",
	     type="PairwiseComparison", 
	     provider="moby.ucalgary.ca", 
	     author="gordonp@ucalgary.ca",
	     in={"AminoAcidSequence"},
	     out={"BlastText"},
             description={"BLAST against any of a number of protein databases"},
             secondaryParams={
                             "db:String:nr:[swissprot,nr,pdb,uniprot]",
                             "threshold:Float:1.0e-8:[0,100]", 
                             "hits:Integer:50:[1,200]",
                             "filter:Boolean:true",
                             "since:DateTime:2006-01-01:[1970-01-01,]",
                             }
            )

public class MyBlastService extends MobyServlet{
  // ...class code here...
}

How do I use them in my service?

In the processRequest method you override, the MobyDataJob request object contains both the primary and secondary parameters. MobyServlet guarantees that the values will be available, even if the client forgot to specify, or illegally specified a value (the default, or closest valid value is provided instead). Take the BLAST service as the example -- to retrieve a secondary of each type from the request:
public void processRequest(MobyDataJob request, MobyDataJob result) throws Exception{

    MobySecondaryData secondary = (MobySecondaryData) request.get("db");
    String targetDB = secondary.asString();

    secondary = (MobySecondaryData) request.get("filter");
    boolean filter = secondary.asBoolean();

    secondary = (MobySecondaryData) request.get("threshold");
    BigDecimal eValueCutoff = secondary.asFloat();

    secondary = (MobySecondaryData) request.get("hits");
    BigInteger numHitsToReport = secondary.asInteger();

    secondary = (MobySecondaryData) request.get("since");
    GregorianCalendar recordsUpdatedSince = secondary.asDateTime();
    // ... rest of the processing...
}
Note the BigDecimal and BigInteger. These are returned because there is no limit on the size of the numbers in the MOBY-S spec. If you are sure that the number you'll receive is not too big, you can always do something like numHitsToReport.intValue().

How can I configure a default or range at runtime?

It may be useful to set, for example, the list of databases available at service startup (based on a directory listing), not at compile time. If this is the case, and you are very comfortable with MobyServlet, you can directly hack the thisService protected variable in your subclass. That variable is used to publish the signature RDF for the service. Note that changes will not be immediate in MOBY Central (since it only checks the signature once a day), but the changes are immediate for new requests.
Paul Gordon
Last modified: Fri Dec 8 14:06:51 MST 2006