Skip to end of metadata
Go to start of metadata

This is part of the Tutorial - Service discovery plugin

Introduction

We'll assume that you've followed the Tutorial - Service invocation plugin and by using Eclipse have created a Taverna activity project from a Maven artifact.

In this tutorial we'll cover the user interface side of the service plugin. Codewise this is separated into a project called myfancytool-activity-ui (or equivalent depending on your archetype settings).

The reason for this separation between the invocation and user interface is to be able to facilitate execution of a workflow on say Taverna Server, but without requiring the server to have the various libraries for Taverna workbench or the user interface for configuring your activity . A workflow definition containing your new service type will include a link to the Maven artifact myfancytool-activity, but not to myfancytool-activity-ui.

If a service type is to be used in a workflow, it will however have be selected and added by a user of the Taverna workbench. This tutorial will show you how you can make your service implementation discoverable from within Taverna, how the service will appear in Taverna, and how to further configure it from within the workbench.

Service descriptions

Before we start, make sure you have the Developer Taverna Workbench up and running. See Testing the service in Taverna for details.

In the Service Panel you will find a folder for Examples, under which you will find Example 1, Example 2 etc. Each of these is represented by a service description bean. In Eclipse under the myfancytool-activity-ui project, open the class uk.ac.manchester.cs.img.myfancytool.taverna.ui.serviceprovider.ExampleServiceDesc or equivalent.

You should see a JavaBean that (abbreviated) looks like:

From service description to configured activity

The two first methods are the most important, the activityClass and activityConfiguration properties. When a particular bean has been selected and either drag-and-dropped into the workflow, or added through right click, Taverna Workbench will call getActivityClass() on the bean, and make a new instance of the returned class. It will then call getActivityConfiguration() and use the returned configuration bean for activity.configure(bean).

This means that the implementations of your activity are not instantiated until they are added to a workflow, delaying any initialization steps. The service description bean is meant to be lightweight and even serializable (for future caching).

The getActivityConfigurationBean() method creates and configures a new ExampleActivityConfigurationBean, similar to how we did in the activity unit test {{ExampleActivityTest}}. In this case we just use the fields exampleUri and {{exampleString} directly from the description bean, but these could also have been hardcoded or looked up dynamically.

Let's give this a try, edit the getActivityConfiguration() method so that it will instead set:

If you are running the workbench in Debug mode, just click File->Save in Eclipse, and any example activity you now drag into your workflow will be configured with the "specialCase". (Otherwise, simply restart the developer workbench.) To verify this in Taverna, click for the Details of the service. You should also notice the additional input and output port appearing.

Now we have 5 example activities that all produce the same activity (although with a slightly different name). You would be guessing correctly if you think that getName() provides the name shown in the service palette, like Example 2. Let us change it to:

If you are running in debug mode, again it should be enough to just click Save in eclipse. To trick Java to update the user interface, simply collapse and expand the Examples folder, or resize the window slightly.

In Taverna 2.2, you will only see one service once you change the name. This is due to a bug that will be fixed in Taverna 2.3

Identifying service descriptions

Why are these service descriptions shown several times, even if they return the same configuration and have the same name? Well, it comes down to the method getIdentifyingData():

This tells the service palette that the uniquely identifying bits of this bean are the fields exampleString and exampleURI. This allows the bean to have additional properties that are not part of the identity, such as descriptions and icons. You can think of the values returned here as the primary keys. Service descriptions are compared across the whole panel according to these keys, allowing for several sources for service descriptions, and service descriptions for multiple types of services.

Check your keys

If your service description is not showing up, check that your getIdentifyingData() is sensible. The methods equals() and hashCode() will use the identifying data to check equality, so this will also determine equality and placement in HashSets.

Let us change back the service description to make sense again, undo the changes so that again the getActivityConfiguration() does bean.setExampleString(exampleString) and that getName() returns exampleString.

Where in the tree?

The service palette uses getPath() to determine where to place the service description in the tree. There is no restriction saying that all descriptions from a plugin needs to be in the same folder (or similarly named folders), or that descriptions from different plugins can't be in the same folder - although there is a strong convention for doing so. Let's try anyway:

Change getPath() so that instead it returns a location within Local services:

As the service tree structure is only updated at Taverna startup and when "Import new services" is used (but no such service plugins are enabled in this developer workbench), Eclipse's debug mode can't help us this time, and we have to restart Taverna.

You may specify folders at any depth using getPath(), but we recommend you don't go any deeper than two levels like above. The Taverna convention is to simply have a top level folder for each service endpoint, like WSDL @ http://example.com/wsdl.

What is in a path anyway?

Although the example code for getPath() returns a List<String>, it is possible to return any object in this list that implements java.lang.Comparable (so that the object can be sorted). Taverna will create intermediate folders using the toString() method on those objects, allowing for path elements that themselves also are JavaBeans. Unfortunately java.lang.String (as used by most paths of the existing service descriptions) can't be compared to anything but Strings, it means you can only use this trick within your own folder structure, as a FancyFolder would not be comparable with a String "Local Services" they can't be at the same level.

If you run the standard Taverna Workbench 2.1 you can see how the BioMoby plugin uses this to its advantage under its Moby Objects hierarchy, where a service description has another service description as a parent - enabling both to be added to the workflow.

Searching for descriptions

When a user uses the Filter text field to find services within the Service panel, Taverna will search all service descriptions, inspecting toString() of all properties in the bean. So if we do a search for localhost we should find all the examples, as they have the property exampleUri: http://localhost:8192/service.

It is also possible to search for a particular property, so while a search for just 4 would give you quite a few hits, a search for exampleString:4 would only show those service descriptions having getExampleString() returning something which toString() contains 4.

Searching for URIs

There is currently a bug in Taverna, affecting searching for property values like URIs. As URIs contain the : character, Taverna interprets a search for say http://moby.ucalgary.ca/MOBY/Central as a search for //moby.ucalgary... in the http property. A direct search within the property would work though, like namespace:http://moby.ucalgary.ca/MOBY/Central. See T2-1102 for details.

You might want to include properties in your service description beans that are not to be searchable. For instance, the getIcon() property is not searchable, because it would typically be toString()-ed to be something like java.awt.ImageIcon jar:blah.jar!beanshell.png. To tell Taverna about such cases, you can add annotations on top of your header.

In Eclipse, go to the getIcon() method. We won't cover how to return your own icons here, but right-click and select Quick-Type hierarchy. Select ServiceDescription.

Eclipse's Maven plugin should have downloaded the source code for ServiceDescription for you. If this is not the case, right click on the activity-palette-api-1.0.jar under Maven Dependencies in the Package Explorer and select Maven -> Download sources. You would then find the getIcon() abstract method having an annotation:

This property annotation says that the icon field is 'expert only', meaning that it won't be searched implicitly, and only shown on screen under a typical Advanced tab. A direct property search for say icon:png should work, though.

Taverna does not yet provide a user interface for browsing all properties set on service descriptions, but might in the future use these annotations to automate the generation of such a view.

This should cover what you need to know about service description beans. Let's move on to who is providing the service descriptions.


This is part of the Tutorial - Service discovery plugin