Wednesday, November 15, 2006

Project Collaboration with Basecamp

Recently we started a small project and decided to try Basecamp, a collaboration tools from 37signals, authors of the famous Ruby on Rails framework.

Basecamp is a unique project collaboration tool. Projects don't fail from a lack of charts, graphs, or reports, they fail from a lack of communication and collaboration. Basecamp makes it simple to communicate and collaborate on projects.

Give this web application a try, it is really smart: it allows you to be productive in few minutes and incredibly facilitates teams collaboration. Each single operation is clean , simple and intuitive, making a wise use of Ajax widgets. We are testing the free edition, which comes with some limitations but it is good enough to start. Then it is possible to upgrade to a professional edition if you realize you need more horse-power. However, pricing looks very competitive.

Wednesday, November 8, 2006

JMS topics and message selectors in CAPS

A topic is a JMS message destination that conforms to the publish-and-subscribe messaging paradigm. In this tiny example I show how to publish a message to a topic in Java CAPS, using message selectors to filter message destinations.

Publisher JCD
This JCD (Java Collaboration Definition in CAPS idiom) is triggered by a File eWay and publishes a JMS text message to a topic

public class jcdPublisher
{

public com.stc.codegen.logger.Logger logger;

public com.stc.codegen.alerter.Alerter alerter;

public com.stc.codegen.util.CollaborationContext collabContext;

public com.stc.codegen.util.TypeConverter typeConverter;

public void receive( com.stc.connector.appconn.file.FileTextMessage input, com.stc.connectors.jms.JMS JMS_1 )
throws Throwable
{
String content = input.getText();
com.stc.connectors.jms.Message msg = JMS_1.createTextMessage();
msg.storeUserProperty( "dest", content );
msg.setTextMessage( content );
JMS_1.send( msg );
}

}

the line
msg.storeUserProperty( "dest", content );
stores the user property that will be used later by message selectors to filter messages.

Consumer JCD
This JCD simply receives a text message from the JMS source (a topic, but it is not specified here but in the Connectivity Map) and writes it to a local file using the File eWay

public class jcdConsumer {

public com.stc.codegen.logger.Logger logger;

public com.stc.codegen.alerter.Alerter alerter;

public com.stc.codegen.util.CollaborationContext collabContext;

public com.stc.codegen.util.TypeConverter typeConverter;

public void receive(com.stc.connectors.jms.Message input,
com.stc.connector.appconn.file.FileApplication FileClient_1)
throws Throwable {
FileClient_1.setText(input.getTextMessage());
FileClient_1.write();
}

}

Connectivity Map
In the connectivity map there are four services:
* svcPublisher contains an instance of jcdPublisher
* svcConsumer1, svcConsumer2 and svcDefaultConsumer all contain a copy of jcdConsumer



svcPublisher receives a file content from FileIn (File eWay instance) and publish it into tpcPublic topic. the three consumers receives messages after they are selected by message selectors.
In this toy example the input text file which triggers the process contains just a list of numbers:

4
1
2
2
1
2
3
1

message selectors are built so that they filter messages using the "dest" user property

Message Selectors
svcConsumer1 consumes only messages with an user property dest='1'



svcConsumer2 consumes only messages with an user property dest='2'



svcDefaultConsumer consumes only messages with the 'dest' user property that is neither '1' nor '2', so it can be expressed as
NOT (dest='1' OR dest='2')




Deployment Profile
The DP maps project components present in a Connectivity Map to a given Environment



Results
Results are written in three distinct files: output1.txt (it will contains only '1'), output2.txt ('2') and outputDef.txt (contains all the other numbers that are not '1' or '2', present in input.txt)

Conclusions
What happens if one of the Connectivity Maps link does not contain any message selector? The obvious response is that the connected consumer would receive *all* the messages, regardless of the user property stored into the message header.

Java CAPS - eInsight Business Processes Correlation HowTo

The Java Composite Application Platform Suite

The Java Composite Application Platform Suite (Java CAPS) allows companies to assemble large-scale applications built on existing systems and infrastructure. Java CAPS is an application-level network that unifies connectivity among people, application systems, and devices in different locations and across organizations. Business services facilitate the implementation of extended applications. Service oriented architectures (SOA) clarify design and enable reuse by sharing logic and data among different client systems and users.

eInsight and Java CAPS

eInsight is a component of Java CAPS. eInsight delivers Business Process management features and functions to Java CAPS. Business Process management is a strategic orchestration of the movement of information and the flow of complex processes between participants (systems, users, and organizations) to accomplish larger business objectives. eInsight uses the standard BPEL language to describe processes

1 Introduction

eInsight provides the means for matching existing Business Process instances to messages that are arriving into a Business Process. Correlation keys are individual data values contained within both the incoming message and the eInsight engine. When arriving messages contain data that matches the configured correlation keys, unique Business Process instances then continue processing on to the next step of a given Business Process.

2 Message Correlations

A correlation key is a value that you can assign to a Business Process, like a Purchase Order number. The correlation key provides a way to associate and route information about specific Business Process instances. For asynchronous message exchange between components, you must implement correlation of the instance identification.

An example of when you use asynchronous message exchanges is when you create a Receive Activity in the middle of a Business Process.

To have the correlation mechanisms working properly, right correlation keys are mandatory.

3 Example 1 - File trigger

In this scenario we have a calling process that sends a JMS message to another process and then waits for a reply, correlating instances through a unique ID.

Invoked Process - bpReplier

The bpReplier process is called from the main one. It is very simple for this example: it just copies the Jms Correlation ID and adds some information in the text field.



Main Process

The main process reads a correlation ID from a file, set it into the CorrelationID field of JMS->MessageProperties and then sends the message to the above mentioned bpReplier. An “Event Based Decision” waits for events: one it is a JMS.receive, second is a “Timer Event” in case nothing is received within a fixed amount of time.



Correlation key

The correlation key is made of two aliases:
* /Message/MessageProperties/CorrelationID
* /FileTextMessage/text


The correlation is used in two activities in the BP:
1 - FileClient.receive - with Initialize Set ='yes'
2 - JMS.receive (in the event based decision) - with Initialize Set='No'

4 Example 2 - JMS trigger

The second example shows how to use correlation in a process triggered by a JMS message instead of a file. The invoked service remains the previous simple "bpReplier", while the main process is slightly different.

Main Process

In this case the main process is split in two: first the trigger, which reads from a file and uses its internal BPID as the CorrelationID for the JMS message:

Second, the “real” main process:

This receives the above message, initializes the correlation key, send a message to the bpReplier (copying the received CorrelationID) and the waits for an event. The JMS.receive, which uses the correlation key but does not initialize it, in the event based decision correlates inbound messages, while the usual Timer Event would raise a timeout in case of long inactivity.

In this case, as we only have one kind of inbound event (a JMS message is received) the only necessary alias for the correlation key is:
/Message/MessageProperties/CorrelationID

Resources

* Sun Java CAPS public forum
* Product's official documentation

Sunday, November 5, 2006

Singleton pattern and Double-Checked Locking problem

Double-Checked Locking is widely cited and used as an efficient method for implementing lazy initialization in a multithreaded environment.
Unfortunately, it will not work reliably in a platform independent way when implemented in Java [...]
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

All programming languages have their share of idioms. Many are useful to know and use, and programmers spend valuable time creating, learning, and implementing them. The problem is that some idioms are later proven not to be all that they were purported, or to simply not work as described. The Java programming language contains several useful programming idioms. It also contains some that further study has shown should not be used. Double-checked locking is one such idiom that should never be used. In this article, Peter Haggar examines the roots of the double-checked locking idiom, why it was developed, and why it doesn't work.
http://www-128.ibm.com/developerworks/java/library/j-dcl.html


I think the problem with DCL comes from checking the wrong variable. Instead of checking the static instance itself one should check a boolean, which is by nature an atomic operation. This would prevent the mentioned JVM memory model "problem". What do you think?



public class Singleton {

private static Singleton _instance = null;
private static boolean _initialized = false;

private Singleton() {
}

public static Singleton getInstance() {
if (!_initialized) {
synchronized (Singleton.class) {
if (!_initialized) {
_instance = new Singleton();
_initialized = true;
}
}
}
return _instance;
}

}