Deploying to a Business Work Service Container

There are three ‘locations’ or ‘containers’ that a Business Work EAR can be deployed to. These are:

1) Business Work Standalone Service Engine

2) Business Work Service Engine Implementation Type (BWSE-IT) within an ActiveMatrix Node

3) Business Work Service Container (BW-SC)

The first two scenarios do not require any special effort during deployment and usually can be done through the admin interfaces (bw-admin for standalone and amx-admin for BWSE-IT). But if one wishes to deploy an EAR to a Service Container then we need to setup the container and make a change in the Process Archive. This tutorial is for a Windows-based system.

Before we get into all that let us figure out what a BW Service Container (BW-SC) and why one would want to use it.

A BW-SC is a virtual machine which can host multiple processes and services within individual process engines. Each EAR deployed to a BW-SC gets its own process engine. The number of such process engines that can be hosted by a container depends on the running processes and the deployment configurations. To give an analogy, the load that an electric supply (service container) can take depends on not just the number of devices (i.e. process engines) on it but also how electricity each device requires (processes running within each engine).

Keeping in mind the above, when using BW-SC, it becomes even more important to have proper grouping of processes and services within an EAR.

The standard scenario when you would use a BW-SC is for fault-tolerance and load-balancing. In other words, to deploy the same service (fault-tolerance) and required backend processes (load balancing) on multiple containers.  Also Service Containers can be used to group related services together to create a fire-break for a failure-cascade.

The first step to deploying to a BW-SC is to enable the hosting of process engines in a container. The change has to be made in the bwengine.xml file found in the bw/<version>/bin directory. Locate the following entry (or add it if you cannot find it):

<property>
<name>BW Service Container</name>
<option>bw.container.service</option>
<default></default>
<description>Enables BW engine to be hosted within a container</description>
</property>

The second step  is to start a service container to which we can deploy our EARs. Go to the command line and drill down to the  bw/<version>/bin directory. There run the following command:

bwcontainer –deploy <Container Name>

Here the <Container Name> value, supplied by you, will uniquely identify the container when deploying EARs. Make sure  that the container name is recorded properly. In the image below you can see an example of starting a container called Tibco_C1.

Starting Container

 

The third step is to deploy our application to the container (Tibco_C1). Log in to the BusinessWork Administrator and upload the application EAR. In the image below the test application EAR has been uploaded and awaits deployment.

EAR Uploaded

The fourth step is to point the process archive towards the container we want to deploy to. Click on the Process Archive.par and select the ‘Advanced’ tab. Go down the variable list and locate the bw.container.service variable which should be blank if you are already not deploying to a container.

Property Set

Type the container name EXACTLY as it was defined during startup. TIBCO will NOT validate the container name so if you set the wrong name you will NOT get a warning, you will just be left scratching your head as to why it didn’t work. In our example we enter ‘Tibco_C1’ in the box (see below).

  Property Defined

 Save the variable value and click on Deploy. Once the application has been deployed, start the service instance. That is it.

To verify that your application is running on the container, once the service instances enter the ‘Running’ state, go back to the command line and the bin directory containing bwcontainer.exe. There execute the following:

bwcontainer –list

This command will list the process engines running in any active containers on the local machine. The output from our example can be seen below.

Command Line Listing

We can see the process archive we just deployed, running in the Tibco_C1 container.

If you have any other containers they will also show up in the output.

Remember one important point: If a service container goes down, all the deployed applications also go down. These applications have to be re-started manually through the Administrator, after the container has been re-started.

 

Continuing with Java

The continue keyword in the Java programming language provides functionality to skip the current iteration of a loop. Unlike the break keyword which ‘break’ the execution flow out of the loop, continue allows us to skip an iteration. This functionality is often replicated using an if block as below:

for(int i=0;i<100;i++) {
     if(i%2==0){
          // Execute the loop only for even values of i otherwise skip the iteration
      }
}

The above piece of code can be re-written using the continue keyword:

for(int i=0;i<100;i++) {
     if(i%2!=0){ 
          continue; //Skip the loop if i is odd
      }

     //Loop continues as normal if i is even
}

 

While this simple example might not bring out the power of the humble continue keyword, imagine if there were several conditions under which the iteration should be suspended. That would mean having a complicated set of nested if-else blocks to check the flow of execution within the iteration. Whereas with continue we just need to check the condition for skipping the iteration. There is no need for the else part.

Another advantage of using continue  is that it allows the control to be transferred to a labelled statement, as we shall see in a bit.

Before going further let me state the two different ways continue can be used:

Form 1:   continue;

Form 2:   continue <label>;

Example:

The scenario: Imagine you need to extract keywords from a text source. This is a multi-step process with the first step being converting the text into tokens (i.e. breaking down the paragraphs and sentences to individual words based on some rules). Then the set of tokens is filtered and common usage words, such as ‘the’, are removed (stop word removal). Following this you may again want to filter the set using a domain specific set of common use words or you may want to ignore the text source all-together (i.e. not process it) if it has certain words in it. For example if you are interested only in processing articles about Apple products you would want to ignore articles which talk about the fruit.

As you might have guessed, the above process requires several iterations over different sets of data. This is where a continue statement would be most effective. The code given below shows how to use continue. Obviously there are several other ways of implementing the desired functionality (including not using continue).

// Stop and ignore word lists

static String stopWordList[] = { “at”, “in”, “the”, “and”, “if”, “of”,“am”, “who” };

static String ignoreWordList[] = { “king”, “queen” };

——————————

// Sample strings

String samples[] = {“I am the king of the world!”, “For I am the Red Queen”, “A man who wasn’t there” };

outer: for (String sample : samples) {

    System.out.println(“Original String: “ + sample + “\n”);

    // Create tokens

    String[] tokens = tokenize(sample);

    System.out.println(“Unfiltered Tokens:”);

    printToken(tokens);

    // Filter tokens on stop words

   ArrayList<String> filteredTokens = new ArrayList<String>();

    for (String token : tokens) {

        if (filterStopWord(token)) {

           continue; // —————- (1)

       }

        if (filterIgnoreWord(token)) {

        System.out.println(“Ignore – “ + sample + “\n\n”);

          continue outer; // ———- (2)

       }

       filteredTokens.add(token); // — (3)

    }

    // Print filtered tokens
   System.out.println(“Filtered Tokens:”);

   printToken(filteredTokens);

   System.out.println(“\n”);
}// End of outer: for

The full .java file can be found here (right click and save-as).

The logic flow is as follows:

1) Initialise a set of samples (can be any source – taken simple sentences for this example).

2) The for loop labelled ‘outer’ iterates through the set of samples.

3) Create unfiltered token set from the sample.

4) Print the token set (unfiltered).

5) Initialise array list to store the filtered set of tokens.

6) Iterate through the unfiltered token set to filter out tokens.

7) Within the iteration if the current token is a ‘stop word’ then skip the inner loop (using continue – line (1)) as it should not be added to filtered set.

8) If the current token is not a ‘stop word’ then the current iteration will continue as normal.

9) Next we check if the token is on the ‘ignore’ list, if it is then we stop processing the sample and skip the iteration of the outer for loop (using labelled continue – line (2)).

10) If the token is not on the ignore list then we continue with the current iteration and add the token to the filtered set.

If we run the above program with the required methods in place we will see the following output:

Original String: I am the king of the world!
Unfiltered Tokens:
[I]  [am]  [the]  [king]  [of]  [the]  [world!]
Ignore - I am the king of the world!

Original String: For I am the Red Queen
Unfiltered Tokens:
[For]  [I]  [am]  [the]  [Red]  [Queen]
Ignore - For I am the Red Queen

Original String: A man who wasn't there
Unfiltered Tokens:
[A]  [man]  [who]  [wasn't]  [there]
Filtered Tokens:
[A]  [man]  [wasn't]  [there]

As per the logic, the first two samples are ignored and the third one is processed.