Friday, September 25, 2015

jBPM and BPMN 2.0 workflow creation

In my previous post I was describing how to install and run jBPM console.

In this one post, I would like to describe how quickly create a workflow calling a web service.
I will be using a public weather web service based API (OpenWeatherMap) for convenience.

With this restful based API, I can easily query the current weather in a city or a zip code area:,us

I will now start by creating a new project called Meteo via the jBPM KIE console:

This will create a project where you will be able to add business processes and task forms.

Next, I am creating a business process called ObtainWeatherForecast to enter a city or zip code, call the web service and display the corresponding weather forecast:

Automatically, the Process Modelling / Shape Repository panel opens with an initial default Start Event generated.

Two side panes are quite useful to add:

  • On the left the Object library. 
  • On the right side, the Properties of the BPMN diagram elements.You click on the top buttons to show the panes.

First I am going to define a set of variables that will be available in the process to maintain internal values so I can share information between nodes.
For this I click on the background of the business process and edit the Variable Definitions Properties of the ObtainWeatherForecast business process.

In the Process Modelling panel, when you select a node (event or task), you can select some very useful context icons
such as View the BPMN Node Source, create a new task or event, link nodes etc ...

When adding a new task, you have various ways to do this.

If the task is one of the 8 basic Tasks (User, Send, Receive, Manual, Service, Business Rule, Script, None),
then you can either click on the task context icon to create the next task node (as a generic/none type)
from an existing event node or a task node (1a) and specify one of the other 7 basic type if needed using the tool context icon for a more specific one (1b).

You can also use the Object library and drag/drop the task (2) and link the nodes via the link context icon (3).

If you want to add a more specific Service Task (Email, Log, REST, WS), then you can use the Object Library and select the corresponding Service Task (4).

The REST Service task has its Data Input (info associated to RESTful call) and Data Output (result from the call) properties already populated:

For the Data Assignment variables, we are going to set the Method to GET and for a quick hard-coded test,
we are going to set the url to
Then we are going to map the object Result of the call (use [Output Mapping]) to our process variable forecast.
Later we will be able to use the forecast JSON output and extract and display the associated information.

At this point you can add another Script Task for displaying the weather forecast result and complete the business process workflow
with a Terminate End Event, link all nodes and add useful properties such as names.

To deploy your Project and Business Process, select Build & Deploy.

After your project is successfully deployed, you select Deploy|Process Deployments.

You can then see your deployed project with the option to Deactivate it or Undeploy it.

Now you can check the Process Definitions and start ObtainWeatherForecast business process by clicking on the Start button:

After execution of the process, if you look at your Process Variables as part of the process definition, you can obtain the current weather in Paris (JSON returned object):

{"coord":{"lon":2.35,"lat":48.85},"weather":[{"id":803,"main":"Clouds","description":"broken clouds","icon":"04n"}],"base":"cmc stations","main":{"temp":287.89,"pressure":1024,"humidity":67,"temp_min":286.15,"temp_max":289.26},"wind":{"speed":2.6,"deg":20},"clouds":{"all":75},"dt":1443208502,"sys":{"type":1,"id":5615,"message":0.0054,"country":"FR","sunrise":1443159717,"sunset":1443202883},"id":2988507,"name":"Paris","cod":200}

One last tip on this first hands-on experience. If your Project Explorer goes away for some reasons (it seems there is a bug in 6.2.0 final related to this). Try to click on the reset perspective button:

Friday, August 7, 2015

First Steps with jBPM and BPMN 2.0 Modelization Tools

In this post, I would like to share my initial experience with jBPM and BPMN 2.0 modelization tools in general. jBPM is an open-source workflow engine written in Java that can execute business processes described in BPMN 2.0.

Business Process Model and Notation (BPMN) is a graphical representation for specifying business processes in a business process model. As an architect, I have been using BPMN as a language for business process modeling (e.g. for the functional breakdown of complex processing pipelines for genomics systems).

They are different ways to install jBPM. The quickest installations options include:
  1. downloading a zip file and install it on a PC or
  2. downloading and using a docker image (particularly suitable for Mac OS)
In this post, I will describe option #1 (basic zip based install). In this case, what you obtain is a zip file - e.g. - latest version as of 8/7/2015.

  • First make sure you have installed Apache Ant and it is on your Windows Path.
  • To install type the following command at the prompt in the jbpm-installer folder:
    • $ ant install.demo

After few minutes, all dependencies are fully downloaded and jBPM is installed.

     You are now ready to start the web-based Knowledge Is Everything KIE workbench (there is also an Eclipse IDE plugin available with the download that you can use).
  • $ ant start.demo
  • Alternatively you can also download and start the demo without eclipse
    • $ ant install.demo.noeclipse
    • $ ant start.demo.noeclipse

    Issues deploying jbpm-console.war
  • if jbpm-console.war cannot be deployed in JBoss wildfly application server (former JBoss AS).
  • see folder: ...\jBPM\jbpm-installer\wildfly-8.1.0.Final\standalone\deployments 
  • and check log file: ...\jBPM\jbpm-installer\wildfly-8.1.0.Final\standalone\log\server.log
  • You might have encounter an issue with your proxy!!!
  • There are several ways to fix this, including 
    • installing KIE outside your firewall/proxy server influence (not from our office!)
    • modify your file ...\jBPM\jbpm-installer\build.xml file:
                 <exec executable="${}" spawn="yes" osfamily="windows">
                      <env key="JAVA_OPTS" value="-XX:MaxPermSize=256m -Xms256m -Xmx512m" />
                      <arg value="-b" />
                      <arg value="${jboss.bind.address}" />
                      <arg value="--server-config=standalone-full.xml" />
                      <arg value="-Dorg.kie.demo=true" />
                      <arg value="-Dorg.kie.example=false" />
                      <arg value="-Dhttp.proxyHost=...." />
                      <arg value="-Dhttp.proxyPort=8999" />
                      <arg value="c standalone-full.xml"/>

     Using KIE
  •  If successfully deployed, go to your browser (use Chrome for better experience!) and enter
    • http://localhost:8080/jbpm-console/kie-wb.html
     You should have access to the jBPM KIE console (see also video demo here and look at jBPM6 Developer Guide).


      The default user name and password are 'admin'.


To have access to the business process demos click Authoring/Project and choose async-examples.

Then Business Processes/check weather (one of the demos - this one is very simple and fun!).

 This displays a very simple business process where the user can enter a zip code and obtain the weather forecast associated to the zip code in question:

Open the properties pane  if not displayed by clicking the double arrow on the top right side of the application.

You can initially do a copy of the demo in case you want to make some modifications to the demo process. You will need to modify the ID and the Version of the business process and save a copy.

Enter a new name and optionally some comments for the new version of the process:

    The copy should now appear in the list of business processes:

Deployment of a Process is done by opening the Project and select Build/Build & Deploy:

 To run the demo process, select Process Management/Process Definitions then select your process and click on the start Action icon:


  Enter the user name ('admin') and a US zip code - Here I am using 94036 (Palo Alto, CA).

Thursday, April 2, 2015

Migrating Healthcare Applications to the Cloud through Containerization and Service Brokering

Organizations that are building their own cloud infrastructure from scratch or rely uniquely only on an infrastructure as a service (IaaS) from a provider, risk spending valuable resources and time building a specialized platform instead of focusing on their core business. On the other hand, organizations who adopt a turnkey proprietary cloud stack will lack flexibility and may end up locked into a specific technology or vendor.

Instead of designing the cloud architecture from the bottom up or the top down, a better strategy is to design from the inside out. By starting with the platform as a service (PaaS) as the central critical layer and creating ways to use various IaaS models and offerings in generic ways, it is possible to create a flexible and efficient lifecycle for the services and applications running on the platform.

In Healthcare, PaaS technology such as the one offered by Pivotal Cloud Foundry facilitates the rapid creation and migration of existing applications towards better user engagement, increasing collaboration between care givers and improving the lives of patients, while reducing the total cost of ownership (TCO).

The main characteristics of this platform are:
  • Application containerization
  • Optimized application scaling
  • Application to service brokering
  • Abstraction of IaaS
  • Excellent application lifecycle management
  • Automatic middleware stack and operating system configuration
  • Advanced application monitoring

In this architecture, backing services (e.g., databases, caching systems, other data services (e.g., Amazon S3), messaging/queueing systems, SMTP services, various external APIs (Google Maps, terminology services, healthcare registry services) are just attached resources. For example, there is a distinction between a local digital imaging and communications in medicine (DICOM) local image store and a remote, 3rd party DICOM picture archiving and communication system (PACS) service hosted in the cloud.

The type of platform is especially suitable managing micro services, which allows better componentization, development and testing processes, decentralized governance, resilience and maintainability. These services, especially when they are based on a RESTful architecture, are extremely easy to build, integrate, test, extend, and maintain, and are extremely adapted for mobile applications integration.

Good and efficient lifecycle management is important to produce and maintain high quality software. This is particularly important in healthcare where the patient life is at risk or a breach of privacy could occur as a result of poor quality software.

The advantage of abstracting the IaaS layer access through a common API is that there no need to have multiple versions of application code for each deployment model. The same code will work and be monitored the same way for all cloud deployment models, including on premise and hybrid.

On top of the generic open PaaS infrastructure, we are adding generic and cross-cutting capabilities not part of the original platform including:
  • Identity management to allow customers, patients and consumers to be accurately and uniquely recognized by using an enterprise master patient index (eMPI) for patients and a lightweight directory access protocol (LDAP) based directory for healthcare providers and consumers.
  • Security/Identity Access Management: authentication, authorization, and single sign-on, all critical to secure provider, patient, and consumer applications and in certain cases, can be addressed by declarative proxification of these services.
  • Cloud-based, connected device management: device registration, discovery, routing, diagnostics, remote control, firmware provisioning, data collection, device-app-user pairing (we are currently supporting 6 million active consumer devices).
  • Open cloud based clinical workflow collaboration capabilities.
  • Secure cloud-based big data store and analytics capability (e.g., to store patient’s observations and genomic data.


We are also creating and exposing healthcare and wellness related services that applications can consume:

Our HealthSuite Digital platform also offers high availability, scalability, privacy and security compliance with regulations (e.g., HIPAA, HITECH) and standards (e.g., NIST SP800-53, ISO 27001) using multitenancy, redundancy, 24/7 monitoring and operations, and disaster recovery.

   More on:  F. Andry, R. Ridolfo, J. Huffman, Migrating Healthcare Applications to the Cloud through Containerization and Service Brokering, 8th International Conference on Health Informatics (HealthINF 2015), pp. 164-171, Lisbon, Portugal, January 2015.

Thursday, June 6, 2013

Java Code Refactoring

I recently browsed again the excellent book Code Complete from Steve McConnell while in the middle of several Java code reviews. Although the book is nor specifically dedicated to Java code, I still found it quite useful and inspiring.

The chapter on refactoring in particular offers a very practical perspective that all programmer should have in mind when it comes to infuse a dose of evolution in the life cycle of their software.

What I found particularly valuable are the checklists that the author has put together: reasons to refactor, specific re-factorings (data level, statement level, routine-level, class-implementation, class-interface, system-level), refactoring safely, strategies, summary.

In this post, I would like to illustrate some of these refactoring techniques with java code snippets.

Since I do not have time to comment every item in these checklists, I decided to pick-up those that are not trivial or obvious and might bring the best return on your refactoring investment. These items are high-lighted in green and developed in sections at the end of this article.

If you think that missing items are worth explaining, please add a comment to this post and I will be glad to add a specific paragraph for those as well.

Checklist: Reasons to Refactor

  • Code is duplicate
  • A routine is too long
  • A loop is too long or too deeply nested
  • A class/interface/method has poor cohesion
  • A class interface does not provide a consistent level of abstraction
  • A parameter list has too many parameters
  • Changes within a class tend to be compartmentalized
  • Changes require parallel modifications to multiple classes
  • Inheritance hierarchies have to be modified in parallel
  • Related data items that are used together are not organized into classes
  • A routine uses more features of another class than of its own class
  • A primitive data type is overloaded
  • A class doesn't do very much
  • A chain of routines passes tramp data
  • A middle man object isn't doing anything
  • One class is overly intimate with another
  • A routine has a poor name
  • Data members are public
  • A subclass uses only a small percentage of its parents' routines
  • Comments are used to explain difficult code
  • Global variables are used
  • A routine uses setup code before a routine call or takedown code after a routine call
  • A program contains code that seems like it might be needed someday

 Checklist: Summary of Refactorings

Data Level Refactoring
  • Replace a magic number with a named constant
  • Rename a variable with a clearer or more informative name
  • Move an expression inline
  • Replace an expression with a routine
  • Introduce an intermediate variable
  • Convert a multi-use variable to a multiple single-use variables
  • Use a local variable for local purposes rather than a parameter
  • Convert a data primitive to a class
  • Convert a set of type codes to a class
  • Convert a set of type codes to a class with subclasses
  • Change an array to an object
  • Encapsulate a collection
  • Replace a traditional record with a data class
Statement Level Refactorings
  • Decompose a boolean expression
  • Move a complex boolean expression into a well-named boolean function
  • Consolidate fragments that are duplicated within different parts of a conditional
  • Use break or return instead of a loop control variable
  • Return as soon as you know the answer instead of assigning a return value within nested if-then-else statements
  • Replace conditionals with polymorphism (especially repeated case statements)
  • Create and use null objects instead of testing for null values
Routine Level Refactorings
  • Extract a routine
  • Move a routine's code inline
  • Convert a long routine to a class
  • Substitute a simple algorithm for a complex algorithm
  • Add a parameter
  • Remove a parameter
  • Separate query operations from modification operations
  • Combine similar routines by parameterizing them
  • Separate routines whose behavior depends on parameters passed in
  • Pass a whole object rather than specific fields
  • Pass specific fields rather than a whole object
  • Encapsulate downcasting ⇐ 

Class Implementation Refactorings
  • Change value objects to reference objects
  • Change reference objects to value objects
  • Replace virtual routines with data initialization
  • Change member routine or data placement
  • Extract specialized code into a subclass
  • Combine similar code into a superclass
Class Interface Refactorings
  • Move a routine to another class
  • Convert one class to two
  • Eliminate a class
  • Hide a delegate
  • Replace inheritance with delegation
  • Replace delegation with inheritance
  • Remove a middle man
  • Introduce a foreign routine
  • Introduce a class extension
  • Encapsulate an exposed member variable
  • Remove Set() routines for fields that cannot be changed
  • Hide routines that are not intended to be used outside the class
  • Encapsulate unused routines
  • Collapse a superclass and subclass if their implementations are very similar
System Level Refactorings
  • Duplicate data you can't control
  • Change unidirectional class association to bidirectional class association
  • Change bidirectional class association to unidirectional class association
  • Provide a factory routine rather than a simple constructor
  • Replace error codes with exceptions or vice versa

Selected items refactoring samples in java

  • A class/interface/method has poor cohesion
    • A class, interface or method should be only responsible for a precise and meaningful set of functionality and behavior. For example,the interface KitchenAppliance below lacks cohesion. A generic kitchen appliance should not allow to wash both clothes and dishes.
      public interface KitchenAppliance {
       public float waterConsumption = 0;
       public float energyConsumption = 0;
       void washClothes();
       void washDishes();


      public interface WashingKitchenAppliance {
       public float waterConsumption = 0;
       public float energyConsumption = 0;
       void wash();
  • A class interface does not provide a consistent level of abstraction
    •  In Java, a consistent level of abstraction is usually obtained when the objects that represent abstract actors perform work, report on, change their state and communicate with other java objects in a a compatible and comparable way.
      The use of inheritance, encapsulation and polymorphism is usually the key to a consistent level of abstraction and is at the core of good design patterns. In the example below, an intermediary level of abstraction, e.g. DairyAnimal (cows, goats) and MeatAnimal (pigs, steers), could be created to avoid  specifying the type of food for each animal and focus on more specific features for the sub-classes.
      public class Animal extends LivingThing
       private Location loc;
       private double energyReserves;
       public boolean isHungry() {
        return energyReserves < 2.5;
       public void eat(Food food) {
        energyReserves += food.getCalories();
       public void moveTo(Location location) {
        this.loc = location;
      thePig = new Animal();
      theCow = new Animal();
      if (thePig.isHungry()) {
      if (theCow.isHungry()) {

      public class DairyAnimal extends Animal {
       private Double milkProduction;
       public Double getMilkProduction() {
        return milkProduction;
  • A parameter list has too many parameters
    • Methods with too many parameters is an indication that the code has either been badly designed initially (lack of abstraction) or has evolved over the months or years without proper refactoring. One elegant solution for creational methods/constructor requiring a large number of parameters is to use a builder pattern well define in Joshua Bloch's Effective Java and offers a way to use optional parameters:
      public NutritionFacts(int servingSize, int servings, int sodium, int iron, int fat, int carbs) {
           this.servingSize = servingSize;
           this.sodium = sodium;
           this.servingSize = servingSize;
           this.iron = iron;
           this.fat = fat;
           this.carbs = carbs;
      NutritionFacts soda = new NutritionFacts(240, 8, 35, 13, 0, 27);

      public class NutritionFacts {
       private int servingSize = 0;
       private int servings  = 0;
       private int sodium  = 0;
       private int iron  = 0;
       private int fat  = 0;
       private int carbs  = 0;
       public static class Builder {
        private int servingSize;
        private int servings;
        private int sodium;
        private int iron;
        private int fat;
        private int carbs;
        public Builder(int servingSize, int servings) {
         this.servingSize = servingSize;
         this.servings = servings;
        public Builder sodium(int val) {
         this.sodium = val;
         return this;
        public Builder iron(int val) {
         this.iron = val;
         return this;
        public Builder fat(int val) {
         this.fat = val;
         return this;
        public Builder carbs(int val) {
         this.carbs = val;
         return this;
        public NutritionFacts build() {
         return new NutritionFacts(this);
       private NutritionFacts(Builder builder) {
        servingSize = builder.servingSize;
        servings = builder.servings;
        sodium = builder.sodium;
        iron = builder.iron;
        fat = builder.fat;
        carbs = builder.carbs;
      NutritionFacts soda = new NutritionFacts(240, 8).build();
      NutritionFacts soda = new NutritionFacts(240, 8).sodium(35).iron(13).fat(0).carbs(27).build();
      NutritionFacts soda = new NutritionFacts(240, 8).sodium(35).iron(13).carbs(27).build();
  • Changes require parallel modifications to multiple classes
    • If you regularly have to modify the same set of classes then try to refactor these classes with the correct level of abstraction and factorization so changes only affect one class.
  • Related data items that are used together are not organized into classes
    • Recurrent set of operations can be combined in its own class:
    • theCow = new DairyAnimal();

      public class DairyAnimalOperation {
       public void tend(DairyAnimal dairyAnimal) {
      Even better, refactoring can include the use of a flexible strategy pattern, if the recurrent process needs to be dynamically.
  • A chain of routines passes tramp data
    • "Tramp data" refers to passing data to one method so it can be passed to another one (Page-Jones 1988). This can be solved by introducing a better level of abstraction in the interfaces in question
  • Replace a magic number with a named constant
    • The word magic refers to the use of numeric or string literal. Use constants or Enums instead.
    • public double areaOfCircle (double radius)  {  
          return Math.pow(radius * 3.14159, 2);  

      private static final double PI = 3.14159;
      public double areaOfCircle (double radius)  {  
          return Math.pow(radius * PI, 2);  
  • Convert a multi-use variable to a multiple single-use variables
    • Common offenders are variable names like i,j, temp. These need to be replaced by specific names (e.g. row, column).
    • for (int i=0;i&tl;N;i++) {
          for (int j=0;j&tl;M;j++) {
             matrix[i][j] = 0; 

      for (int row=0;row&tl;numRows;row++) {
          for (int colum=0;colum&tl;numColumns;colum++) {
              matrix[row][colum] = 0; 
  • Encapsulate a collection
    • Instead of returning the collection itself, encapsulate a read-only collection instance with specific methods to add or remove elements in the original collection. You can leverage unmodifiable view methods that are part of the collection class for this:
    • public static <T> Collection<T> unmodifiableCollection(Collection<? extends T> c)
      public static <T> Set<T> unmodifiableSet(Set<? extends T> s)
      public static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s)
      public static <T> List<T> unmodifiableList(List<? extends T> list)
      public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m)
      public static <K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K,? extends V> m)
  • Replace conditionals with polymorphism
    • With polymorphism, subclasses of a class possesses their own specific behaviors and share also some of the functionality of their parent class. Refactor conditionals, especially complex case statements with polymorphism design:
    • Bike myBike = new Bike();
      String bikeType = "default";
      witch(myBike.getTireWidth()) {
       case 23 : 
        if (myBike.getSuspension().compareToIgnoreCase("Simple") == 0) {
         bikeType = "Road bike";
       default : 
        if (myBike.getSuspension().compareToIgnoreCase("Dual") == 0) {
         bikeType = "Mountain bike";


      public class MountainBike extends Bicycle {
          private String suspension;
          public MountainBike(
                     int startCadence,
                     int startSpeed,
                     int startGear,
                     String suspensionType){
          public String getSuspension(){
            return this.suspension;
          public void setSuspension(String suspensionType) {
              this.suspension = suspensionType;
      public class RoadBike extends Bicycle{
          private int tireWidth;
          public RoadBike(int startCadence,
                          int startSpeed,
                          int startGear,
                          int newTireWidth){
          public int getTireWidth(){
            return this.tireWidth;
          public void setTireWidth(int newTireWidth){
              this.tireWidth = newTireWidth;
  • Separate routines whose behavior depends on parameters passed in
    •  If you have a method which executes different statements based on a particular parameter value, figure out if you can break the method into separate ones without passing the parameter in question.
  • Encapsulate downcasting
    • Objects returned by a method should use the most specific type possible. 
    • public class A {
       public String doSomething() {
        return "Do something.";
      public class B extends A {
       public String doSomethingMoreSpecific() {
        return "Do something more specific.";
      public class DownCast {
       private List<A> list;
       public List<A> getList() {
        return list;
       public List<B> getMostSpecificList() {
        return (List<B>) (List<?>) list;
       public void setList(List<A> list) {
        this.list = list;
       public DownCast() {
        list = new ArrayList<A>();
        for (int i=0;i<10;i++) {
         list.add(new B());
      public static void main(String[] args) {
       DownCast obj = new DownCast();
       List<A> listOfA = obj.getList();
       List<B> listOfB = obj.getMostSpecificList();
  •  Extract specialized code into a subclass
    • Refactor specialized code into specific own subclasses if the code in question is only used in a subset of initial classes.
  •  Hide a delegate
    •  If Class A calls B then C while A was supposed to only call B and B calls C, then dissociates C from A and have B calls C only.
  •  Remove a middle man
    • On the other hand, if you think that A should call C directly as long as the role of B is still clearly defines, does not have overlap with C and can be used independently of C.
  •  Encapsulate unused methods
    • Create new interfaces for the most common used set of methods
    • public class Bird {
       private String species;
       private String eggColor;
       private String food;
       private int flySpeed;
       private int flyHeight;
       private String dragType;
       private String wingType;
       public String getSpecies() {
        return species;
       public void setSpecies(String species) {
        this.species = species;
       public String getEggColor() {
        return eggColor;
       public void setEggColor(String eggColor) {
        this.eggColor = eggColor;
       public String getFood() {
        return food;
       public void setFood(String food) { = food;
       public int getFlySpeed() {
        return flySpeed;
       public void setFlySpeed(int flySpeed) {
        this.flySpeed = flySpeed;


      public interface BirdFlight {
       public int getFlySpeed();
       public void setFlySpeed(int flySpeed);
       public int getFlyHeight();
       public void setFlyHeight(int flyHeight);
       public String getDragType();
       public void setDragType(String dragType);
       public String getWingType() ;
       public void setWingType(String wingType);
      public class Bird implements BirdFlight {
       private String species;
       private String eggColor;
       private String food;
       public String getSpecies() {
        return species;
       public void setSpecies(String species) {
        this.species = species;
       public String getEggColor() {
        return eggColor;
       public void setEggColor(String eggColor) {
        this.eggColor = eggColor;
       public String getFood() {
        return food;
       public void setFood(String food) { = food;
       public int getFlySpeed() {
       public void setFlySpeed(int flySpeed) {
       public int getFlyHeight() {
       public void setFlyHeight(int flyHeight) {
  •  Duplicate data you can't control
    • As long as layering principles are not violated, wrap or access data maintain by the system via a consistent way/interface/API. A typical examples is data shares in GUI control in the front-end layer. Try to find a way to copy/mirror the data in question and treat it as reference source of data.

Friday, May 17, 2013

Advanced UML Sequence Diagrams

A Sequence Diagram is a type of UML Interaction Diagram that is used to model objects that need to pass messages to accomplish a task.

The messages are usually defined in the order of the execution.

Objects interactions can include:
  • creation and termination
  • requests
  • invoke object operations
  • notifications
In the very simple sequence diagram below, a user sends a query to a health IT application that retrieve a clinical document to an XDS Repository. The clinical data is returned back to the user (an actor in this type of diagram).

Object colors can indicates a different scope between objects (e.g gray here indicate a component that is part of a different sub-system, or out-of-scope for the current document or release etc).

Lifelines are vertical dashed lines with the object positioned at the top.  

Messages are horizontal lines with arrows pointing in the direction in which the message is sent with annotation (method, parameters, arguments, return value, type of control flow etc ...)

UML 2.0 has two forms of messages:
  • operation call : the invocation of an operation of a receiving object (either synchronous or asynchronous)
  • signal : a message object sen out by one object and handle by another one (always asynchronous)

Synchronous messages usually have solid arrows (by the way, in the tool I use, return synchronous messages for not have a solid arrow). Asynchronous message use dashed arrows.

An interaction operand is a container that groups the interaction fragments and uses an optional guard expression or interaction constraint. When the guard condition is not present, the interaction is always executed.

Interaction operators include:
  • Alternative (alt) 
  • Option (opt) : 
  • Break (break) :
  • Parallel (par)
  • Loop (loop)  
  • Critical (critical) or (region)
  • Negative (neg)
  • Assertion (assert)
  • Strict Sequence (strict)
  • Weak Sequence (seq)
  • Ignore (ignore)
  • Consider (consider)
Lets consider a simple alternative (alt) operand.

Imagine that in the initial sequence diagram, that we want to request a document, we request a clinical document from an external source (CCD producer system).

In this case, the first thing is to add a combined fragment on top of the existing diagram, and choose the alt type:

Then conditions are added (if and else equivalent):

Then you can add the new alternative message (to the external CCD producer system) and re-organize the layout of the diagram : placing the combined fragment below the incoming message and moving the else clause separation (dotted line) below the first alternative (accessing the XDS repository). In my tool, you can use ALT-Left-Mouse click for this:

There are numerous UML modeling tools available (commercial or free). For his post, I used Enterprise Architect.