Archive for the ‘MDA’ Category.

Super Size EMF Fast Food Demo: Add Complex Event Processing (Part 2)

Where were we?

In the last post we considered the problem of the Integrated fast food management. In step 1, we designed the models and in step 2 we weaved them. As a result the application were developed just by weaving live-models. We finished the last post by asking ourselves how could we answer the Fast Food manager’s issues:  the boss wanted to control the burger cooking rate according to current demand. In addition, soon, he will ask to include other contextual parameters, such as the number of available seats, or the location of the truck which delivers salads and burgers.  How could we define a flexible, maintainable, and intelligent system? We proposed to use CEP concepts.

What the hell is the CEP?

CEP stands for Complex Event Processing, I will let you read the really good introduction given by Tim Bass from TIBCO in [1], then  browse [2,3] to get a good idea of what it can bring. Basically, the idea is that we can perceive the real-time current state of the world by listening all the events the world emits.  For instance, we could improve the airport schedule by taking into account in real time and in each airport: the petrol delivery, the existing delays, the weather forecast, information from airlines companies, etc. All those systems emit events, if we could collect all of them in a central backbone, we could process this “cloud of events” in order to recognize patterns. Once a pattern is recognized, it means that a particular situation has been achieved, and then, we can take action. That is an Event-Driven Architecture (EDA). Formal definition: “Complex Event Processing is the subject of processing data in an event-driven application. The idea is to have a central processor, the CEP engine, which will be given the task to handle every occurring event of the system in order to have a better view of that system, which in turn, takes actions. It is called complex because it’s purpose is to be able to recognize complicated patterns among events and correlate them in order to infer new knowledge. Any kind of relations between events could be used, in particular temporal relationships. Due to the goal of being able to take action, CEP are meant to process and analyse data in real-time. In order to ease the creation of such processors, CEP engines have emerged as to provide an efficient way of developing and deploying applications requiring complex event processing”.

Where are you going? Starting with live-models is OK, but what the hell is the point with CEP?

Well, we were asking ourselves how we could bring intelligence on our application. Actually the CEP paradigm is an elegant solution and suits well. Indeed, the weaver enables to listen model changes, let’s then sending all modification events on a collector. Therefore, we only need to analyze all of them and recognize some patterns such as “more than 3 burgers has been ordered within 2 mins”. That is a new paradigm in live-models, by the notification system of the weaver we are able to take decisions according to contextual information, in this case, the model states.

Step 3: Collecting Events

OK, so, the next step is then to collect events. The collector could be a simple pipe, list or something more complex such as Enterprise Service Bus, JMS queue, etc. In our case, let’s use directly the CEP flow entry without using any median such as a queue.

Collecting modification event in a collector
Collecting modification event in a collector

The aim of the event collector is to collect all modification events from Orders. Notice that later on, we can add any other events which could give us a better view of the real time context.

Step 4: Inferring information from real-time data (the context)

The last step is to put in place a CEP which will analyze all notification events from Orders. In our case , when a notification about a burger arrives, we will have to check if we have received more than 3 burgers within the 2 mins. Then, we need to select all events received within this time frame and counting each quantity ordered for each event.

 #Pattern definition select irstream sum(quantity) as totalQuantity from OrderBurgerEvent(type='superburger').win:time(2 min) having sum(quantity) > 3 

This rule is a pattern definition in ESPER, the open source CEP. Therefore, we are able to listen the event cloud and to infer that “the conditions are met” for increasing the burger rate.

Where are the snippets?

Oh, yes, we lack of code here ! So, let’s code all those things.

Weaving Order and Bill

First of all we need to see how we can weave the bill and order. Each time a new order is created, we create the corresponding Bill and we weave them each other. This means that the attribute burgerPriceTotal must be calculated each time an OrderEntry is added or removed from an Order. Therefore, we need a Weaving Process which listens to ADDED and REMOVED events of the burgerEntries Collection of the Order Object. Let’s see some code:

//Creatiion of Order
Order order = BurgerFactory.eInstance().createOrder();
Bill bill = BurgerFactory.eInstance().createBill();

// create one event for each case : add and remove in burgerEntries
ChangedEvent addEvent = ProcessFactory.eINSTANCE.createChangedEvent();
addEvent.setPath("burgerEntries");
addEvent.setEventType(EventType.ADD);
ChangedEvent removeEvent = ProcessFactory.eINSTANCE.createChangedEvent();
removeEvent.setPath("burgerEntries");
removeEvent.setEventType(EventType.REMOVE);

// create the activity processed by the event
command.setcommand ("platform:/plugin/burgerFactory/org.euranova.burgerfactory.handlers.ReCalculateBurgerPriceActivity");
//Reference the Bill model that will be used in runtime
command.getParameterLocations ().put (Bill.class, bill);

// attach activity to event through sequence flows
SequenceFlow sequence = ProcessFactory.eINSTANCE.createSequenceFlow();
sequence.setSource(addEvent);
sequence.setTarget(command);
sequence.setSource(removeEvent);
sequence.setTarget(command);

// create the process
WeavingProcess wp = ProcessFactory.eINSTANCE.createBindingProcess();
wp.getElements().add(addEvent);
wp.getElements().add(removeEvent);
wp.getElements().add(command);
wp.getElements().add(sequence);

// create a weaver and activate it
Weaver w = new Weaver();
w.getProcesses().add(wp);
// set the model on which we attach the weaving process
w.getModels().add(Order);
w.getModels().add(bill);
w.activate();

A weaving process is composed by sequences of commands, on each command we have to define an Activity, which could be JAVA, ATL or any other custom types. We set the Bill model in the context and as parameter of the command. This mechanism enables to re-use a model in several commands.
Now we will be notified in the AddBurgerEntryActivity that the burgerEntries collection has been modified, but what happens when we receive this event? We will get the Order on which the list has been modified. We also get the Bill we have registered as parameter of the first command of the weaving process. Therefore, we just re-calculate the price.

public class ReCalculateBurgerPriceActivity {
	// we plan to replace HashMap<String, Object> by 'Context' class
	public void execute (HashMap<String, Object> context) {
		// the context contains the initial EMF notification
		Notification notification = (Notification) context.get(CONTEXT_NOTIFICATION);
		// that's the burger entry modified, now get the Order
		BurgerEntry newBurgerEntry = (BurgerEntry)notification.getNewValue();
		Order fromOrder = newBurgerEntry.getOrder();
		// Get the bill to weave with the Order ID
		Bill currentBill = context.getModels(Bill.getClass());
		//Calculate the price on the burgerEntries
		float price = calculateTotal(fromOrder);
		//Set the buger price
		currentBill.setBurgerPriceTotal(price);
		}
}

.

Collecting event for the CEP

Each time an Order is Validated and ready to be sent to the KitchenPlanning, we need to send the OrderEvent on the Event Collector or directly to the CEP engine. Let’s see how we can listen the TimeStamp attribute for Order and fire an OrderBurgerEvent on the CEP:

// create one event for each case : add and remove in burgerEntries
ChangedEvent setEvent = ProcessFactory.eINSTANCE.createChangedEvent();
setEvent.setPath("timeStamp");
setEvent.setEventType(EventType.SET);
ChangedEvent removeEvent = ProcessFactory.eINSTANCE.createChangedEvent();

// create the activity processed by the event
setCommand.setaddCommand ("platform:/plugin/burgerFactory/org.euranova.burgerfactory.handlers.OrderValidatedActivity");

// attach activity to event through sequence flows
SequenceFlow asetSeq = ProcessFactory.eINSTANCE.createSequenceFlow();
setSeq.setSource(setEvent);
setSeq.setTarget(setCommand);

// create the process
WeavingProcess wp = ProcessFactory.eINSTANCE.createBindingProcess();
wp.getElements().add(setEvent);
wp.getElements().add(setCommand);
wp.getElements().add(setSeq);

// create a weaver and activate it
Weaver w = new Weaver();
w.getProcesses().add(wp);
// set the model on which we attach the weaving process
w.getModels().add(Order);
w.activate();

Quiet the same as the code we saw before. Now what’s the content of the Activity:

public class OrderValidatedActivity{
	// we plan to replace HashMap<String, Object>by 'Context' class
	public void execute (HashMap<String, Object>context) {
		// the context contains the initial EMF notification
		Notification notification = (Notification) context.get(CONTEXT_NOTIFICATION);
		// that's the burger entry modified
		BurgerEntry newBurgerEntry = (BurgerEntry)notification.getNewValue();
		//Fire the event on the CEP engine
		epService.getEPRuntime().sendEvent(new OrderburgerEvent(newBurgerEntry));
		}
}

.

That’s all ! Now let’s what happens in the CEP engine side.

Complex Event Processing

We need to code an ESPER pattern and the actions to take when this pattern is matched. First, let’s start the CEP engine

EPServiceProviderepService = EPServiceProviderManager.getDefaultProvider();
epService.getEPAdministrator().getConfiguration().addEventType("OrderBurgerEvent",OrderBurgerEvent.class.getName());
//Create the pattern and load it as a statement
EPStatement statement = epService.getEPAdministrator().createEPL("select irstream sum(quantity) as totalQuantity from OrderBurgerEvent(type='superburger').win:time(2 min) having sum(quantity) > 3");
//Add a listener which will be called when the pattern is matched
statement.addListener(new BurgerRateListener());

Finally, let’s define our BurgerRate Listener:

public class BurgerRateListener implements UpdateListener {
	public void update(EventBean[] newEvents, EventBean[] oldEvents) {
		//here we get all the events which compose the pattern
		//in our case we have to increase the supersize burger cooking rate
		KitchenManager.getSingleton().updateSuperSizeRate(3);
		}
}

Notice, that the system is :

  • flexible: rules can be modified and redeployed live
  • extensible: we could connect any other event sources for refining our vision of the context
  • completely Asynchronous, that’s all about event programming

Architecture considerations

In this post, we only focused on simple application on the same JVM for the clarity of the post. However a real application must be  distributed among clients. We could delegate the model distribution to live-model repository such as Eclipse CDO [4] in the EMF project.  Therefore, the cash desk application and the kitchen application are considered as CDO clients able to request and modify our live-models. Concerning the CEP, the only difference is that the engine must be launched in a separate application and then, requires a message backbone such a JMS Queue or an ESB to interconnect the client applications and the CEP.

Conclusion

A lot of things in these two last posts. We saw how we can create an application with live-models, and why we needed to weave them. First, we designed our models and defined how we should weave them at runtime.  We showed the necessity to listen model modifications in order to synchronize each other.  Since we are able to get modification events, why wouldn’t we be able to listen all event notifications, therefore, we are potentially able to perceive the context in real-time, then being able to react and take action accordingly. In order to detect “notable” situations, we re-use the inference engines used in CEP and we bring the Event-Driven Architecture value in live-model applications.

References

[1] What is Complex Event Processing, http://www.thecepblog.com/2007/05/14/what-is-complex-event-processing-part-1/

[2] Oracle CEP Project, http://www.oracle.com/technology/products/event-driven-architecture/complex-event-processing.html

[3]  ESPER, the Open Source CEP, http://esper.codehaus.org/

[4] The Eclipse CDO project, http://www.eclipse.org/cdo/

Super Size EMF Fast Food Demo: Tracking your live-models (Part 1)

Last week we submitted a talk at Eclipse Con 2010Add Complex Event Processing to your EMF models: Super Size models Fast food demo“. This is a good opportunity for explaining the concepts and architecture exposed in the talk. Actually that’s a good continuation of the last post. Indeed, we saw the M2M principles and the reasons why we needed transformation support and tracking of modifications from live-models.  Today we  put all those things in practise and dive into a real application example with live models, going further we use Complex Event Processing for injecting “intelligence” in the application.

Example to explain

In order to introduce all those new concepts, we use an application example for illustrating this post. Let’s imagine that we have to implement the integrated software of a Fast Food chain. The aim is to implement the software of each cash desk but also to send  orders to the kitchen.

The burger factory

The burger factory. How can we take into account the" context" into the burger cooking rate?

Before finishing writing the last line of the requirement, the fast food manager tell you something like “ho, by the way, I would like to improve the quality of service, I mean increasing the “fast” not the “food ” (he is laughing … that’s a fast food manager joke for sure) then I would like to be able to take decision to increase or decrease the burger rate at the kitchen if conditions are met. Condition being something like more than 3 burger ordered within 2 mins. In addition as I haven’t got much seats in my restaurant, if there is too much people seated, and other still going in at the cash desk queues, I would like to slow down the burger rate, then, we increase the time spent in the queue and I can let finish people in the restaurant. New seat detectors will be installed in 6 months”.

How could we implement such an application with live models ?

Step 1: designing models

The first step is to design models for order, bill and kitchen planing. The cash desk create orders and when press finish, it creates the bill and send the request to the general kitchen burger planning.

Order: list of burgers and drinks. It is represented by an entry which contains the reference to a burger and its quantity.

Bill: contains the burger total price and the drink total price.

Planning: that’s the kitchen planning, once a burger is ordered, we plan its preparation. It can be represented by pipes of burger. The planning will we weaved with all orders.

Burger Factory Model

Burger Factory Model

Therefore, the basic element is Order. From Order, we can weave the Bill, this means that from an order we can derive the bill model value. In the same way, the kitchen planning can weaved from order as well.

What do you mean by “weaved”?

If the bill and order are weaved, it means that when we create an order, we create a bill and the value of the bill attributes will depend on the attribute values of the Order instance. The weaving definition will describe how the two models are linked and when it must be updated.

The “how” will be the transformation process between the source and target model while the “when” will be the modification event we attach to the process.

Will it be live? What does it means?

Yes it will! It means that we aren’t going to generate code from our EMF models, instead, the application is composed by live-models, the runtime representation of our models. In this case, no generation phase is required, our models are the application.

Step 2: defining the weaving

Weaving between Order and Bill

Let’s start by the simplest weaving. The bill must be updated each time the burger entry list or the drink entry list is modified. This asks the first important questions: “how can we know that this particular attribute has changed? and how can I start a process or a transformation to update correctly the bill model?”

By the weaver framework of course!  In the scope of the Wazaabi project, we designed the Weaver framework (presented in the last post). This framework is able to listen any particular change on models, either structural change or value change. In addition it enables developer to start a Synchronization process to update any other models deriving from the first.

order/Bill Weaving

order/Bill Weaving trigged by any change on the entry lists.

Between our two live-models, we need to update the bill price each time a new entry is added or removed. The activity (a step in a weaving process) will be triggered by the event “list modified”. This activity is just a JAVA class which recomputes the burger total price or drink if the event has been emitted by the drink entry list.

The activity needs to receive input parameter, in our case, we set the entry list as parameter. Therefore, the activity has just to compute the total price and set the new value on the bill.

Weaving between Order and KitchenPlanning

The kitchen planning is composed by 3 queues, one for each burger. The idea is that the Activity “BurgerPlan” is triggered each time the timestamps is modified. Actually the timestamps is defined once the order is validated, and therefore, it should not change any more.

Order/kitchen Planning Weaving

Order/kitchen Planning Weaving triggered by the Time Stamp attribute modification.

Why don’t you use M2M framework such as ATL?

The first reason, is that ATL does not support, currently, incremental support (see last posts), therefore, we need to re-generate the target model, which is not possible in our case, because we cannot replace the instance of models, such as planning kitchen. In addition it is much more powerful to detect small modifications, and update those impacts instead of re-generating the entire model, especially in important models.

In addition, the kind of process we have shown in those examples could require to call an external Web Service or to look-up config in DB, or any other actions not directly linked to the source model. This is definitely not possible in traditional M2M.

However, we want to use ATL for defining those updates. Indeed, ATL is really suited for defining links between source and target models, that’s why in our case the synchronization process could be defined in ATL. Today we are joining  ATL research, an initiative from ATLANMOD (the ATL’s creator) in order to unify researches led around ATL and finally , if it turns out that the new technology is interesting, integrating officially ATL.  In this project we are developing a full support of ATL transformation as activity process in the Weaver framework.

What about UI?

Good question. We have done a  great job ! We have defined our live-models and the weaving between them. Now, we just need to build UI on top of those models. Either we create an SWT UI bound to our models, one for the Cash desk for editing orders and printing Bills, and  one for the kitchen for printing the planning. Or we ca use Live-Model UI framework such as Wazaabi. In this case, we have to define a UI model for Order, Bill and Kitchen plan and just weave them with their corresponding live models. Once the UI is defined, the application can work, nothing else is required. The job is done !

However, do you remember that the fast food boss wanted to control the burger cooking rate according to current demand. In addition, soon, the boss will ask to include other contextual parameters, such as the number of available seats, or the location of the truck which delivers salads and burgers.  How could we define a flexible, maintainable, and intelligent system? We propose to use CEP concepts. But we will see it in the next post on Thursday!

Conclusion (Part1)

In this post, we saw how we can create an application with live-models, and why did we need to weave them. First, we designed our models and defined how we should weave them.  We showed the necessity to listen model modifications in order to synchronize each other. Finally a UI layer for editing models is required and the job is done !  On the next post, we will see how the Complex Event Processing can bring value in our Fast Food management. Going further, we will show how we could extend the Weaver for collecting events and reacting in real-time to the fast food context.

So, stay tuned if you want to find out what will bring the Complex Event Processing in Live-Model applications!

Model transformations in new design approaches

Today we dive into a technical and theoretical track on the model transformation. In this post we investigate the existing techniques in Eclipse M2M in order to transform models, going further we replace them in the live-Model context and define what do we need to design such applications. We also present the live Weaver developed by our colleague Olivier Moises, which enables to track model changes. We will see how this kind of framework can be used in live transformation.

Do we need model transformations ?

The model transformation is the possibility to transform one model in another or n models in m others. As soon as we speak about designing models, we need to speak about transforming them.

Scenarios and applications of model transformation

In this section we describe the traditional usage of model transformation. I must confess that’s a bit theoretic, if you do not want to delve into those details, skip this part. However don’t underestimate the power of such concepts in a family discussion, this can really enjoy your Christmas dinner.

In the MDA approach, source and target models are defined conforming to certain metamodels. Those metamodels can be the same or different. We speak respectively about endogenous and exogenous transformations. Two other distinctions are made of models transformations depending on the difference between the abstraction level of source and target models: horizontal and vertical transformations. These four scenarios of transformations can be mixed: an endogenous or exogenous transformation can also be a horizontal or vertical transformation as explained in [7] and illustrated in the following table.

Transformations scenarios

Transformations scenarios

(source: [7])

Endogenous model transformation: transformation where source and target models are expressed in the same language (conform to the same metamodel). For examples, endogenous transformations are used for:

  • Optimization: improves the performance of a program.
  • Refactoring: makes structural changes in models to improve some characteristics (increasing modularity for instance) without modifying the level of abstraction and the behavior of models.
  • Simplification or normalization: reduces the syntactical complexity of a program.

Exogenous model transformation: also called translation, it’s a transformation where source and target models are expressed in different languages (conform to different metamodels). For examples, exogenous transformations are used for:

  • Synthesis: decreases the level of abstraction of models. For example UML Class Diagram can be translated to Java code.
  • Reverse engineering: increase the level of abstraction of models. For example, Java code can be translated to UML Class Diagram (but it’s more difficult than a synthesis).
  • Migration: transforms a program written in a certain language to another language belonging to the same level of abstraction. For example, a C++ program to Java program.

You can find more information about Horizontal and vertical transformations in [7].

I have heard something about ATL and Qvt in Eclipse M2M, what they are?

Query/View/Transformation (QVT)

In 2002, the OMG issued a Request For Proposals (RFP) [4] to standardize the definition of model transformation and therefore proposed the QVT standard to ensure interoperability between other standards recommended for the MDA (MOF, UML, OCL, etc.). This RFP proposes three main concepts Query, View, Transformation (QVT) whose formal definitions given by the OMG, are the following:

  • Query: a query is an expression that is evaluated on a MOF model. The result of a query is one or more instances of types defined in the source model, or defined in the Query language;
  • View: a view is a model that is completely derived from another model (original model);
  • Transformation: a model transformation is a process for generating a target model from a source model.

The requirements are divided into two categories, here is a summary of them [6]:

Mandatory Requirements

  • Query Language: a query language to make queries on MOF models;
  • Language for creating views: a language used to create views of meta-models or models. However, it has not been implemented in the proposed standard;
  • Transformation language: a language used to make transformations on MOF models. The definitions of transformations describe the relationship between source and target models;
  • Declarative language: definition of a transformation is declarative;
  • Abstract syntax of QVT in MOF: the abstract syntax of QVT languages are described in MOF 2.0.

Optional Requirements

  • Bidirectional transformations: the changes could take place in both directions (transformation of a source model to a model target, and conversely, the possibility to rebuild the source from the target model);
  • Traceability between source and target models: mechanisms providing the ability to save links between elements of source and target models during the transformation;
  • Reusable transformations: possibility to reuse transformation definitions and to execute transactionally a transformation;
  • In-place updates: a transformation where the source and target models may be the same.

QVT architecture

The QVT specification document [5] defines three languages and metamodels that are arranged in a layered architecture as shown in the figure below. These three languages are used to define model transformations of models and models are classified into two categories: declarative and imperative. Relations and Core are declarative languages and Operational Mappings is an imperative and an extension of the other two [5].

QVT architecture

QVT architecture

(source: [5])

Relations able you to specify transformations as a set of relations between MOF models. It is essentially based on objects pattern matching.

Core language is simpler than Relations. It is a minimal extension of EMOF and OCL. One of its goal is to provide the basis for the specification of the semantics of Relations language, given as a transformation RelationsToCore.

In addition to these two declarative languages that reflect the same semantics at two different levels of abstractions, the standard QVT provides two mechanisms for extending Relations and Core: the Operational Mappings language and a mechanism for invoking transformation functions implemented in an arbitrary language, the Black Box. These two extensions have been proposed because it is sometimes difficult to provide a complete solution only in a declarative form.

Operational Mappings language is an imperative language standard providing OCL extensions with side effects that allow a more procedural programming approach with a concrete syntax similar to other imperative languages (loops, conditions, etc.)

The Black Box mechanism offers the possibility to add plugins and execute external code during the transformation process, which is particularly interesting. Indeed, you can code complex algorithms in any other language supporting MOF (eg Java), reuse existing libraries and make some parts of the implementations not transparent, but it can become dangerous: the implementation of a plugin can access references of obejcts in the models during the transformatin and therefore likely to perform arbitrary operations on these objects without any control.

ATLAS Transformation Language

ATL is a hybrid language: declarative and imperative. Simple transformations can be written in the declarative form, based on the principle of mapping between source and target elements. However, the code quickly becomes unreadable when trying to encode a complex transformation In this case the imperative form will be used. The main idea of ATL is that everything is a model, including the transformations. For instance, we can apply a transformation where the source models and/or targets are also transformations (ie Higher Order Processing).

ATL transformations are unidirectional, in which the source models are in a readonly mode (ie, navigable) and target models in a writeonly mode (ie not navigable). So the elements of a source model can be browsed without being able to modify them, so it is not possible to make an in-place transformation (ie changing directly to the source model). But this is a contradiction with QVT, which allows such a transformation. The navigation of elements of a target model is not allowed because they will be only initialized after completing the transformation.
The metamodels are expressed in the XMI serailization standard format or by using the INRIA metamodeling language KM3 (Kernel Meta Meta Model).

Here is a formal description of ATL based on the QVT definition [8]:

  • Query: ATL query is an expression written in OCL which can return primitive values (Boolean, Integer, String etc.), elements of a model, collections, tuples, etc.
  • View: the views are specific representations of models. The use of views is limited: it is difficult to update them. But it is possible to overcome this limitation by integrating two properties to a transformation language:
    • Support incremental transformation: you can update a view from its source model. This avoids running the whole transformation again;
    • Support for bidirectional transformation: changes in one view are propagated directly to the source model.

Currently, these properties are not supported by ATL, but according to Jean Bézivin et al. [11] bidirectional changes could be obtained by using the property of traceability.

  • Transformation: ATL can transform one or more source models in one or more target models. The models must be conform to their respective MOF metamodel.

ATL architecture

As explained in [9], the architecture of ATL is divided into three layers, ATLAS Model Weaving, ATL and ATL Virtual Machine, each representing a level of abstraction. The figure below illustrates this architecture.

ATL architecture

ATL architecture

(source: [9])

  • AMW: a component of GMT project (Generative Modeling Technologies) (for more info: http://www.eclipse.org/gmt/amw/). This tool supports the creation of different kinds of links between model elements. These links are stored in a model (weaving model) conforming to an extensible metamodel (weaving metamodel);
  • ATL Language: transformations are defined in a hybrid language declarative and imperative;
  • ATL VM: the ATL compiler translates the code defined in the upper layer into byte-code, an executable code on the VM. The VM language provides a limited set of instructions grouped by categories (instructions for manipulating models, stack, memory and flow control).

Let’s see snippets

Now let’s give two practical examples of QVT Operational Mappings and ATL languages.

QVT example

Let’s take from [5] the transformation example converting an UML class diagram into a RDBMS schema. To declare a QVT transformation, transformation keyword is used followed by parentheses containing the name of models, the direction of the transformation and eventually other parameters:

modeltype UML uses SimpleUml;
modeltype RDBMS uses SimpleRdbms;

transformation Uml2Rdb(in srcModel:SimpleUML,out destModel:SimpleRDBMS);

main() {
  srcModel.objectsOfType(Class)->map class2table();
  srcModel.objectsOfType(Association)->map asso2table();
}

Uml2Rdbsm transformation takes in inpout a source model conforming to its metamodel SimpleUML and returns in output a target model conforming to its metamodel SimpleRDBMS. In the main section, class2table is a mapping function called to map Class type elements of source model and Table type elements of target model. Then another mapping is performed between elements of Assocation and Table by the ass2table mapping function.

Mapping operation is one of the most common operation of a QVT program. It associates one or a several elements of a source model to one or several elements of a target model. To declare a mapping function, the mapping keyword is used, then we specify the type on which the mapping will be performed (Class), followed by the the name of the function and eventually its parameters between parentheses, and at the end we specify the created type (Table).

mapping Class::class2table () : Table {
  name := 't_' + self.name;
  column := self.attributes->map attribute2column();
  key_ := object Key {
    name := 'k_'+ self.name;
    column := result.column->select(c|c.kind='primary');
  };
}
mapping Attribute::attribute2column(): Column {
  type := self.type.name;
  name := self.name;
  kind := self.kind;
}

class2table mapping returns a Table having the next characteristics: a name corresponding to the Class name with prefix t_, a column created from attribute2column mapping and result.column, containing the result of this operation, is used to create the primary key key_.

mapping Association::asso2table() : Table {
  name := self.name;
  column := OrderedSet{
      object Column{
      name := self.source.name;
      kind := self.source.kind;
      type:= 'Association';
    } ,
      object Column{
      name := self.destination.name;
      kind := self.destination.kind;
      type:= 'Association';
    }
  };
  key_ := object Key{
      name := self.name;
      column := if(self.isPersistent()) then
          result.column
        else
          result.column->select(c:Column | c.kind='persistent')
        endif;
    };
  foreignKey := null;
}

asso2table mapping transforms an association into a table. A collection of object couples (source and destination) are ordered and affected to colum attribute. isPersistent is a query testing the persistence of an association.

query UML::Association::isPersistent() : Boolean =
(self.source.kind='persistent' and self.destination.kind='persistent');

To compile Operational Mappings transformation, you can use SmartQVT (an open source an Eclipse-based project implementing QVT Operational language, more info on http://smartqvt.elibel.tm.fr/). An example illustrating a result of this transformation is given by the following figure, showing an UML source model (left) transformed into a RDBMS target model (right).

UML2RDBMS model transformation with SmartQVT

UML2RDBMS model transformation with SmartQVT

ATL example

To illustrate the ATL language, we will take the simple Families2Persons example from [10]. This transformation converts a model representing the composition of a family into a model representing each member of to this family as a person. This is illustrated in the two figures below.

Family metamodel

Family metamodel

Person metamodel

Person metamodel

(source: [10])

The header section contains the name of the transformation (Families2Persons) and the name of  the source and target models (IN and OUT) which are respectively conform to Families and Persons metamodels.

module Families2Persons;
create OUT : Persons from IN : Families;

A helper (also available in Operational QVT) is an operation that performs an auxiliary computation on source elements and return a result.

helper context Families!Member def: familyName : String =
	if not self.familyFather.oclIsUndefined() then
		self.familyFather.lastName
	else
		if not self.familyMother.oclIsUndefined() then
			self.familyMother.lastName
		else
			if not self.familySon.oclIsUndefined() then
				self.familySon.lastName
			else
				self.familyDaughter.lastName
			endif
		endif
	endif;

familyName helper returns a string containing the family name (= lastName) of a person. But this information is not available Member class. Thanks to the relation between Family and Member, it is possible to get this information by navigation.

helper context Families!Member def: isFemale() : Boolean =
	if not self.familyMother.oclIsUndefined() then
		true
	else
		if not self.familyDaughter.oclIsUndefined() then
			true
		else
			false
		endif
	endif;

isFemale helper checks if a member is a female by testing the familyMother and familyDaugther parameters. If the member is a mother or a daugther, the function would return a boolean with true value.

The two following rules will be used to generate in target model a Male or Female person, depending on the result of the test isFemale(). In both case, a Person has an attribute (fullName) which corresponds to the concatenation of  firstName from Member and familyName from Family.

rule Member2Male {
	from
		s : Families!Member (not s.isFemale())
	to
		t : Persons!Male (
			fullName <- s.firstName + ' ' + s.familyName
		)
}

rule Member2Female {
	from
		s : Families!Member (s.isFemale())
	to
		t : Persons!Female (
			fullName <- s.firstName + ' ' + s.familyName
		)
}

To compile your ATL transformation, ATL offers a complete development environment. It provides a set of tools, ATL Development Tools (ADT), integrated into the Eclipse platform (for more info, http://www.eclipse.org/m2m/atl/). An example illustrating a result of the  Families2Persons transformation is given by the following figure, showing the Simpson family model (left) transformed into a Person model (right).

Families2Persons model transformation with ADT

Families2Persons model transformation with ADT

What’s the incremental support ?

One of the most challenging issue of model transformation is to assure consistently a synchronization between the source model and the target model. Basically, an user could change models at anytime he wants. Modification made on source model is either an atomic operation (create, delete, or update) or a set of complex atomic operations. So, the main question is: how to apply modifications made on source model elements to target model elements?

A simple solution would be to rerun the entire transformation on the modified model. This approach is not optimized because it could easily become heavy (loss of execution time) if multiple models are involved in making changes.  In addition, if we use live representation of models, the instance of the target models will be overridden.

A more effective solution is to transform only the source model elements that are changed and then update some elements of the target model (and not the whole model). Formally, a transformation is called incremental if individual changes in a source model lead to execution of only those rules which matched the modified elements. To support incremental model transformations, two main approaches are presented in [11] as illustrated in the following figure.

Incremental transformation approaches

Incremental transformation approaches

(source: [11])

  • Re-transformation: executes a sequence of transformations generating either a target models which must be merged with the original target models, or change sets which can be directly applied to existing target models. In order to know which source elements have been modified and which haven’t. In re-transformation approach, these elements will always be re-calculated thanks to trace information (only if traceability is supported), because the execution state of the model transformation system is not maintained in this approach.
  • Live transformation: change made in source model models are instantly propagated to target models. In this approach, transformation context is continuously maintained, so trace information of the current state of execution will be used to know which source elements have been modified and which haven’t. Therefore, live transformation is more efficient than re-transformation approach.

The support of incremental change is among the mandatory requirements of the QVT RFP. Core languages and declarative QVT Relations allow incremental updates (both directions) but not the imperative Operational Mappings language. So, a future improvement of  SmartQVT would be the support of this property.

Regarding ATL, the current version does not directly support incremental processing. Each time a transformation is launched, the source model is fully read and the target model is completely rebuilt. Also if you launch the transformation again, the change made to the target model by the user will be lost [7]. However it would be possible to implement incremental transformation by using the traceability property, but it is still a research topic of the ATLAS group [8].

OK but why do I need live transformations?

We need to have live transformations as soon as we have live models! The first post on this blog was inaugurated by a article on Wazaabi the live EMF model Ui framework. In Wazaabi the Ui are live models, and in this case it become interesting to have live M2M to transform you UI in anything else. For instance, Architect, the Wazaabi modeler, which by the way, has been proposed as the E4 workbench editor, is based on M2M.

the Wazaabi architect archiecture

the Wazaabi architect archiecture

In Architect, the developer can design a JSF UI model. Behind the scene the editor renders a view of this model by transforming it into an SWT model. This SWT model is then rendered in a Wazaabi view which is copied in the Architect editor. As a result, you can Edit any kind of UI model and by transformations, you directly edit this model through an SWT model. For more technical information about architect check out [1], it is a good example of live M2M, and that is a cool architecture as well. If it is not clear do not mind, I will dedicated a post next week to Architect.

The Live-M2M could also be used in conjunction with live model repository such as CDO [2]. In this case, the models are stored in the repository and clients can access to their live representations. Eike Stepper shown us a cool demo of the eDine restaurant application in Eclipse summit 09 [3] based on shared live-models.

Edine App from Eike Stepper

eDine App from Eike Stepper based on CDO and live models

In his demo Eike adapts the model in order to visualize the result into a UI. We could imagine updating this application by transforming models. Let’s imagine that we have an “order model” which contains the content of your order. Now we could imagine that the “bill model” is just a transformation of the order according to some rules. Finally we could ultimately imagine that the UI is another transformation between the bill model and an Wazaabi UI bill model.

In order to design such kind of applications, we need to define models, transformations between them and just adapting those models to specific business logic. That’s all ! But it is an important change in design and modelling. By using live models we change the way we design applications and live Weaving is just a piece of this change.

Therefore, what’s your Live-Weaver? Is it another yet ATL?

Not at all. As we have seen, the traditional transformation method provides poor mechanisms for incremental support, but provide a full support for transformation semantics. More over, in order to define which field of which part of the model has changed, we need to define a notification system able to detect any change from input or output models. That is exactly what the Live-Weaver does, detecting changes and starting a custom process. This change can be either a value change or structural change, typically when a model elements are structurally modified, removed, moved, etc. The framework is able to detect, specific kind of change on specific parts of models.

We can attach a listener to the change notification in order to start a “synchronisation process”. This process can contain ATL transformations, custom code, WS call, etc. The aim is to be as open as possible.

By implementing a complete framework and by enabling to listen any kind of changes on models, we provide a convenient way to support live transformations, therefore, we can investigate new modelling  approaches  for designing live-model based applications, by (1) defining models, (2) transformation and weaving between them and (3) adapting them for specific business logic.  In addition, the ability to listen any kind of changes from models can be coupled to specialized elements, such as rule engines, in order to detect “notable” event, and triggering a corresponding action. Actually, that’s noting else than a Complex Event Processing [12] applied to models change event notifications.

References

[1] Wazaabi Architect documentation, http://wazaabi.org/documentation/technical-description/architect-modeler

[2] CDO Wiki, http://wiki.eclipse.org/CDO

[3] Edine Application, http://thegordian.blogspot.com/2009/04/modeling-goes-enterprise.html

[4] Object Management Group (OMG), Meta Object Facilitiy (MOF) 2.0 Query/View/Transformation RFP. 2003.
http://www.omg.org/

[5] Object Management Group (OMG), Meta Object Facilitiy (MOF) 2.0 Query/View/Transformation Specification. 2008.
http://www.omg.org/spec/QVT/1.0/PDF/

[6] Ivan Kurtev, State of the Art of QVT: A Model Transformation Language Standard. Springer-Verlag, 2008.
http://www.springerlink.com/content/2g55gw5260q2740h/

[7] Philipp Huber’s Master Thesis, The Model Transformation Language Jungle – An Evaluation and Extension of Existing Approaches. Vienna University of Technology, 2008. http://www.big.tuwien.ac.at/teaching/theses/ma/huber.pdf

[8] Jean Bézivin, Grégoire Dupé, Frédéric Jouault, Gilles Pitette, Jamal Eddine Rougui, First experiments with the ATL model transformation language: Transforming XSLT into XQuery. In OOPSLA 2003 Workshop, Anabeim, California, 2003. http://www.softmetaware.com/oopsla2003/bezivin.pdf

[9] Frédéric Jouault, Ivan Kurtev, On the Architectural Alignment of ATL and QVT. Springer-Verlag 2006.
http://www.sciences.univ-nantes.fr/lina/atl/www/papers/ATLandQVT-PRELIMINARY%20VERSION.pdf

[10] Freddy Allilaire, Frederic Jouault, A simple illustration of model-to-model transformation. ATLAS group, INRIA & University of Nantes 2007.
http://www.eclipse.org/m2m/atl/doc/ATLUseCase_Families2Persons.pdf

[11] Istán Ráth, Gabor Bergmánn, András Örös, Dániel Varró, Live Model Transformations Driven by Incremental Pattern Matching. Springer-Verlag, 2008.
http://www.springerlink.com/content/g43052uj0p27428v/

[12] Complex Event Processing definition, Wikipedia, http://en.wikipedia.org/wiki/Complex_event_processing

Post written by S. Skhiri and C. Topak.