Runtime Setup

Introduction

This chapter describes how to run Stardust in a Spring-managed environment. Stardust is built to leverage functionalities of arbitrary managed environments. Since different managed environments are valid runtime platforms for Stardust, there is a dedicated layer to configure integration in one of these environments. In general, the configuration is reduced to the following aspects:

Furthermore this chapter includes a section on Spring Remoting and Stardust as well as a section on Keeping the Configurations Separate.

Configuring the Managed Environment

As for any Spring application, the Stardust related configuration resides in the Spring configuration file. The Spring configuration files including all Stardust-related configuration are provided in the Stardust distribution as a set of the following three files:

These files are located in the etc/spring directory of your Stardust installation. If you use the configuration provided with the Stardust distribution, you can jump directly to Configuring the Stardust clients.

Using a custom Timer Scheduler

To use a custom TimerScheduler instead of the provided DefaultScheduler, add the following scheduled factory bean and time scheduler bean to your stardust-spring-context.xml file:

<bean id="timerFactoryBean" class="org.springframework.scheduling.concurrent.ScheduledExecutorFactoryBean" />
<bean id="timerScheduler" class="org.eclipse.stardust.engine.spring.schedulers.TimerScheduler">
   <property name="service" ref="timerFactoryBean" />
</bean>

Additionally, add the following time scheduler property to the carnotForkingService bean:

<bean id="carnotForkingService" parent="abstractCarnotService"
   class="org.eclipse.stardust.engine.api.spring.QueuedSpringForkingService">
   [...]
   <property name="scheduler" ref="timerScheduler" />
</bean>

Property Placeholder

The property placeholder reads the carnot.properties and allows to reference entries made in the carnot.properties in the Spring configuration.

Data Source

The Stardust data source in the standard configuration defines a data source according to the audit trail data source bean set in the AuditTrail.DataSourceBean property in your carnot.properties file.

All connection properties required for this data source are provided as references to the values in the carnot.properties file. You can change the data source type as well as the connection properties. These settings depend on the database you are using, please refer to the chapter Audit Trail Database Setup of the Deployment Guide for detailed information on settings for a specific database.

Transaction Manager

Stardust delegates the transaction handling to Spring. You can use arbitrary transaction managers, depending on what suits your needs best. The default configuration for Stardust is the org.springframework.transaction.jta.JtaTransactionManager.

Enabling logging on transaction management for Spring managed Stardust runtime

Add the following logger to log4j configuration:

log4j.logger.org.springframework.transaction=DEBUG
log4j.logger.org.springframework.transaction.interceptor.TransactionInterceptor=DEBUG

Configuring the Stardust Deployment

Deployment information in Spring is added to the same configuration file as the Spring configuration itself. In Stardust's example configuration described above there are several Stardust Spring beans.

If working in Spring local mode, a Web server is not necessary. Make sure that all libraries are in the CLASSPATH and your CARNOT_WORK is set to your default workspace location.

In case of Web deployment add the library carnot-spring.jar, residing in the lib folder of your Stardust installation, as well as all libraries residing in the lib/spring folder, to your WEB-INF/lib folder.

Preparing a Deployment in an EJB Environment

To prepare a deployment of Spring bean applications in an EJB Environment, perform the following steps:

  1. Put your spring.jar and carnot-spring.jar files from the WEB-INF/lib folder of your ipp-portal.war directly into the ear file.
  2. Reference these jar files in the classpath section of the stardust-engine-core/META-INF/MANIFEST.MF file.
  3. Make sure the spring.jar file is removed from the WEB-INF/lib folder of your ipp-portal.war and referenced instead in the classpath section of ipp-portal.war/META-INF/MANIFEST.MF.
  4. In case you are working with JBoss, additionally you need to:
    1. Add the following to your carnot.properties file:
      Carnot.Spring.ApplicationContextClass = org.jboss.spring.vfs.context.VFSClassPathXmlApplicationContext

Services

carnotWorkflowService

Stardust's workflow service is needed for all basic operations. Consider that the singleton attribute has to be set to false.

The following class is provided for this service: org.eclipse.stardust.engine.api.spring.WorkflowServiceBean.

carnotUserService

Stardust's user service is needed for all user operations. Consider that the singleton attribute has to be set to false.

The following class is provided for this service: org.eclipse.stardust.engine.api.spring.UserServiceBean.

carnotQueryService

Stardust's query service. Needed for all query operations. Consider that the singleton attribute has to be set to false.

The following class is provided for this service: org.eclipse.stardust.engine.api.spring.QueryServiceBean.

carnotAdministrationService

Stardust's administration service is needed for all administrative operations. Consider that the singleton attribute has to be set to false.

The following class is provided for this service: org.eclipse.stardust.engine.api.spring.AdministrationServiceBean.

carnotForkingService

Stardust's forking service is needed internally to fork asynchronous process threads. In most deployment scenarios it is very important to control the amount of threads a system will create. This is necessary to control resource usage, such as database connections. Stardust's Spring forking service delegates the thread control to a job manager. Consider that the singleton attribute has to be set to false.

The following class is provided for this service: org.eclipse.stardust.engine.api.spring.QueuedSpringForkingService.

Configuring the Stardust Clients

It is assumed that Stardust is bootstrapping the Spring environment. This is the case for:

If you run Stardust embedded in your own Spring-enabled application, some of the following steps, like classpath setup, might not be necessary. Refer to the chapter Embedding Stardust into a Spring Bean Application for details.

Classpath Setup

The Stardust Spring integration is tested against the Spring Framework 3.2.4. Make sure you add the libraries spring.jar (from the Spring Framework) and carnot-spring.jar (delivered with the Stardust distribution) to your classpath.

If you are using a Stardust fat client, the carnot-spring.jar will automatically be loaded. The additional Spring library mentioned above have to be placed in the lib directory of your Stardust workspace. Please add also the Jakarta commons-logging library (version 1.1.1) and the Spring library c3p0-0.9.0.4.jar (if you are using the default data source configuration).

If you are using a Stardust Web client (e.g. Tomcat), all libraries have to be placed in the Web application's WEB-INF/lib directory.

That means, that you add the libraries spring.jar (from the Spring Framework), carnot-spring.jar, residing in the lib folder of your Stardust installation, as well as all libraries residing in the lib/spring folder, to your WEB-INF/lib folder.

Spring Context

The config files, usually the three files carnot-spring-services-context.xml, carnot-spring-jta-jencks-context.xml and carnot-spring-ds-jndi-context.xml from the etc/spring subdirectory of your Stardust installation, have to be copied to the classpath as well. In case of fat clients they have to be copied to your Stardust workspace's etc directory. In case of a Web client they have to be copied to the WEB-INF/classes directory of your Web application. If you have set up your own configure files, please place them in the classes folder as well and reference them with an import statement in one of the carnot-spring*-context.xml files (see also section Keeping the Configurations Separate).

Setting Local or JMS ForkingService

In your carnot-spring-services-context.xml file, set the forking service to:

...
<alias name="${forkingServiceBeanName}" alias="carnotForkingService" />
...

Replace ${forkingServiceBeanName} by localForkingService, in case you are working in a non-JMS environment. Otherwise replace it by jmsForkingService.

Custom Configuration Settings

The bean customCarnotProperties offers the possibility for configuration settings outside the carnot.ear. Here you can enter Stardust properties or load them from the classpath.

<bean id="customCarnotProperties"
  class="org.springframework.beans.factory.config.PropertiesFactoryBean">
    <property name="properties">
        <props>
            <prop key="AuditTrail.Type">DERBY</prop>
            ...
        </props>
    </property>
</bean>

You can then pass these properties to the beans:

<bean id="carnotUserService"
  class="org.eclipse.stardust.engine.api.spring.UserServiceBean">
    <property name="dataSource"> ... </property>
    <property name="transactionManager"> ... </property>
    <property name="carnotProperties" ref="customCarnotProperties" />
</bean>

Spring Configuration in a Web Environment

If you are working in a Web environment you should configure JNDI. Your carnot-spring-ds-jndi-context.xml file contains JNDI configuration entries, which you have to apply to the database you are using.

The data source configuration looks like the following:

<bean id="carnotXaAuditTrailDataSourceJNDI"
  class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="java:comp/env/jdbc/AuditTrail.DataSource" />
</bean>

Reference this configuration according to the database you use, in the appropriate carnotAuditTrailDataSource configuration, e.g. if you are using Oracle:

   <bean id="carnotXaAuditTrailDataSourceLocal" class="oracle.jdbc.xa.OracleXADataSource" lazy-init="true">
      <property name="serverName" value="${AuditTrail.Host}" />
      <property name="portNumber" value="${AuditTrail.Port}" />
      <property name="databaseName" value="${AuditTrail.Instance}" />
      <property name="user" value="${AuditTrail.User}" />
      <property name="password" value="${AuditTrail.Password}" />
   </bean>

Please refer to the chapter Audit Trail Database Setup of the Deployment Guide for detailed information on the audit trail properties settings for a specific database.

Configure a web.xml file, containing the following lines:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/config/ipp/spring/*-context.xml</param-value>
</context-param>

Stardust Properties

The client factory has to be set in the carnot.properties file relevant for your client type. In case of fat clients, this file is located in your Stardust workspace's etc directory. In case of a Web client, the carnot.properties are located in the WEB-INF/classes directory.

In case of Web deployment please change the value of the properties Client.ServiceFactory and Web.ServiceFactory in the carnot.properties file, residing in the WEB-INF/classes folder of your ipp-portal.war, to:

Client.ServiceFactory = org.eclipse.stardust.engine.api.spring.SpringServiceFactory
Web.ServiceFactory = org.eclipse.stardust.engine.api.spring.SpringServiceFactory

Additionally set the audit trail properties according to the database you are using:

For example, set the properties to:

AuditTrail.Type = Oracle

AuditTrail.DriverClass = oracle.jdbc.OracleDriver
AuditTrail.URL = jdbc:oracle:thin:@<host>:<port>:<dbname>
AuditTrail.User = <yourDBUserName>
AuditTrail.Password = <yourDBUserPassword>
AuditTrail.DataSourceBean = carnotXaAuditTrailDataSourceLocalUrl

Please refer to the chapter Audit Trail Database Setup of the Deployment Guide for detailed information on the audit trail properties settings for a specific database.

Usually the Stardust Spring configuration is set up in the file stardust-spring-context.xml. In case you want to use another configuration file, set the property Carnot.Spring.ApplicationContextFile to your own configuration:

Carnot.Spring.ApplicationContextFile = my-spring-context.xml

Spring Remoting and Stardust

Spring offers multiple possibilities for remote communication. Stardust is agnostic of the remoting implementation used. However, in order to work with Stardust, remoting implementations need to rely on Java serialization and deserialization. An example for a valid remoting implementation are the HttpInvoker.

Spring remoting does not support transaction propagation. However, you have the following options for a workaround:

  1. Deploy the additional code on the server, too, and invoke this code via remoting. As the additional code will invoke the WorkflowService locally on the server, both can share the same transaction.
  2. Through EJB remoting: invoke the WorkflowService via EJB-remoting. This requires the engine to be deployed as EJBs.
  3. Running Spring against WebLogic RMI: use WebLogic RMI for remoting and in the client use the remote JTA transaction manager from WebLogic

Spring Configuration Example via HTTP Remoting

In the following section we present a spring configuration, using the Stardust Process engine as shared server and Web deployment. This engine can be accessed via a Web or Java client. For example the clients could be the Stardust Portal or the Sysconsole.

Server Configuration

Configuration of the web.xml

Add the following lines to the web.xml file:

<servlet>
    <servlet-name>carnot-spring-remoting</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>carnot-spring-remoting</servlet-name>
    <url-pattern>/remoting/*</url-pattern>
</servlet-mapping>
<resource-ref>
    <res-ref-name>jdbc/AuditTrail.DataSource</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

Servlet Configuration

The servlet configuration should be located in the WEB-INF/config/ipp/srping folder of your Web application. The filename is composed of the servlet name with postfix "-servlet". Thus, the servlet configuration in our example would be called carnot-spring-remoting-servlet.xml.

The following diagram illustrates the spring beans connections, which are necessary for the server configuration. A bean is created for the Data Source to be used and the according transaction manager. Now these beans are passed per dependency injection to:

The beans CarnotWorkflowService, CarnotAdministrationService, CarnotUserService and CarnotQueryService represent the interface for Remoting and the service beans.

carnot-spring-remoting-servlet.xml

The spring configuration for the servlet and hence the server configuration of our Stardust Process engine:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<!-- Application context for a Stardust Process Engine server -->
<beans>
    <!-- use DataSource that is specified in the application server -->
    <bean id="carnotAuditTrailDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="java:comp/env/jdbc/AuditTrail.DataSource" />
    </bean>

    <!-- Definition of the transaction manager -->
    <bean id="carnotTxManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource"><ref local="carnotAuditTrailDataSource" /></property>
    </bean>

    <!-- ForkingService -->
    <bean id="carnotForkingService" class="org.eclipse.stardust.engine.api.spring.QueuedSpringForkingService">
        <property name="dataSource"> <ref local="carnotAuditTrailDataSource"/> </property>
        <property name="transactionManager"> <ref local="carnotTxManager"/> </property>
        <property name="jobManager"> <ref local="carnotAsyncJobManager"/> </property>
    </bean>
    
    <!-- The following service beans will be exported by the carnot-spring-remoting servlet -->
    <bean id="carnotWorkflowService" class="org.eclipse.stardust.engine.api.spring.WorkflowServiceBean">
        <property name="dataSource"> <ref local="carnotAuditTrailDataSource"/> </property>
        <property name="transactionManager"> <ref local="carnotTxManager"/> </property>
    </bean>
        <bean id="carnotUserService" class="org.eclipse.stardust.engine.api.spring.UserServiceBean">
        <property name="dataSource"> <ref local="carnotAuditTrailDataSource"/> </property>
        <property name="transactionManager"> <ref local="carnotTxManager"/> </property>
    </bean>

    <bean id="carnotQueryService" class="org.eclipse.stardust.engine.api.spring.QueryServiceBean">
        <property name="dataSource"> <ref bean="carnotAuditTrailDataSource"/> </property>
        <property name="transactionManager"> <ref local="carnotTxManager"/> </property>
    </bean>

    <bean id="carnotAdministrationService" class="org.eclipse.stardust.engine.api.spring.AdministrationServiceBean">
        <property name="dataSource"> <ref local="carnotAuditTrailDataSource"/> </property>
        <property name="transactionManager"> <ref local="carnotTxManager"/> </property>
    </bean>

    <!-- remote access to Stardust services -->
    <bean name="carnotRemoteInvocationExecutor"
        class="org.eclipse.stardust.engine.api.spring.CarnotRemoteInvocationExecutor" />

    <bean name="/CarnotWorkflowService" singleton="false"
        class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
        <property name="remoteInvocationExecutor" ref="carnotRemoteInvocationExecutor" />
        <property name="service" ref="carnotWorkflowService" />
        <property name="serviceInterface" value="org.eclipse.stardust.engine.api.spring.IWorkflowService" />
    </bean>

    <bean name="/CarnotUserService"
        class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
        <property name="remoteInvocationExecutor" ref="carnotRemoteInvocationExecutor" />
        <property name="service" ref="carnotUserService" />
        <property name="serviceInterface" value="org.eclipse.stardust.engine.api.spring.IUserService" />
    </bean>

    <bean name="/CarnotQueryService" singleton="false"
        class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
        <property name="remoteInvocationExecutor" ref="carnotRemoteInvocationExecutor" />
        <property name="service" ref="carnotQueryService" />
        <property name="serviceInterface" value="org.eclipse.stardust.engine.api.spring.IQueryService" />
    </bean>
        <bean name="/CarnotAdministrationService" 
        class="org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter">
        <property name="remoteInvocationExecutor" ref="carnotRemoteInvocationExecutor" />
        <property name="service" ref="carnotAdministrationService" />
        <property name="serviceInterface" value="org.eclipse.stardust.engine.api.spring.IAdministrationService" />
    </bean>
</beans>

Necessary JAR Files

The archive files carnot-engine.jar, carnot-spring.jar, spring-3.2.4.jar and their dependencies should be added to the classpath of the Web application. Add them to the WEB-INF/lib folder of your Web application.

Client Configuration

According to the implementation of the client, the following ServiceFactory should be set in the carnot.properties file:

Client.ServiceFactory=org.eclipse.stardust.engine.api.spring.SpringServiceFactory
Web.ServiceFactory=org.eclipse.stardust.engine.api.spring.SpringServiceFactory

Additionally you can set the spring configuration file, which must exist in the classpath:

Carnot.Spring.ApplicationContextFile=carnot-spring-client.xml

carnot-spring-client.properties

In the carnot-spring-client.properties file set the URL to the location of the Stardust server component and the spring servlet to receive the http requests:

Carnot.Spring.RemotingUrl=http://<appserver>:<port>/<web-root>/remoting

carnot-spring-client.xml

The carnot-spring-client.xml file contains the spring configuration for the SpringServiceFactory.

Four service beans with access to the serverside beans via HTTP Remoting will be created.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<!--
    - Application context for a Stardust Process Engine client.
-->
<beans>

    <!-- Resolves MavenProject: org.eclipse.stardust.documentation:org.eclipse.stardust.docs.spring:1.1.2.v20140219-0356 @ /opt/users/hudsonbuild/workspace/stardust-kepler/documentation/org.eclipse.stardust.docs.spring/pom.xml placeholders from carnot-spring-client.properties -->
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location"> <value>classpath:carnot-spring-client.properties</value> </property>
    </bean>

    <bean id="carnotHttpInvokerRequestExecutor" 
        class="org.eclipse.stardust.engine.api.spring.CarnotHttpInvokerRequestExecutor" />

    <bean id="carnotWorkflowService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
        <property name="httpInvokerRequestExecutor" ref="carnotHttpInvokerRequestExecutor" />
        <property name="serviceUrl" value="${Carnot.Spring.RemotingUrl}/CarnotWorkflowService" />
        <property name="serviceInterface" value="org.eclipse.stardust.engine.api.spring.IWorkflowService" />
    </bean>

    <bean id="carnotUserService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
        <property name="httpInvokerRequestExecutor" ref="carnotHttpInvokerRequestExecutor" />
        <property name="serviceUrl" value="${Carnot.Spring.RemotingUrl}/CarnotUserService" />
        <property name="serviceInterface" value="org.eclipse.stardust.engine.api.spring.IUserService" />
    </bean>

    <bean id="carnotQueryService" class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
        <property name="httpInvokerRequestExecutor" ref="carnotHttpInvokerRequestExecutor" />
        <property name="serviceUrl" value="${Carnot.Spring.RemotingUrl}/CarnotQueryService" />
        <property name="serviceInterface" value="org.eclipse.stardust.engine.api.spring.IQueryService" />
    </bean>

    <bean id="carnotAdministrationService" 
        class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean">
        <property name="httpInvokerRequestExecutor" ref="carnotHttpInvokerRequestExecutor" />
        <property name="serviceUrl" value="${Carnot.Spring.RemotingUrl}/CarnotAdministrationService" />
        <property name="serviceInterface" value="org.eclipse.stardust.engine.api.spring.IAdministrationService" />
    </bean>
</beans>

Necessary JAR Files

The archive files carnot-client.jar, carnot-spring.jar, spring-3.2.4.jar and their dependencies should be added to the classpath of the Web application. Add them to the WEB-INF/lib folder of your Web application.

Keeping the Configurations Separate

Most Spring users will have their own Spring configuration and setup for their beans (including data sources, transaction managers, etc.). It is possible to declare all these beans in the carnot-spring*-config.xml or to put all Stardust beans into the own configuration. However, Stardust recommends to keep both files separate and leverage the import and alias functionality.

In order to import the carnot-spring*-config.xml into your context configuration add:

<import resource="services.xml"/>

If you want Stardust to use a data source and/or transaction manager defined in your context configuration, it is recommended to comment the Stardust data source definition and to create an alias:

<alias name="myTxManager" alias="carnotTxManager"/>