Windows service example

From ControlTier

Jump to: navigation, search

Requires Version 3.4.4 (help?)

This Windows Service example shows the basics of using an object of the JavaServiceWrapper type to manage the runtime lifecycle of a JBoss Application Server which is represented by the JBossServer type. The JavaServiceWrapper type manages the use of Tanuki Software's Java Service Wrapper facility to control a java process as a Windows NT service.

This example shows you how to do the following things:

  1. Use the lifecycle commands, Start, Stop and Status to manage the JavaServiceWrapper
  2. Use the commands Add, and Remove, to add and remove Windows NT services
  3. Use the JavaServiceWrapper Settings to configure the Tanuki Java Service Wrapper to properly manage the JBoss server
  4. use the project.xml resource model format to define and configure the Service objects

This example is built to using the JBossServer type, which has a JBossZip as a child dependency to allow deployment of the JBoss software zip package. (Further customization would include deploying a ear or war package to the server, but is not within the scope of this example.)

We also define a JavaServiceWrapper service object which manages the JBossServer. This JavaServiceWrapper has a JavaServiceWrapperZip child dependency to deploy the Java Service Wrapper software zip package. It also has the JBossServer object as a child dependency.

Once the JBossServer is defined, it is set as a child dependency of the JavaServiceWrapper. We use the Deploy command to fully deploy and start the JavaServiceWrapper, which includes deploying the JBossServer that is its child dependency. The Deploy command is a workflow that calls a sequence of other commands. JavaServiceWrapper has extended the normal Deploy workflow with the highlighted commands:

  1. Stop
  2. Remove
  3. Packages-Install
  4. Service-Install
  5. Configure
  6. Add
  7. Start

JavaServiceWrapper has the Add and Remove commands to perform the Windows service registration or removal. It also has the Service-Install command, which performs the installation of the dependent JBossServer object. Once the JavaServiceWrapper is deployed, we can run the standard lifecycle commands Start and Stop on the JavaServiceWrapper object to control the JBoss windows service itself rather than the normal JBossServer lifecycle commands. Since the JavaServiceWrapper has registered a Windows Service definition to properly interface with the JBoss software, the lifecycle commands will simply act on the Windows Service using the normal system service control mechanism.

Contents

Dependencies

This demo has these dependencies.

  • ControlTier — 3.4.4
  • Windows
    • This example is not compatible with Linux or Unix. It is compatible with x86 32-bit Windows XP or newer.
  • Tanuki Software Java Service Wrapper — 3.3.3
  • JBoss Software — 4.0.5.GA
    • Download Zip: JBoss-4.0.5.GA release
    • Copy the downloaded Zip to %CTIER_ROOT%\examples\windows-service\pkgs\jboss-4.0.5.GA.zip

Building the Example

Follow the instructions in this section to setup the example code into your environment.

Note: Don't worry about what these commands do, as they just bootstrap the example code to work in your environment and to pre-load the resource model for you. (For complete detail about how to use the Examples see Using the Examples):

Execute these bootstrap steps:

  1. cd %CTIER_ROOT%\examples\windows-service
    • At the command line, navigate to the examples\windows-service directory under your %CTIER_ROOT% directory.
  2. Edit the file: templates\defaults.xml
    • If you use a different node name that 'localhost', modify the file templates\defaults.xml to set the value.
  3. ctl -p demo -m ProjectBuilder -c Register -- -xml projectbuilder.xml -install
    • This loads a ProjectBuilder object definition into the ControlTier Server.
  4. ctl -p demo -m JavaServiceWrapperZip -c upload -- -filename pkgs\wrapper-windows-x86-32-3.3.3.zip -xml templates\wrapper-windows-x86-32-3.3.3.zip.xml
    • Upload the "wrapper-windows-x86-32-3.3.3.zip" file to the package repository. (See Dependencies for download link.)
  5. ctl -p demo -m JBossZip -c upload -- -filename pkgs\jboss-4.0.5.GA.zip -xml templates\jboss-4.0.5.GA.zip.xml
    • Upload the "jboss-4.0.5.GA.zip" file to the package repository. (See Dependencies for download link.)
  6. ctl -p demo -t ProjectBuilder -o windows-service -c Build
    • Builds a working example based on template files and your working environment. Later see Further Customization

You are now ready to run the examples.

Running the Example

You can run any of the Service commands like so: ctl -p demo -t Service -o mock -c <command-name>

If you run the command without the "-c <command-name>" parameter you will see a listing of commands.

In the commands below, we will show the output of the command first, then an explanation of what occurred.

We will show how the JBoss server can be controlled using the JavaServiceWrapper object by doing a series of commands. The first command we will run is "Deploy", as this installs all of the necessary software packages and configures them. As a result of this command, the JBoss server installed as a windows service, and started up.

After the Deploy command, we will show how the service can be stopped, removed as a windows service, and finally re-added as a windows service, and started again using the individual commands.

Run Deploy

The Deploy command installs the dependent JavaServiceWrapperZip, installs the dependent JBossServer, configures the JavaServiceWrapper, and then starts it. When you execute it you should see that it in runs the sequence of commands in the Deploy workflow as shown in the Overview.

execute:

ctl -p demo -t JavaServiceWrapper -o windows-service -c Deploy

output:

Start: "Run the service deployment cycle, stopping, unconfiguring, installing package dependencies, installing the dependent Service,\
    and configuring and the starting the service. ." commands: Stop,Remove,Packages-Install,Service-Install,Configure,Add,Start
...
Running handler command: startService
wrapper  | Starting the JBoss 4.0.5 (windows-service) service...
wrapper  | JBoss 4.0.5 (windows-service) started.
Started the "jbosswrapper" Windows service.
end workflow command (1/1) -> "assertServiceIsUp "
end workflow command (7/7) -> "Start "
[command.timer.demo.JavaServiceWrapper.Deploy: 1:05.078 sec]
Workflow completed. execution time: 1:05.078 sec

What happened?

The Deploy command executed the workflow sequence described above.

  1. the Stop command is invoked, which in this case ends up doing nothing because the service is not yet installed.
    • The "jbosswrapper" Windows service is not running
  2. The Remove command removes an existing windows service, but this first execution does not have to remove anything.
    • The "jbosswrapper" Windows service is not installed
  3. The Packages-Install command downloads and extracts the JavaServiceWrapperZip object (the Tanuki software zip package)
    • Start: "Install the configured package dependencies for the deployment." \
    • Beginning installation for packages: wrapper-windows-x86-32-3.3.3.zip[JavaServiceWrapperZip] ...
  4. The Service-Install workflow then dispatches three commands to the JBossServer object
    1. The Install command, used to install the object definition to CTL
    2. The Packages-Install command, which similarly installs the JBossServerZip
    3. The Configure command, which generates the JBoss configuration
  5. Next the Configure command for the JavaServiceWrapper itself is executed, which generates the Tanuki software configuration file (wrapper.conf) via the Docs-Generate command.
    • Copying 1 file to C:\ctier\examples\windows-service\install\wrapper-windows-x86-32-3.3.3\conf
  6. Then the Add command registers a Windows Service definition using the Tanuki software and configuration
    • wrapper | JBoss 4.0.5 (windows-service) installed.
  7. Finally, the Start command starts the Windows Service, causing the JBoss server to start.
    • wrapper | Starting the JBoss 4.0.5 (windows-service) service...
    • wrapper | JBoss 4.0.5 (windows-service) started.
    • Started the "jbosswrapper" Windows service.

In this example, the JBossServer is configured to use the port 8180 to run, so you should now be able to visit the URL for JBoss ( http://localhost:8180 if your hostname is "localhost") to see the JBoss server default page:

JBoss running for the example

Run Stop

The Stop command ensures the service is stopped. When you execute it you should see that it in turn executes the assertServiceIsDown command, which will stop the Windows Service for JBoss.

execute:

ctl -p demo -t JavaServiceWrapper -o windows-service -c Stop

output:

begin workflow command (1/1) -> "assertServiceIsDown " ...
wrapper  | The JBoss 4.0.5 (windows-service) Service is installed.
wrapper  | Unable to query the configuration of the JBoss 4.0.5 (windows-service) service - Access is denied. (0x5)
wrapper  |   Running: Yes
Result: 3
Exit code = 3, running bit = 2
Running handler command: stopService
wrapper  | Stopping the JBoss 4.0.5 (windows-service) service...
wrapper  | Waiting to stop...
wrapper  | JBoss 4.0.5 (windows-service) stopped.
Stopped the "jbosswrapper" Windows service.
end workflow command (1/1) -> "assertServiceIsDown "

What happened?

The Stop command invokes the shutdown sequence for the Service:

  1. the assertServiceIsDown command is invoked, which uses the Tanuki wrapper to query the state of the service
    • begin workflow command (1/1) -> "assertServiceIsDown " ...
    • ...
    • wrapper | Running: Yes
  2. Since the service is running, the stopService command is invoked, which uses the Tanuki wrapper to stop the service
    • Running handler command: stopService
    • wrapper | Stopping the JBoss 4.0.5 (windows-service) service...
    • wrapper | Waiting to stop...
    • wrapper | JBoss 4.0.5 (windows-service) stopped.
    • Stopped the "jbosswrapper" Windows service
  3. Finally, the assertServiceIsDown succeeds because the stopService command succeeded.
    • end workflow command (1/1) -> "assertServiceIsDown "

Run Remove

The Remove command will remove the definition of the JBoss server as a Windows Service. This command first checks whether the service is already registered, and if so it runs the removeService command.

execute:

ctl -p demo -t JavaServiceWrapper -o windows-service -c Remove

output:

Start: "Remove the Java Service Wrapper Windows service if it is installed." commands: assertServiceIsNotInstalled
begin workflow command (1/1) -> "assertServiceIsNotInstalled " ...
wrapper  | The JBoss 4.0.5 (windows-service) Service is installed.
wrapper  | Unable to query the configuration of the JBoss 4.0.5 (windows-service) service - Access is denied. (0x5)
wrapper  |   Running: No
Result: 1
Exit code = 1
Running handler command: removeService
wrapper  | JBoss 4.0.5 (windows-service) removed.
end workflow command (1/1) -> "assertServiceIsNotInstalled "
[command.timer.demo.JavaServiceWrapper.Remove: 3.797 sec]
Workflow completed. execution time: 3.797 sec

What happened?

The Remove command invokes service removal sequence for the JavaServiceWrapper:

  1. the assertServiceIsNotInstalled command is invoked:
    • begin workflow command (1/1) -> "assertServiceIsNotInstalled " ...
  2. The assertServiceIsNotInstalled command uses the Tanuki wrapper to check whether the service is registered.
    • wrapper | The JBoss 4.0.5 (windows-service) Service is installed.
  3. Since the service is installed, the removeService command is invoked
    • Running handler command: removeService
    • wrapper | JBoss 4.0.5 (windows-service) removed
  4. Finally, the assertServiceIsNotInstalled command succeeds.
    • end workflow command (1/1) -> "assertServiceIsNotInstalled "


Run Add

Now that we've done automatic deployment, and manual stop and remove of the service, let's do a manual add and start of the service.

The Add command will add the definition of the JBoss server as a Windows Service. This command first checks whether the service is already registered, and if not it runs the addService command.

execute:

ctl -p demo -t JavaServiceWrapper -o windows-service -c Add

output:

Start: "Add the Java Service Wrapper Windows service if it is not already installed." commands: assertServiceIsInstalled
begin workflow command (1/1) -> "assertServiceIsInstalled " ...
wrapper  | The JBoss 4.0.5 (windows-service) Service is not installed.
Exit code = 0
Running handler command: addService
wrapper  | JBoss 4.0.5 (windows-service) installed.
end workflow command (1/1) -> "assertServiceIsInstalled "
[command.timer.demo.JavaServiceWrapper.Add: 3.375 sec]
Workflow completed. execution time: 3.375 sec

What happened?

The Add command invokes service registration sequence for the JavaServiceWrapper:

  1. the assertServiceIsInstalled command is invoked:
    • begin workflow command (1/1) -> "assertServiceIsInstalled " ...
  2. The assertServiceIsInstalled command uses the Tanuki wrapper to check whether the service is registered.
    • wrapper | The JBoss 4.0.5 (windows-service) Service is not installed.
  3. Since the service is not installed, the addService command is invoked
    • Running handler command: addService
    • wrapper | JBoss 4.0.5 (windows-service) installed.
  4. Finally, the assertServiceIsInstalled command succeeds.
    • end workflow command (1/1) -> "assertServiceIsInstalled "


Run Start

The Start command ensures the service is started. When you execute it you should see that it in turn executes the assertServiceIsUp command, which will start the Windows Service for JBoss.

execute:

ctl -p demo -t JavaServiceWrapper -o windows-service -c Start

output:

begin workflow command (1/1) -> "assertServiceIsUp " ...
wrapper  | The JBoss 4.0.5 (windows-service) Service is installed.
wrapper  | Unable to query the configuration of the JBoss 4.0.5 (windows-service) service - Access is denied. (0x5)
wrapper  |   Running: No
Result: 1
Exit code = 1, running bit = 0
Running handler command: startService
wrapper  | Starting the JBoss 4.0.5 (windows-service) service...
wrapper  | JBoss 4.0.5 (windows-service) started.
Started the "jbosswrapper" Windows service.
end workflow command (1/1) -> "assertServiceIsUp "

What happened?

The Stop command invokes the shutdown sequence for the Service:

  1. the assertServiceIsUp command is invoked, which uses the Tanuki wrapper to query the state of the service
    • begin workflow command (1/1) -> "assertServiceIsUp " ...
    • ...
    • wrapper | Running: No
  2. Since the service is not running, the startService command is invoked, which uses the Tanuki wrapper to start the service
    • Running handler command: startService
    • ...
    • wrapper | JBoss 4.0.5 (windows-service) started.
  3. Finally, the assertServiceIsUp succeeds because the startService command succeeded.
    • end workflow command (1/1) -> "assertServiceIsUp "

How it Works

From Workbench's "Service Manager" page you can see the JavaServiceWrapper's resource model in a graphical representation:

Image:windows-service-wrapper-object.png

You can see that the JavaServiceWrapper object has a JavaServiceWrapperZip and a JBossServer object, and a set of configuration Settings.

You can also view the JBossServer object's resource model:

Image:windows-jboss-object.png

It has a JBossZip object, and two Setting resources as child dependencies.

These objects are defined as a resource model in a project XML file generated into the %CTIER_ROOT%\examples\windows-service. directory. This section walks through the XML file used to define the Setting and Service objects.

Examine the contents of this file to see the full resource model definition excerpted below:

%CTIER_ROOT%\examples\windows-service\default-object.xml

The JavaServiceWrapper Setting definitions

The JavaServiceWrapper type defines a number of Setting subtypes which let you customize how the JavaServiceWrapper should control the underlying Java-based software service. In this example we have configured it to work with the JBossServer which will also be described below.

These Settings are defined in the default-object.xml:

Setting Type Purpose Value
JavaServiceWrapperConsoleTitle Console title for service wrapper JBoss 4.0.5 - service wrapper
JavaServiceWrapperNtServiceDescription NT Service description" The Jboss server
JavaServiceWrapperNtServiceDisplayName NT Service display name JBoss 4.0.5 (${entity.name})
JavaServiceWrapperNtServiceName NT Service name jbosswrapper
JavaServiceWrapperJavaMainClass Java Main Class to invoke org.tanukisoftware.wrapper.WrapperSimpleApp
JavaServiceWrapperJavaAdditional Java OPTS to use -server -Dsession.serialization.jboss=true
JavaServiceWrapperAppParameters Wrapper service app parameters org.jboss.Main -c ${entity.name}
JavaServiceWrapperJavaInitMemory JBoss initial memory 64
JavaServiceWrapperJavaMaxMemory JBoss max memory 96
JavaServiceWrapperJavaClassPath JBoss Class path components ${entity.attribute.jboss_install_root}/lib/*.jar,\

${entity.attribute.jboss_install_root}/lib/endorsed/*.jar,\ ${entity.attribute.jboss_install_root}/bin/run.jar

Below is the XML used to define these settings for the JavaServiceWrapper's resource model. The setting tag is used to define each setting and the corresponding script location. Notice that the type= attribute declares the appropriate Setting type, the name attributes all match the name of the Service we will define, and that the settingValue is the full path of the appropriate script for that management task.

<setting type="JavaServiceWrapperConsoleTitle" name="windows-service" 
    description="Console title for service wrapper" 
    settingValue="JBoss 4.0.5 - service wrapper" settingType=""/>
<setting type="JavaServiceWrapperNtServiceDescription" name="windows-service" 
    description="NT Service description" 
    settingValue="The Jboss server" settingType=""/>
<setting type="JavaServiceWrapperNtServiceDisplayName" name="windows-service" 
    description="NT Service display name" 
    settingValue="JBoss 4.0.5 (${entity.name})" settingType=""/>
<setting type="JavaServiceWrapperNtServiceName" name="windows-service" 
    description="NT Service name" 
    settingValue="jbosswrapper" />
<setting type="JavaServiceWrapperJavaMainClass" name="windows-service" 
    description="Java Main Class to invoke" 
    settingValue="org.tanukisoftware.wrapper.WrapperSimpleApp" />
<setting type="JavaServiceWrapperJavaAdditional" name="windows-service" 
    description="Java OPTS to use" 
    settingValue="-server -Dsession.serialization.jboss=true -Djava.naming.provider.url=jnp://localhost:1199" />
<setting type="JavaServiceWrapperAppParameters" name="windows-service"
    description="Wrapper service app parameters"
    settingValue="org.jboss.Main -c ${entity.name}" />
<setting type="JavaServiceWrapperJavaInitMemory" name="windows-service"
    description="JBoss initial memory"
    settingValue="64" />
<setting type="JavaServiceWrapperJavaMaxMemory" name="windows-service"
    description="JBoss max memory"
    settingValue="96" />
<setting type="JavaServiceWrapperJavaClassPath" name="windows-service"
    description="JBoss Class path components"
    settingValue="${entity.attribute.jboss_install_root}/lib/*.jar,${entity.attribute.jboss_install_root}/lib/endorsed/*.jar,\
    ${entity.attribute.jboss_install_root}/bin/run.jar" />

The JBossServer Setting Definitions

The JBossServer type defines its own set of Setting types, which allow you to customize the type. (See JBoss.) In this example, we define only one Setting:

Setting Type Purpose Value
JBossPortConfig Port configuration for JBoss ports-01

This setting configures JBoss to listen on a particular set of ports, in this case ports-01 configures JBoss to use the main HTTP port of "8180".

The JavaServiceWrapper definition

The JavaServiceWrapper is defined by a deployment tag. This element declares the name, type, and some paths (installRoot, basedir). The installRoot and basedir are configured to point to a directory named "install", inside the example folder. This path will be where the JavaServiceWrapperZip software package will be installed (as well as the JBossServerZip as shown later.)

The settings defined above are referenced in the resources element. The Node where this Service is to be deployed is referenced in the referrers element.

The Settings and the Node are reference using a Resource Reference element, which identifies the appropriate object via the name and type attributes.

There are two other entries in the <resources> section, one for the JBossServer object, and one for the JavaServiceWrapperZip. The zip package is used to deploy the Tanuki software package, and the JBossServer is used to reference the install location defined in that service, and so that the JavaServiceWrapper can invoke the installation of the JBossServer.

<deployment 
     type="JavaServiceWrapper"
     name="windows-service" 
     description="Wrapper for the JBoss Server" 
     installRoot="${env.CTIER_ROOT}/examples/windows-service/install" 
     basedir="${env.CTIER_ROOT}/examples/windows-service/install" 
     startuprank="1">

   <resources>
     <!--
      Setting resources
     -->
     <resource name="windows-service" type="JavaServiceWrapperConsoleTitle" />
     <resource name="windows-service" type="JavaServiceWrapperNtServiceDescription" />
     <resource name="windows-service" type="JavaServiceWrapperNtServiceDisplayName" />
     <resource name="windows-service" type="JavaServiceWrapperNtServiceName" />
     <resource name="windows-service" type="JavaServiceWrapperJavaMainClass" />
     <resource name="windows-service" type="JavaServiceWrapperJavaAdditional" />
     <resource name="windows-service" type="JavaServiceWrapperAppParameters" />
     <resource name="windows-service" type="JavaServiceWrapperJavaClassPath" />
     <resource name="windows-service" type="JavaServiceWrapperJavaInitMemory" />
     <resource name="windows-service" type="JavaServiceWrapperJavaMaxMemory" />

  <!-- the JBossServer -->
     <resource type="JBossServer" name="windows-service"/>
     <!--
       include the JavaServiceWrapperZip resource:
     -->
     <resource name="wrapper-windows-x86-32-3.3.3.zip" type="JavaServiceWrapperZip" />
   </resources>

   <!--
 Define a parent dependency to the node where you are running this example. 
   -->
   <referrers replace="false">
     <!--
   Use the default node name defined in defaults.xml
     -->
     <resource type="Node" name="localhost"/>
   </referrers>
</deployment>

JBossServer Definition

The configuration of the JBossServer is fairly simple. For simplicity, this example does not include any form of ear or war deployment, but that could be configured as described in other documents and examples.

The <deployment> element defines the JBossServer's name, description and installRoot and basedir. For JBoss, the installRoot is configured to be the path where the JBossServerZip will be expanded. The basedir is the location of the specific service configuration path, underneath the installRoot, and in this example we name it using the object's name.

The JBossServer has a number of possible Setting subtyes which can be used to configure the JBoss software. In this example we used only one Setting objects as shown in the default-object.xml file, and a single JBossZip subtype to configure the distribution software, which are added in the <resources> section.

In the <referrers> section, the Node to deploy the service is added, as well as the JavaServiceWrapper we have defined earlier.

<deployment 
     type="JBossServer"
     name="windows-service" 
     description="JBoss Server 4.0.5" 
     installRoot="${env.CTIER_ROOT}/examples/windows-service/install/jboss-4.0.5.GA" 
     basedir="${entity.attribute.jboss_install_root}/server/${entity.name}"
     startuprank="1">

   <resources>
     <!--
    Setting resources
     -->
      <resource name="windows-service" type="JBossPortConfig"/>
     <!--
       include the JBossZip resource:
     -->
     <resource name="jboss-4.0.5.GA.zip" type="JBossZip" />
   </resources>

   <!--
 Define a parent dependency to the node where you are running this example. 
   -->
   <referrers replace="false">
     <!--
   Use the default node name defined in defaults.xml
     -->
     <resource type="Node" name="localhost"/>
   </referrers>
</deployment>


Related Topics

Unix Examples:

Personal tools
Development