How To create a service

Overview

These instructions are for core developers only and may be slightly out of date. They will eventually be revised, but if you are looking for general instructions on extending OMERO with a service, see Extending OMERO.server. If you would indeed like to create a core service, please contact the forum.

To fulfill #306, r905 provides all the classes and modifications needed to create a new stateless service (where this varies from stateful services is also detailed). In brief, a service provider must create an interface, an implementation of that interface, a Spring configuration file, as well as modify the server configuration and the central service factory (These last two points stand to change with #314).

Note

With the creation of OMERO.blitz, there are several other locations which need to be modified. These are also listed below.

Files to create

src/main/java/ome/api/IConfig.java

the interface which will be made available to client and server alike (which is why all interfaces must be located in the /common component). Only serializable and client-available types should enter or exit the API. Must subclass ``ome.api.ServiceInterface``.

src/main/java/ome/logic/ConfigImpl.java

the implementation which will usually subclass AbstractLevel{1,2}Service or AbstractBean (See more below on super-classes) This is class obviously requires the most work, both to fulfill the interface’s contract and to provide all the metadata (annotations) necessary to properly deploy the service.

src/main/resources/ome/services/service-ome.api.IConfig.xml

a Spring configuration file, which can “inject” any value available in the server (Omero)context into the implementation. Two short definitions are the minimum. (Currently not definable with annotations.) As explained in the file, the name of the file is not required and in fact the two definitions can be added to any of the files which fall within the lookup definition in the server’s beanRefContext.xml file (see below).

src/main/java/ome/services/blitz/impl/ConfigI.java

a Ice “servant” implementation which can use on of several methods for delegating to the ome.api.IConfig interface, but all of which support throttling.

Files to edit (not strictly necessary, see #314)

src/main/java/ome/system/ServiceFactory.java

our central API factory, needs an additional method for looking up the new interface (get<interface name>Service())

src/main/resources/ome/services/ server Spring

configurations, which makes the use of JNDI and JAAS significantly simpler.

src/main/slice/omero/API.ice (blitz)

a ZeroC slice definition file, which provides cross-language mappings. Add the same service method to ServiceFactoryI as to ServiceFactory.java.

src/main/resources/ome/services/blitz-servantDefinitions.xml (blitz)

a Spring configuration, which defines a mapping between Ice servants and Java services.

src/main/slice/omero/Constants.ice (blitz)

a ZeroC slice definition file, which provides constants needed for looking up services, etc.

src/main/java/ome/services/blitz/impl/ServiceFactoryI.java (blitz)

the central session in a blitz. Should always be edited parallel to ServiceFactory.java. Also optional in that MyServicePrxHelper.uncheckedCast( serviceFactoryI.getByName(String) ) can be used instead.

Files involved

src/main/resources/beanRefContext.xml

src/main/resources/beanRefContext.xml

Singleton definitions which allow for the static location of the active context. These do not need to be edited, but in the case of the server beanRefContext.xml, it does define which files will be used to create the new context (of importance is the line classpath*:ome/services/service-*.xml). blitz’s beanRefContext.xml defines the pattern classpath*:ome/services/blitz-*.xml to allow for blitz-specific configuration.

And do not forget the tests

src/test/java/ome/server/itests/ConfigTest.java

tests only the implementation without a container.

blitz: Currently, testing blitz is outside the scope of this document.

Things to be aware of

Local APIs

Several services implement a server-side subclass of the ome.api interface rather than the interface itself. These interfaces are typically in ome.api.local. Such local interfaces can provide methods that should not be made available to clients, but which are needed within the server. Though not currently used, the @Local() annotation on the implementation can list the local interface for future use. See UpdateImpl for an example.

Stateful services

Currently all stateful services are in their own component (renderer and romio) but their interface will still need to be under common for them to be accessible to clients. To be done.