Services

The TopLogic engine consists of a large number of services that are integrated and parameterized via the application configuration. A service is a singleton object (an object of a class of which there is only one instance) in the system. Such a service instance has a specific life cycle. It is created and initialized when the system is booted. During the runtime of the system, the service instance provides services or manages resources of the system. When the system is shut down, the service instance is also informed and can perform cleanup operations.

Service class

A service is a derivative of the class com.top_logic.basic.module.ManagedClass. It can override the startUp() and shutDown() methods to perform initialization and cleanup tasks when booting and shutting down the system. In addition, a service class also needs a descriptor class, which is used to register it in the configuration. The descriptor class is typically an inner class of the service named Module derived from TypedRuntimeModule. The descriptor class must implement the singleton pattern (cf. singleton reference) in order to be referenceable from the configuration.

Service configuration

A service can be parameterized by configuration options. Typically, the basic configuration in the application configuration is in the module that defines the service. In the concrete application the parameters can be overwritten. The service can also be displayed in the service editor at application runtime and its configuration settings can be edited.

The configuration options that can be set for a service are defined by the service in its configuration interface. The configuration interface follows the rules of typed configuration. For each configuration property, the configuration interface defines a Get method that returns the value. The name of the method determines the name of the configuration property (or it is explicitly specified via the annotation @Name(...) at the Get method). The configuration interface is linked to the service via the service constructor. The service constructor must have the signature public MyService(InstantiationContext, Config) for this. Here Config is the configuration interface of the service, which in turn must be an extension of ServiceConfiguration.

Minimal service class

A minimal service (with configuration options) consists of the following classes:

import com.top_logic.basic.config.InstantiationContext;
import com.top_logic.basic.config.annotation.Name;
import com.top_logic.basic.module.ConfiguredManagedClass;
import com.top_logic.basic.module.TypedRuntimeModule;

/**
 * Custom service.
 */
public class MinimalService extends ConfiguredManagedClass<MinimalService.Config<?>> {

	/**
	 * Configuration options for {@link MinimalService}.
	 */
	public interface Config<I extends MinimalService> extends ConfiguredManagedClass.Config<I> {

		/**
		 * Example for an int-valued configuration option.
		 */
		@Name("my-option")
		int getMyOption();

	}

	/**
	 * Creates a {@link MinimalService} from configuration.
	 */
	public MinimalService(InstantiationContext context, Config<?> config) {
		super(context, config);

		// TODO: Do something with the options in config.
	}

	@Override
	protected void startUp() {
		super.startUp();

		// TODO: Some startup task.
	}

	@Override
	protected void shutDown() {
		// TODO: Some cleanup work.

		super.shutDown();
	}

	/**
	 * Service descriptor for {@link MinimalService}
	 */
	public static class Module extends TypedRuntimeModule<MinimalService> {

		/**
		 * Singleton {@link Module} instance for reference in the configuration.
		 */
		public static final Module INSTANCE = new Module();

		private Module() {
			// Singleton constructor.
		}

		@Override
		public Class<MinimalService> getImplementation() {
			return MinimalService.class;
		}

	}

}

Instead of deriving ManagedClass directly, ConfiguredManagedClass is used here to parameterize the service via configuration options. In this case, the confiugration interface of the service must extend ConfiguredManagedClass.Config accordingly.

Activating the service

The service descriptor must now be included in the application configuration and the service activated there:

<application xmlns:config="http://www.top-logic.com/ns/config/6.0">
	<services>
		<config service-class="com.top_logic.basic.module.ModuleSystem">
			<instance>
				<modules>

					<!-- Register and activate service here. -->
					<module key="my.package.MinimalService$Module" value="true"/>

				</modules>
			</instance>
		</config>
	</services>
</application>

Service basic configuration

The basic service configuration is also stored in the application configuration. Here, at least the service class (here MinimalService) and its service implementation (here also MinimalService) must be specified. Furthermore, values can be stored for configuration parameters that were defined in the configuration interface of the service:

<application xmlns:config="http://www.top-logic.com/ns/config/6.0">
	<services>

		<!-- Core configuration with example option. -->
		<config service-class="com.top_logic.base.MinimalService">
			<instance class="com.top_logic.base.MinimalService"
				my-option="42"
			>
			</instance>
		</config>

	</services>
</application>