The CTP Module
UNDER CONSTRUCTION
The CTP module (CTP.jar) contains the code of the CTP application, including all the standard stages and plugins. This article describes the theory of operation of the packages contained in the CTP module. The CTP module is used in CTP, TFS, CTPClient, ISN, and other MIRC software. The intended audience for this article is software engineers extending or maintaining any of that software.
See Setting Up a MIRC Development Environment for information on obtaining and building the VTP module.
The CTP module contains five packages:
- org.rsna.ctp contains the CTP main class and the Configuration singleton class.
- org.rsna.ctp.objects contains classes that implement the four types of objects that CTP can process.
- org.rsna.ctp.pipeline contains the Pipeline class, interfaces that define the types of pipeline stages, and a set of abstract classes that provide starting points for developing each pipeline stage type.
- org.rsna.ctp.plugin contains the interface that defines a plugin and an abstract class that provides a starting point for developing a plugin.
- org.rsna.ctp.servlets contains the standard servlets used in CTP.
- org.rsna.ctp.stdstages contains the standard pipeline stages included in CTP.
Each of these packages will be described in the sections below, with example code where necessary to illustrate the theory of operation. It will be helpful to get the source code and build it so you can reference the Javadocs as you go along.
In addition to the packages listed above, the source code tree also contains packages that are part of helper applications used in CTP:
- org.rsna.installer contains the the installer program for CTP, TFS, and ISN.
- org.rsna.launcher contains the program used to manually launch CTP TFS, and ISN.
- org.rsna.runner contains the program that can be used in a batch job to start or stop CTP, TFS, and ISN. This program is typically used to implement a CTP Linux service.
1 Overview
CTP is a framework for pipelines and plugins.
- A pipeline is an ordered sequence of processing stages. Data objects enter a pipeline at the head end and encounter the stages in sequence.
- A pipeline stage performs some task on a data object when it arrives at the stage as it flows down the pipe.
- A plugin is a module that adds capability to the program outside the scope of a pipeline.
CTP includes a servlet container to provide a user interface for configuring certain features and for accessing data.
CTP is installed using the CTP-installer.jar program that is created when CTP is built. See Setting Up a MIRC Development Environment for information on building CTP. The installer creates a folder called CTP and puts all the necesssary files and subdirectories in it.
CTP is configured by a single XML file. CTP imposes no limits on the number of pipelines or plugins that may be configured or on the number of stages that may be configured in a single pipe. The structure of the configuration file is described in detail in CTP-The RSNA Clinical Trial Processor.
CTP can be run manually through the Launcher.jar program, or it can be run as a Windows or Linux service. See Running CTP as a Windows Service or Running CTP as a Linux Service for details.
The Launcher.jar program is located in the CTP directory. All the modules required for running CTP are located in the CTP/libraries directory or one of its subdirectories. The manifest in the CTP.jar module includes a classpath listing only the util.jar module. When CTP starts, it calls ClasspathUtil.addJars to add all the jar files in the CTP/libraries directory tree to the classpath. By constructing the classpath in this way, developers can add pipeline stages and plugins into CTP without having to modify the CTP build itself.
After setting up the classpath, CTP then loads the configuration. The configuration is encapsulated in the singleton org.rsna.ctp.Configuration class. The Configuration class parses the configuration file and loads the plugins and pipelines. Pipelines load their stages.
Pipelines, stages, and plugins have constructors that take their configuration file XML Element as an argument, and they obtain all their configuration information from it. When these objects are instantiated, the Configuration object is not yet constructed; therefore, the constructors are just for construction of the objects themselves, and they may not reference the Configuration object or any other stages or plugins.
Pipelines, stages, and plugins have start methods that are called after the Configuration object has been constructed and all the pipelines, stages, and plugins have been instantiated. The start methods can reference anything in the Configuration, including other stages and plugins. This two-phase startup is necessary because certain stages are designed to interact with other stages and plugins, so everything has to be constructed before any such interaction can be allowed to occur.
CTP calls the start methods of all the plugins first, followed by the start methods of all the pipelines. The start methods of pipelines call the start methods of their stages. This sequence is important because a stage may depend on a plugin, and therefore a plugin must be completely running before it is referenced.
Pipelines are implemented as asynchronous threads. A pipeline object maintains an ordered list of all its stages. There are four types of stages:
- ImportService
- Processor
- StorageService
- ExportService
These stage types are described in CTP-The RSNA Clinical Trial Processor and Extending CTP. Each stage implements its specific interface. Data objects enter a pipe through an ImportService stage. A pipeline object maintains a separate list of its ImportService stages. When a pipeline is ready to process a new data object, it polls its ImportServices in turn until it finds one that has a data object available. As data objects flow down the pipe, they skip any ImportServices; thus, although ImportServices are configured into the pipeline, they can be thought of as being separate from it, and the order in which they appear - and even where they appear - in the pipeline is not important. (Nevertheless, for human readability, it is best to put the ImportServices first in the pipe.)