5. GDA configuration

5.1. Spring configuration

5.1.1. FindableNameSetterPostProcessor

Putting this:

<bean class="gda.spring.FindableNameSetterPostProcessor" />

in your Spring XML file causes all Findable objects to have their name property set to be the same as the Spring id. Therefore you don’t (except in a couple of special cases) need:

<property name="name" value="..." />

5.1.2. Making properties from java.properties available

Use this:

<context:property-placeholder location="file:${gda.config}/properties/java.properties" />

It allows you to use properties in your Spring XML files. For example:

<property name="hostname" value="${gda.images.camerahost}" />

5.1.3. Instantiating EPICS devices directly

For example:

<bean id="S1_top_motor" class="gda.device.motor.EpicsMotor">
    <property name="pvName" value="BL04J-AL-SLITS-01:Y:PLUS" />
</bean>

5.1.4. Instantiating using the EPICS interface “behind the scenes”

This is for those who don’t like having PVs in their XML files ;-)

Put this somewhere in the Spring XML file (it doesn’t need an ID):

<bean class="gda.configuration.epics.EpicsConfiguration">
    <constructor-arg value="${gda.config}/xml/epics-interface.xml" />
</bean>

Then do this:

<bean id="S1_top_motor" class="gda.spring.EpicsMotorFactoryBean">
    <property name="deviceName" value="S1.YP" />
</bean>

EpicsMotorFactoryBean is a Spring factory bean - the S1_top_motor object will actually be an EpicsMotor.

In addition to EpicsMotorFactoryBean, there is also EpicsMonitorFactoryBean and EpicsPositionerFactoryBean (they all need a deviceName).

5.1.5. Importing one file into another

<import resource="S1.xml" />

Effectively, the <import> is replaced with the contents of the imported file. All the beans are in the same Spring context (i.e. no need to duplicate the PropertyPlaceholderConfigurer, the FindableNameSetterPostProcessor, etc.).

5.1.6. Please use the ref attribute!!!

Instead of this:

<bean id="s1_bottom" class="gda.device.scannable.ScannableMotor">
    <property name="motorName" value="S1_bottom_motor" />
</bean>

you can do this:

<bean id="s1_bottom" class="gda.device.scannable.ScannableMotor">
    <property name="motor" ref="S1_bottom_motor" />
</bean>

Note the property is motor, not motorName, and this uses the ref attribute - which plugs the S1_bottom_motor motor into the s1_bottom object (so the ScannableMotor doesn’t need to use the Finder to get the underlying motor - it’s already wired up using Spring).

Since Spring has this dependency injection capability, there’s no need to use the Finder in new classes - Spring can be used to do the wiring.

5.1.7. Making remote objects available through CORBA

You’ll need this in your server-side configuration:

<corba:export namespace="stnBase" />

You need to declare the corba namespace by putting this at the top of the XML file:

xmlns:corba="http://www.diamond.ac.uk/schema/gda/corba"

and adding these entries to the xsi:schemaLocation attribute:

http://www.diamond.ac.uk/schema/gda/corba http://www.diamond.ac.uk/schema/gda/corba/gda-corba-1.0.xsd

Due to a limitation of Spring, property placeholders cannot be used in the namespace attribute when using <corba:export />. So this, for example:

<corba:export namespace="${gda.beamline.name}" />

will not work. (Property placeholders are typically resolved by a PropertyPlaceholderConfigurer, which is a BeanFactoryPostProcessor that operates on bean definitions in an application context. The <corba:export /> element itself is not transformed into a bean definition: it uses the namespace value to add bean definitions for remote objects. It is not possible for the PropertyPlaceholderConfigurer to resolve placeholders used in the namespace attribute before that value is used to find remote objects.)

5.1.8. Importing remote objects from another object server

You’ll need this in your client-side configuration:

<corba:import namespace="stnBase" />

As with <corba:export />, to use the corba namespace you need to declare it at the top of the XML file.

The good thing about using corba:import is that ‘hidden’ beans are added to the Spring context for all of the remote objects, so you can use them in any ref="..." attributes elsewhere in the file.

5.1.9. The corba namespace

If you use the <corba:export> or <corba:import> elements described above, you should add the schema for the corba namespace to the Eclipse XML Catalog, so that Eclipse can validate XML files containing these custom elements. To do this:

  • Open the Eclipse preferences (Window → Preferences)
  • Go to XML → XML Catalog
  • Click “Add...”
  • Enter the following details:
    • Location: click “Workspace...” and select uk.ac.gda.core/src/gda/spring/namespaces/corba/gda-corba-1.0.xsd
    • Key Type: choose “Namespace Name”
    • Key: enter http://www.diamond.ac.uk/schema/gda/corba/gda-corba-1.0.xsd

Due to an issue with SpringSource Tool Suite, you may still get the following warning, which can be ignored:

Unable to locate Spring NamespaceHandler for element ‘corba:export’ of schema namespace ‘http://www.diamond.ac.uk/schema/gda/corba’

5.1.10. SingletonRegistrationPostProcessor

<bean class="gda.spring.SingletonRegistrationPostProcessor" />

This registers certain objects you create in the Spring context as the application-wide singleton instances (e.g. the metadata).

(Objects in Spring XML files are, by default, singletons. In a perfect world, the metadata and other singletons could be injected into other objects, rather than the other objects calling Whatever.getInstance(). In practice it’s difficult to do this because (1) there are too many objects that need the singletons; and (2) not all of those objects will be defined in the Spring XML file. It’s good to define the objects in the Spring XML file, as this gives us complete control over their configuration, and means we can swap the real objects for mock objects. But this means we need to register those objects with some kind of registry.)

5.1.11. Property editors

PropertyEditor (Javadoc) is a standard Java interface concerned with converting text representations of property values into their ‘real’ types (among other things).

In Spring they are used to convert the text values used in Spring configuration files into the type required by the bean being instantiated. Spring has built-in support for many types already, but by putting this in your Spring configuration:

<import resource="classpath:gda/spring/propertyeditors/registration.xml" />

you will also be able to set properties of these types:

and any other types supported by the PropertyEditors listed in the GdaPropertyEditorRegistrar class.

5.1.12. Example Spring configuration

The Diamond I04.1 beamline uses Spring exclusively for its configuation. If you have access to the GDA Subversion repository, you can view the I04.1 configuration. The Spring contexts for the two object servers are split into multiple XML files, which are all in the xml/server directory.

5.2. Logging

Logging messages can be generated not only by GDA classes, but also by third-party libraries such as Commons Configuration. GDA classes typically use the SLF4J API for logging. Log entries from code that uses Commons Logging or Log4j are redirected into SLF4J using two SLF4J bindings: Commons Logging over SLF4J and Log4j over SLF4J.

GDA uses Logback as the SLF4J implementation, so logging entries are passed from SLF4J to Logback.

5.2.1. Server-side logging configuration

The server-side logging configuration is used for object servers, and for the event server.

GDA has a default server-side logging configuration file, located in the uk.ac.gda.core plugin in the file src/gda/util/logging/configurations/server-default.xml.

A server-side logging configuration file for a particular GDA configuration can be specified using the gda.server.logging.xml property. The default server-side configuration will be applied first, followed by the custom configuration.

5.2.2. Client-side logging configuration

GDA has a default client-side logging configuration file, located in the uk.ac.gda.core plugin in the file src/gda/util/logging/configurations/client-default.xml.

A client-side logging configuration file for a particular GDA configuration can be specified using the gda.client.logging.xml property. The default client-side configuration will be applied first, followed by the custom configuration.

5.2.3. Using property placeholders in Logback configuration files

You can make properties defined in java.properties available for use in a Logback configuration file by adding the following element to the top of the file (inside the <configuration> element):

<property file="${gda.config}/properties/java.properties" />

(Use of ${gda.config} works here because gda.config is a system property.)

You can then use property placeholders elsewhere in the file. For example:

<appender name="SOCKET" class="ch.qos.logback.classic.net.SocketAppender">
    <RemoteHost>${gda.logserver.host}</RemoteHost>
    <Port>${gda.logserver.port}</Port>
    ...
</appender>

5.3. Metadata

5.3.1. ICAT

The icat property of the GdaMetadata instance should be defined as follows:

<bean class="gda.data.metadata.icat.IcatConnectionDetails">
    <property name="name" value="icat" />
    <property name="url" value="jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(HOST=${oracle.host})(PROTOCOL=tcp)(PORT=${oracle.port}))(CONNECT_DATA=(SID=xe)))" />
    <property name="user" value="${icat.username}" />
    <property name="password" value="${icat.password}" />
    <property name="shiftTolerance" value="1440" />
    <property name="icatClassName" value="gda.data.metadata.icat.DLSIcat" />
</bean>

(oracle.host, oracle.port, icat.username, and icat.password are properties defined in the java.properties file.)

The DLSIcat class provides connectivity to the ICAT database. There is an alternate class in the uk.ac.gda.core plugin called XMLIcat which uses an XML file as a database. This is primarily for use in unit testing or offsite demonstrations, but could also be used by other facilities if they do a database dump into that format.