On Thu, Apr 23, 2009 at 11:30, Alan Williams <[email protected]> wrote:


> The filter mechanism currently looks at all the properties of the
> service, not just its name.  That does mean that it can match services
> where the reason for the match is not immediately obvious.  The
> alternative would be not to match all the "correct" services.

What this means, is that if the service provider gives us more
information, such as descriptions, etc, it will also search in these.

However we have not yet added a general way to show these additional
properties, so it might be confusing to get a hit for something,
without showing the property that matched the search string.

One way to do this is to be inspired by Google and have multiple lines
in the results. Obviously this would make the list be longer, so
another alternative is to show it in a separate panel, but then you
could only see it per selected service. We could do something in the
middle of these, were we "expand details" only on the service that has
been selected, or if a search is in effect.

I'm not sure how easy it is to do this in a JTree though, so we might
have to change that as well, meaning that we would have to do such an
improvement for 2.2 or as a later update to 2.1.


Other things Alan did not mention:

You can search for multiple words, Google-style, so for instance
typing "gene enzyme" in the search box would match services that have
both 'gene' and 'enzyme' in their properties'.

You can search by specific properties, but there's no exposure as to
what those properties are (basically they are what you previously saw
in the drop-down boxes in 2.0), for instance name:gene would match
gene only in the getName() property - but not in say getDescription()
or getURI().



The APIs for appearing in the service palette are much simplified
compared to the old query/partition thing that we didn't quite get to
work.

Here's an example for Soaplab:


http://code.google.com/p/taverna/source/browse/taverna#taverna/ui/net.sf.taverna.t2.ui-activities/trunk/soaplab-activity-ui/src/main/java/net/sf/taverna/t2/activities/soaplab/servicedescriptions%3Fstate%3Dclosed

SoaplabServiceProvider.java is the provider of service descriptions,
which in this case are instances of the bean
SoaplabServiceDescription.java. Think of a service description as a
line in the the "Available services" tree, so for most cases it's more
on the level of a method than an endpoint.

Typically the provider would be configured with an endpoint address,
in this case that configuration is in the bean
SoaplabServiceProviderConfig.java - so we'll start there:


http://code.google.com/p/taverna/source/browse/taverna/ui/net.sf.taverna.t2.ui-activities/trunk/soaplab-activity-ui/src/main/java/net/sf/taverna/t2/activities/soaplab/servicedescriptions/SoaplabServiceProviderConfig.java
shows that the configuration of a provider requires only one property,
"url". This is normal JavaBean style, so just setBean() and setUrl().
You will notice a little annotation:

  @PropertyAnnotation(displayName = "Soaplab location", preferred = true)
        public String getUrl() {
                return url;
        }

If the configuration bean subclasses
net.sf.taverna.t2.lang.beans.PropertyAnnotated - then annotations made
using  @PropertyAnnotation are provided as normal BeanInfo properties.
Alternatively you can make a SoaplabServiceProviderConfigBeanInfo
class and provide these manually - but we found that was quite
cumbersome, so we made an annotation to do it.

You don't need to put in these annotations, any properties will be
used by default. The advantage is two things. For the configuration of
the service provider, these annotations allow you to give more user
friendly "display names" - these are used by the UI builder when
creating the "Add Soaplab service" dialogue that pops up when clicking
"Add new service".

That means that you no longer has to make a little Swing UI just to be
added to the tree.  We will however make an interface that allows you
to specify that yourself if you really want to, for instance BioMoby
will need this for a more advanced "Add" dialogue.

But in the simple case, where you just need a URI and a few other
attributes, the bean itself and some annotations should be enough.


Now to the service descriptions themselves.

http://code.google.com/p/taverna/source/browse/taverna/ui/net.sf.taverna.t2.ui-activities/trunk/soaplab-activity-ui/src/main/java/net/sf/taverna/t2/activities/soaplab/servicedescriptions/SoaplabServiceDescription.java

is a typical service description, note that you will have to subclass
ServiceDescription<ConfigType> where ConfigType is the type of the
activity configuration. (The one given to theActivity.configure() ).

Three bean properties are enforced by this abstract class, getName(),
getIcon() and getPath().  The name and icon are what you will see in
the service palette. So in theory each method could have a different
icon - but in most cases the service providers will just return a
static Icon representing their service.

getPath() returns a List of String's that says where you want to
appear in the service palette tree. So now each service description
decides for itself. As a convention, the first folder should be the
common for every service from the provider, so in this case it will be
a folder called "Soaplab @ http://someurl";. In the simplest case, like
with WSDLs, this is all you need, so a singleton list with that string
can be returned. In the Soaplab case, we also want to expose folders
for the categories, so the category (from getCategory() ) is also
returned as the second level in the tree.

As you see with this, you would no longer have those drop down boxes
to select what the tree should be, but the service descriptions
themselves decide this.  This is no stopper to bring back the
2.0-style of letting the user select how to organize the tree, as all
the properties are there, but by default we'll only support the
getPath() directly.

(Note that the interface states a list of Comparable's - but normally
Strings should be used. The idea was that whatever is returned is
compared using compareTo() when arranging the tree, and the
.toString() is used as the label in the tree. My idea was that you
could return say URIs or more clever objects that knew how to arrange
themselves - and possibly to add right-clicks later, but I found that
the Comparable interface allows the compareTo() method to fail on
incompatible objects. So for instance if one service description let's
getPath() return Arrays.asList(URI.parse("blasedlasd")); - and another
Arrays.asList("Hello")  - it's not going to work when sorting them, as
URIs refuse to be compared to strings.   If you are consistent on
deeper-level branches it should still work, though.. but perhaps we
should change it to only be a List of String's)


OK, so just to finish the service description, we have a few
additional methods/properites here:

isTemplateService() should always return false - except for template
services like Beanshell, RShell etc. In short a template service is
one there's only one of, and which needs further configuration
(typically poping up a dialogue box) before it really can be used.
However, there's a short cut for returning these based on
AbstractTemplateProvider


getCategory() - which we have already included in the path,
getOperation() and getUrl(). Each of these will also be searched overf
from the Filter box, and you could search over say only "operation",
by saying operation:something

You will see that one important job of the service description is to
help creating an Activity instance. It does this by providing two
items, getActivityClass() returns the *class* of the activity that is
to be instantiated (using the public empty constructor), and
getActivityConfiguration()  returns the configuration bean that is to
be applied to the activity, by activity.configure(bean).

This will be performed only when the service is added to the workflow,
ie. when you drop the service description onto the diagram or the
model explorer.


OK, so there's lots of these ServiceDescription beans, one per
"service", ie. a configuration of an activity that can be added to the
workflow. Where do they come from?

This is where the service provider comes into the picture. We'll
finish with the soaplab provider, it looks like this:

http://code.google.com/p/taverna/source/browse/taverna/ui/net.sf.taverna.t2.ui-activities/trunk/soaplab-activity-ui/src/main/java/net/sf/taverna/t2/activities/soaplab/servicedescriptions/SoaplabServiceProvider.java

It is extending AbstractConfigurableServiceProvider because it is a so
called configurable service provider. In this case it can be
configured with a SoaplabServiceProviderConfig - which we saw had the
getUri() property - basically the location of the Soaplab
installation.

To be discovered by Taverna, SoaplabServiceProvider is implementing
the SPI net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider,
and is therefore listed in:

http://code.google.com/p/taverna/source/browse/taverna/ui/net.sf.taverna.t2.ui-activities/trunk/soaplab-activity-ui/src/main/resources/META-INF/services/net.sf.taverna.t2.servicedescriptions.ServiceDescriptionProvider


It has as well getName() and getIcon() - these are used for including
the provider in the list you see from the "Add services" button.

What happens when you click there, is that a copy will be made of the
bean returned through getConfiguration() (in the superclass). This is
the *template* configuration bean - and is the one sent in through the
constructor:

super(new SoaplabServiceProviderConfig("http://somehost/soaplab/services/";));

This bean is then used with the automatic UI builder, and it will put
up a field for the URI property. Any other properties specified would
also be included, but in this case there's just the URI. The defaults
will be set from that template bean, so it will say
"http://somehost/soaplab/services/"; as the initial value.

What happens next is that the user edits this string, and clicks
"Add".  This will then make a *copy* of the
SoaplabServiceProviderConfig (using the .clone() method) - and call
.configure() on it using the new configuration.

This will then be a configured ServiceDescriptionProvider that will be
added to the ServiceDescriptionRegistry. The registry will serialize
the SoaplabServiceProviderConfig to an XML file in the user's home
directory, so that on a restart of Taverna the added service will
still be there. (but the endpoint will be queried freshly.)

(we could extend this serialisation to actually serialise the whole
ServiceDescription beans - this should make Taverna have a list of
services immediately at start-up, even without network access. Taverna
could then do a refresh in the background to pick up any services that
have changed)


On adding a new provider to the regisstry, it will call the
findServiceDescriptionsAsync() method to get new service descriptions
from the providers. These are then put into the registry. One of the
listeners to this registry is the "Available services" tree, which
will rebuild the tree, using the getPath() etc. from the service
descriptions, and put the soaplab services into the tree.

You will notice that the findServiceDescriptionsAsync is an
asynchronous method with callbacks, it does not simply return the
List<ServiceDescription> - as there's no-one waiting for him anymore.
The reason for this is that it typically will take some time to do the
look-up of services, contacting the WSDL or similar, and we don't want
to freeze the UI what that is happening.

The provider can call back status reports, like
callBack.status("Connecting to Soaplab:" + soaplab); or
callBack.warning("oooh") - these are currently shown on a status line
in the "Available services" panel.

You will see the soaplab provider doing it's soaplab-specific stuff to
look up services, and it builds a set of SoaplabServiceDescription
beans. It is setting details like category, operation and url.

The provider then calls callBack.partialResults(descriptions); with a
collection of service descriptions received so far. In the simple
cases, like this, it will simply return all results. This will be
pushed into the registry, and will almost immediately appear in the
tree. For providers that look up several services (like a BioCatalogue
or caGrid/caDSR provider), or take a lot of time, they can provide
intermediate results, calling partialResults several times. It should
then call callback.finished() once it's done. This allows the provider
to fill the tree part by part, but for simple services like WSDL we do
it all in once, as it would otherwise cause too many UI updates.

If anything goes wrong, it can call callBack.fail() - which would
present the error message to the user in a dialogue box and remove the
service provider from the registry. (including any results given so
far).  If a RuntimeException happens (like a NullPointerException), a
handler on the thread will also catch this and report it using
callback.fail(), however this wouldn't provide  the user with a usable
message.


A configurable ServiceDescriptionProvider can also provide a list of
ready made provider configurations at getDefaultConfigurations() - the
service provider registry will automatically make a new copy of
ServiceDescriptionProvider and configure them for each of these
default configurations. For example the Soaplab provider includes a
bean for the typical soaplab installation at
http://www.ebi.ac.uk/soaplab/services/ so that these services will be
included in the service palette without a need to click "Add service".
 However it's debatable if it's clever to provide these hard-coded in
the Java, so for our "Bundled WSDLs" we'll probably instead go for a
configuration file in the downloaded Taverna distribution - this could
just be the same kind of file saved in the users home directory when
adding services manually.


As you might have guessed, the ServiceDescriptionProvider is not tied
with a ServiceDescription - but for a ServiceDescription to appear at
least one provider would need to list it. It is possible to build
general ServiceDescriptionProvider's that lists different types of
service descriptions, some that come to mind:

  * A BioCatalogue provider
  * A caDSR provider for caGrid services
  * A workflow services provider that lists services used in the
current (or all) open workflow
  * My favorites provider




-- 
Stian Soiland-Reyes, myGrid team
School of Computer Science
The University of Manchester

------------------------------------------------------------------------------
Stay on top of everything new and different, both inside and 
around Java (TM) technology - register by April 22, and save
$200 on the JavaOne (SM) conference, June 2-5, 2009, San Francisco.
300 plus technical and hands-on sessions. Register today. 
Use priority code J9JMT32. http://p.sf.net/sfu/p
_______________________________________________
taverna-hackers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/taverna-hackers
Developers Guide: http://www.mygrid.org.uk/usermanual1.7/dev_guide.html
FAQ: http://www.mygrid.org.uk/wiki/Mygrid/TavernaFaq

Reply via email to