Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Difference between revisions of "VIATRA/Integration/MWE2 Integration"

(Started updating the wiki page to reflect the current state of the API)
Line 8: Line 8:
 
*Nontrivial side-effect relations between transformation steps can be handled.
 
*Nontrivial side-effect relations between transformation steps can be handled.
 
*The execution of event-driven transformation can be controlled.
 
*The execution of event-driven transformation can be controlled.
*Because of the specialized language, the description code base is short and easily expandable
+
*Because of the specialized language, the description code base is short and easily expandable.
  
 
== MWE 2 Basics ==
 
== MWE 2 Basics ==
Line 20: Line 20:
 
[[File:VIATRAMWE2.png]]
 
[[File:VIATRAMWE2.png]]
  
The Transformation chain consists of numerous transformation steps and channels. This is required as certain transformations (for example event-driven transformations) do not follow the batch execution semantics of the MWE language. This way incremental transformation can be wrapped into batch transformation chains. Transformation steps represent the individual transformations. Channels can be used to determine dependability relations between the steps themselves. If a step listens to a channel, the addition of a certain event to the channel will enable the execution of the step. After the execution has finished, new events are pushed to the site's target channels. Note, that the transformation chain itself has input and output channels. These can be used to indicate the first and last transformation steps in the chain.
+
A Transformation chain consists of numerous transformation steps and channels. This is required as certain transformations (for example event-driven transformations) do not follow the batch execution semantics of the MWE language. This way fine-grained incremental model transformations can be wrapped into these batch transformation chains. Transformation steps represent the individual transformations. Similar to the transformations themselves, these transformation steps define dependability relations towards each other. Channels can be used to determine these aforementioned dependability relations, as well as provide a direct communication method between transformation steps. If a step listens to a channel, the addition of a certain event to the channel will enable the execution of the step. After the execution has finished, new events are pushed to the site's target channels. The creation and processing of these events is the responsibility of the corresponding IEventFactory and IEventProcessor classes. The communicating transformation steps contain IListeningChannel and ITargetChannel objects. These wrapper classes bind together the channels with the factory (in case of target channels) or processor object (in case of listening channels) specified by the user. Note, that the transformation chain itself has input and output channels as well. These can be used to indicate the first and last transformation steps in the chain.
  
 
===Prerequisites and Installation===
 
===Prerequisites and Installation===
Line 33: Line 33:
  
 
===Library Classes===
 
===Library Classes===
 +
TODO new classes
  
 
The library defines a set of base classes which represent the main elements the previously described transformation workflow semantics. User defined behavior can be added to these elements via inheritance.
 
The library defines a set of base classes which represent the main elements the previously described transformation workflow semantics. User defined behavior can be added to these elements via inheritance.
*'''TransformationChain''': Represents a basic transformation chain. It provides an interface for defining transformation steps, as well as owns references to its inwards and outwards facing channels.
+
Interfaces:
*'''TranformationStep''': Base abstract class for defining transformation steps. It stores references to the channels it targets and listens to. The user defined functionality can be defined in the execute, initialize and dispose methods. It also provides an interface for the addition of event processors. Transformation steps execute if ONE of their listening channels are triggered by an event.
+
*'''ITransformationChain''': Represents a basic transformation chain. It provides an interface for defining transformation steps, as well as owns references to its inwards and outwards facing channels.
 +
*'''ITranformationStep''': Interface that defines the main entry points of transformation steps. The user defined functionality can be implemented in the execute, initialize and dispose methods.  
 +
*'''IChannel''': Defines methods for registering and receiving events.
 +
*'''IEvent''': Interface for events, defines methods for getting and setting the event parameter.
 +
*'''IEventFactory''': Provides an interface for creating certain typed events. As the events can contain parameters, event- and parameter types are specified as generic type parameters.
 +
*'''IEventProcessor''': Provides an interface for creating certain typed events. As the events can contain parameters, event- and parameter types are specified as generic type parameters.
 +
*'''IListeningChannel''': Provides an interface for channels, that are specifically designed as listening channels. It defines easy to use methods for event processing, that the owner transformation step can use.
 +
*'''ITargetChannel''':Provides an interface for channels, that are specifically designed as target channels. It defines easy to use methods for event creation, that the owner transformation step can use.
 +
 
 +
Classes:
 +
TODO
 
*'''SyncTranformationStep''': Child class of the TransformationStep class. Synchronizing transformation steps only execute if ALL of their listening channels are triggered by an event.
 
*'''SyncTranformationStep''': Child class of the TransformationStep class. Synchronizing transformation steps only execute if ALL of their listening channels are triggered by an event.
*'''Channel''': Representation of transformation chain channels. It contains a set of events, and provides an interface for defining a custom event factory.
+
*'''IChannel''': Representation of transformation chain channels. It contains a set of events, and provides an interface for defining a custom event factory.
 
*'''IEvent''': Interface for events
 
*'''IEvent''': Interface for events
 
*'''ControlEvent''': Implements the IEvent interface and represents a regular control event with no data flow.
 
*'''ControlEvent''': Implements the IEvent interface and represents a regular control event with no data flow.
Line 47: Line 58:
 
**'''ControlEventProcessor''': Child class of the EventProcessor, processes control events.
 
**'''ControlEventProcessor''': Child class of the EventProcessor, processes control events.
  
===Example===
+
===Hello World Example===
 
The usage of these classes can be most effectively described via a simple 'Hello World' example:
 
The usage of these classes can be most effectively described via a simple 'Hello World' example:
  
Line 61: Line 72:
 
<source lang="java">
 
<source lang="java">
 
import org.eclipse.emf.mwe2.runtime.workflow.IWorkflowContext;
 
import org.eclipse.emf.mwe2.runtime.workflow.IWorkflowContext;
import org.eclipse.viatra.emf.mwe2orchestrator.Channel;
+
import org.eclipse.viatra.emf.mwe2integration.mwe2impl.MWE2TransformationStep;
import org.eclipse.viatra.emf.mwe2orchestrator.EventProcessor;
+
import org.eclipse.viatra.emf.mwe2orchestrator.IEvent;
+
import org.eclipse.viatra.emf.mwe2orchestrator.TransformationStep;
+
  
public class BatchTransformationStep extends TransformationStep {
+
public class BatchTransformationStep extends MWE2TransformationStep {
 
     @Override
 
     @Override
 
     public void initialize(IWorkflowContext ctx) {
 
     public void initialize(IWorkflowContext ctx) {
         // create transformation
+
         //The reference to the context is set
        System.out.println("Init batch transformation");
+
 
         this.context = ctx;
 
         this.context = ctx;
 +
        //Normally the transformation is initialized here.
 +
        System.out.println("Init batch transformation"); 
 
     }
 
     }
 +
   
 
     public void execute() {
 
     public void execute() {
         for (Channel channel : listeningChannels) {
+
         //Firstly the triggering event is processed
            IEvent<? extends Object> nextEvent = channel.getNextEvent();
+
        processNextEvent();
            for (EventProcessor<? extends IEvent<?>> processor : processors) {
+
         //The transformation is executed
                processor.processEvent(nextEvent);
+
            }
+
         }
+
 
         System.out.println("Batch transformation executed");
 
         System.out.println("Batch transformation executed");
         for (Channel channel : getTargetChannels()) {
+
         //Events are sent to all target channels
            try {
+
        sendEventToAllTargets();
                channel.registerEvent(null);
+
            } catch (InterruptedException e) {
+
                e.printStackTrace();
+
            }
+
        }
+
 
     }
 
     }
 +
   
 
     @Override
 
     @Override
 
     public void dispose() {
 
     public void dispose() {
 +
        //Upon ending the runnable monitoring the incoming events needs to be stopped
 
         isRunning = false;
 
         isRunning = false;
 +
        //Dispose functions
 
         System.out.println("Dispose batch transformation");
 
         System.out.println("Dispose batch transformation");
 
     }
 
     }
Line 101: Line 106:
 
<source lang="java">
 
<source lang="java">
 
import org.eclipse.emf.mwe2.runtime.workflow.IWorkflowContext;
 
import org.eclipse.emf.mwe2.runtime.workflow.IWorkflowContext;
import org.eclipse.viatra.emf.mwe2orchestrator.Channel;
+
import org.eclipse.viatra.emf.mwe2integration.mwe2impl.MWE2TransformationStep;
import org.eclipse.viatra.emf.mwe2orchestrator.EventProcessor;
+
import org.eclipse.viatra.emf.mwe2orchestrator.IEvent;
+
import org.eclipse.viatra.emf.mwe2orchestrator.TransformationStep;
+
  
public class EventDrivenTransformationStep extends TransformationStep {
+
public class EventDrivenTransformationStep extends MWE2TransformationStep {
 
     @Override
 
     @Override
 
     public void initialize(IWorkflowContext ctx) {
 
     public void initialize(IWorkflowContext ctx) {
 
         System.out.println("Init event-driven transformation");
 
         System.out.println("Init event-driven transformation");
 
         this.context = ctx;
 
         this.context = ctx;
 
 
     }
 
     }
  
 
     @Override
 
     @Override
 
     public void execute() {
 
     public void execute() {
         for (Channel channel : listeningChannels) {
+
         processNextEvent();
            IEvent<? extends Object> nextEvent = channel.getNextEvent();
+
            for (EventProcessor<? extends IEvent<?>> processor : processors) {
+
                processor.processEvent(nextEvent);
+
            }
+
        }
+
 
         System.out.println("Send tick to event-driven transformation");
 
         System.out.println("Send tick to event-driven transformation");
         for (Channel channel : getTargetChannels()) {
+
         sendEventToAllTargets();
            try {
+
                channel.registerEvent(null);
+
            } catch (InterruptedException e) {
+
                e.printStackTrace();
+
            }
+
        }
+
 
     }
 
     }
  
Line 150: Line 140:
 
module org.eclipse.viatra.emf.mwe2orchestrator.transdemo
 
module org.eclipse.viatra.emf.mwe2orchestrator.transdemo
  
import org.eclipse.viatra.emf.mwe2orchestrator.*
+
import org.eclipse.viatra.emf.mwe2integration.*
import org.eclipse.viatra.emf.mwe2orchestrator.transdemo.*
+
import org.eclipse.viatra.emf.mwe2integration.mwe2impl.*
 +
import org.eclipse.viatra.emf.mwe2integration.demo.*
  
var chainStartChannel = Channel {}
+
//The channels between the transformation steps are defined here
var chainEndChannel = Channel {}
+
var chainStartChannel = MWE2Channel {}
 +
var chainEndChannel = MWE2Channel {}
  
var BatchChannel = Channel {}
+
var BatchChannel = MWE2Channel {}
var EventDrivenChannel = Channel {}
+
var EventDrivenChannel = MWE2Channel {}
  
 +
//The workflow and components are defined in the usual MWE2 fashion
 
Workflow {
 
Workflow {
component = TransformationChain {
+
//Add an MWE2TransformationChain component
inChannel = chainStartChannel
+
component = MWE2TransformationChain {
outChannel = chainEndChannel
+
//define the start and end channels of the chain
 +
startChannel = MWE2TargetChannel{channel = chainStartChannel}
 +
endChannel = MWE2ListeningChannel{channel = chainEndChannel}
  
 +
//define individual transformation steps
 
transformationStep = EventDrivenTransformationStep {
 
transformationStep = EventDrivenTransformationStep {
listeningChannel = chainStartChannel
+
//register listening channels to which this step listens
listeningChannel = EventDrivenChannel
+
//Add the chainStartChannel as listening channel, this way the transformation
targetChannel = BatchChannel
+
//chain can start the step sequence
 +
listeningChannel = MWE2ListeningChannel{ channel = chainStartChannel}
 +
listeningChannel = MWE2ListeningChannel{ channel = EventDrivenChannel}
 +
//register target channels to which this step sends events
 +
targetChannel = MWE2TargetChannel{channel = BatchChannel}
 
}
 
}
 
 
 
transformationStep = BatchTransformationStep {
 
transformationStep = BatchTransformationStep {
listeningChannel = BatchChannel
+
listeningChannel = MWE2ListeningChannel{ channel = BatchChannel}
targetChannel = chainEndChannel
+
//Add the chainEndChannel as target channel, this way the transformation
 +
//chain when to finish its execution.
 +
targetChannel = MWE2TargetChannel{ channel = chainEndChannel}
 
}
 
}
 
}
 
}
 +
//You can add additional regular MWE2 components here
 
}
 
}
 
</source>
 
</source>
  
This example is included in the library project under the *.transdemo package.
+
 
 +
This example is included in the test project of the library.
 +
 
 +
===Complex Example (CPS)===
 +
TODO
 +
 
 +
 
  
 
== Project Locations ==
 
== Project Locations ==
  
The library itself can be found at https://github.com/lunkpeter/org.eclipse.viatra/tree/master/MWE/org.eclipse.viatra.emf.mwe2orchestrator
+
The library itself can be found at https://github.com/lunkpeter/org.eclipse.viatra/tree/MWE/plugins/org.eclipse.viatra.emf.mwe2integration.
It contains a simple example as well.
+
The test project at https://github.com/lunkpeter/org.eclipse.viatra/tree/MWE/tests/org.eclipse.viatra.emf.mwe2integration.test contains a simple example as well.
 
Note that at its current state, the library itself is not an integrated part of the VIATRA framework, however as this inclusion is intended in the future, the library is in the org.eclipse.viatra namespace.
 
Note that at its current state, the library itself is not an integrated part of the VIATRA framework, however as this inclusion is intended in the future, the library is in the org.eclipse.viatra namespace.

Revision as of 10:58, 15 June 2015

Transformation Chains Using VIATRA MWE 2 Integration

Motivation

Define heterogeneous model transformation chains using a specialized description language.

  • Sequence of model transformation steps can be easily specified and maintained.
  • Nontrivial side-effect relations between transformation steps can be handled.
  • The execution of event-driven transformation can be controlled.
  • Because of the specialized language, the description code base is short and easily expandable.

MWE 2 Basics

Generic modeling workflows can be easily described via using the Xtext Modeling Workflow Engine. It enables the creation of components with various attributes, and it executes them in order. More, exact information about the Xtext MWE 2 can be found at https://www.eclipse.org/Xtext/documentation/306_mwe2.html

VIATRA MWE2 Integration Library

The VIATRA MWE2 Integration library provides support for defining complex transformation chains using Xtext MWE 2 workflows. As it can be seen on the figure below, due to the fact that the transformation chain itself is an MWE component, it can be easily integrated into higher level modeling workflows.

VIATRAMWE2.png

A Transformation chain consists of numerous transformation steps and channels. This is required as certain transformations (for example event-driven transformations) do not follow the batch execution semantics of the MWE language. This way fine-grained incremental model transformations can be wrapped into these batch transformation chains. Transformation steps represent the individual transformations. Similar to the transformations themselves, these transformation steps define dependability relations towards each other. Channels can be used to determine these aforementioned dependability relations, as well as provide a direct communication method between transformation steps. If a step listens to a channel, the addition of a certain event to the channel will enable the execution of the step. After the execution has finished, new events are pushed to the site's target channels. The creation and processing of these events is the responsibility of the corresponding IEventFactory and IEventProcessor classes. The communicating transformation steps contain IListeningChannel and ITargetChannel objects. These wrapper classes bind together the channels with the factory (in case of target channels) or processor object (in case of listening channels) specified by the user. Note, that the transformation chain itself has input and output channels as well. These can be used to indicate the first and last transformation steps in the chain.

Prerequisites and Installation

In order to use this library, the following Eclipse plug-ins are required:

After the prerequisites are met clone the following repository and import the contained projects. Note, that it contains the source of the VIATRA framework as well. https://github.com/lunkpeter/org.eclipse.viatra

Library Classes

TODO new classes

The library defines a set of base classes which represent the main elements the previously described transformation workflow semantics. User defined behavior can be added to these elements via inheritance. Interfaces:

  • ITransformationChain: Represents a basic transformation chain. It provides an interface for defining transformation steps, as well as owns references to its inwards and outwards facing channels.
  • ITranformationStep: Interface that defines the main entry points of transformation steps. The user defined functionality can be implemented in the execute, initialize and dispose methods.
  • IChannel: Defines methods for registering and receiving events.
  • IEvent: Interface for events, defines methods for getting and setting the event parameter.
  • IEventFactory: Provides an interface for creating certain typed events. As the events can contain parameters, event- and parameter types are specified as generic type parameters.
  • IEventProcessor: Provides an interface for creating certain typed events. As the events can contain parameters, event- and parameter types are specified as generic type parameters.
  • IListeningChannel: Provides an interface for channels, that are specifically designed as listening channels. It defines easy to use methods for event processing, that the owner transformation step can use.
  • ITargetChannel:Provides an interface for channels, that are specifically designed as target channels. It defines easy to use methods for event creation, that the owner transformation step can use.

Classes: TODO

  • SyncTranformationStep: Child class of the TransformationStep class. Synchronizing transformation steps only execute if ALL of their listening channels are triggered by an event.
  • IChannel: Representation of transformation chain channels. It contains a set of events, and provides an interface for defining a custom event factory.
  • IEvent: Interface for events
  • ControlEvent: Implements the IEvent interface and represents a regular control event with no data flow.
  • Advanced Features:
    • IEventFactory: Provides an interface for adding and removing certain typed events to and from the channel it is attached to. The events can contain parameters. Event and parameter types are specified as generic type parameters.
    • ControlEventFactory: Responsible for managing control events. Every channel owns one of these by default.
    • EventProcessor: Abstract class responsible for processing a certain type of Event. It can be attached to a transformation step. The type of the processed events are defined by generic type parameters.
    • ControlEventProcessor: Child class of the EventProcessor, processes control events.

Hello World Example

The usage of these classes can be most effectively described via a simple 'Hello World' example:

  • Create a new Eclipse plug-in project via File Menu --> New --> Project
  • Create a new MWE2 file (in a not default package) using the similar method. If prompted, add the Xtext nature to the project.

Define Transformation Steps

In the next step define the concrete transformation steps. Add these classes to the package created before.

BatchTransformationStep.java

import org.eclipse.emf.mwe2.runtime.workflow.IWorkflowContext;
import org.eclipse.viatra.emf.mwe2integration.mwe2impl.MWE2TransformationStep;
 
public class BatchTransformationStep extends MWE2TransformationStep {
    @Override
    public void initialize(IWorkflowContext ctx) {
        //The reference to the context is set
        this.context = ctx;
        //Normally the transformation is initialized here.
        System.out.println("Init batch transformation");   
    }
 
    public void execute() {
        //Firstly the triggering event is processed
        processNextEvent();
        //The transformation is executed 
        System.out.println("Batch transformation executed");
        //Events are sent to all target channels
        sendEventToAllTargets();
    }
 
    @Override
    public void dispose() {
        //Upon ending the runnable monitoring the incoming events needs to be stopped
        isRunning = false;
        //Dispose functions
        System.out.println("Dispose batch transformation");
    }
}

EventDrivenTransformationStep.java

import org.eclipse.emf.mwe2.runtime.workflow.IWorkflowContext;
import org.eclipse.viatra.emf.mwe2integration.mwe2impl.MWE2TransformationStep;
 
public class EventDrivenTransformationStep extends MWE2TransformationStep {
    @Override
    public void initialize(IWorkflowContext ctx) {
        System.out.println("Init event-driven transformation");
        this.context = ctx;
    }
 
    @Override
    public void execute() {
        processNextEvent();
        System.out.println("Send tick to event-driven transformation");
        sendEventToAllTargets();
    }
 
    @Override
    public void dispose() {
        isRunning = false;
        System.out.println("Dispose event-driven transformation");
 
    }
}

Define Transformation Structure

Define the transformation chain structure using the MWE2 language. Make sure to include all the referenced packages (if the classes are in the same package as the MWE2 file, include that package as well), and that the module name matches the containing package.

TransformationDemo.mwe2

module org.eclipse.viatra.emf.mwe2orchestrator.transdemo
 
import org.eclipse.viatra.emf.mwe2integration.*
import org.eclipse.viatra.emf.mwe2integration.mwe2impl.*
import org.eclipse.viatra.emf.mwe2integration.demo.*
 
//The channels between the transformation steps are defined here
var chainStartChannel = MWE2Channel {}
var chainEndChannel = MWE2Channel {}
 
var BatchChannel = MWE2Channel {}
var EventDrivenChannel = MWE2Channel {}
 
//The workflow and components are defined in the usual MWE2 fashion
Workflow {
	//Add an MWE2TransformationChain component
	component = MWE2TransformationChain {
		//define the start and end channels of the chain
		startChannel = MWE2TargetChannel{channel = chainStartChannel}
		endChannel = MWE2ListeningChannel{channel = chainEndChannel}
 
		//define individual transformation steps
		transformationStep = EventDrivenTransformationStep {
			//register listening channels to which this step listens
			//Add the chainStartChannel as listening channel, this way the transformation 
			//chain can start the step sequence
			listeningChannel = MWE2ListeningChannel{ channel = chainStartChannel}
			listeningChannel = MWE2ListeningChannel{ channel = EventDrivenChannel}
			//register target channels to which this step sends events
			targetChannel = MWE2TargetChannel{channel = BatchChannel}
		}
 
		transformationStep = BatchTransformationStep {
			listeningChannel = MWE2ListeningChannel{ channel = BatchChannel}
			//Add the chainEndChannel as target channel, this way the transformation 
			//chain when to finish its execution.
			targetChannel = MWE2TargetChannel{ channel = chainEndChannel}
		}
	}
	//You can add additional regular MWE2 components here
}


This example is included in the test project of the library.

Complex Example (CPS)

TODO


Project Locations

The library itself can be found at https://github.com/lunkpeter/org.eclipse.viatra/tree/MWE/plugins/org.eclipse.viatra.emf.mwe2integration. The test project at https://github.com/lunkpeter/org.eclipse.viatra/tree/MWE/tests/org.eclipse.viatra.emf.mwe2integration.test contains a simple example as well. Note that at its current state, the library itself is not an integrated part of the VIATRA framework, however as this inclusion is intended in the future, the library is in the org.eclipse.viatra namespace.

Copyright © Eclipse Foundation, Inc. All Rights Reserved.