SCA/SCA Component/SCA Signature
An SCA signature is an object which identifies an SCA element (a component, a service...) in a unique manner.
Or said differently, SCA signatures are computed element IDs, similar to a unique HashCode. They only make sense for SCA.
SCA signatures were necessary
Within SCA tools, SCA elements are manipulated by different technologies.
The SCA Composite Designer and the Composite editor rely on EMF and GMF. So, they manipulates EObjects.
The SCA XML editor and the Form editor rely on the WTP XML model. So, they manipulate DOM nodes.
The SCA builder rely on EMF. But it also deals with resource markers. It must be able to write identifiers on resource markers, so that editors will be able to find where they should display markers (which line for a source editor, which page for the form editor, which figure for the designer). That was the real problem. Be able to retrieve an SCA element in a model from a marker added by the SCA builder. And this, in EMF models, GMF diagrams and XML documents.
At first glance, an EMF URI could have worked.
Except that SCA tools deal with *.composite and *.composite_diagram files. All the editors edit directly the *.composite, except the designer which edits the *.composite_diagram. That's two resources working on the same contextual elements. But resource and EMF URIs would be different since the file is not the same.
More gnerally, resource URIs depend on resource locations. They are not based on the content of these resources. SCA signatures solve all these problems. They are computed from the content of SCA resources. If an SCA resource is moved or renamed, the associated signature does not change. It only changes with the content of the resource.
If you find two SCA elements with the same signature, there are only two possibilities. Either they are the same element, or the project contains errors. There is no other explaination. In a model instance, to find the element matching a given signature, you simply have to compute the signature of any element until you find one with the same signature. SCA signatures can be computed quickly and for any SCA element (in a composite, a constraining type - and soon for a component type). They can be created either from XML nodes or from EObjects.
SCA signatures in a concrete way
SCA signatures are computed from resource contents.
It looks like an XPath expression. It uses element names and sometimes also, attributes, which are used as identifiers.
Let's take an example by considering the composite below.
<?xml version="1.0" encoding="ISO-8859-15"?> <sca:composite xmlns:sca="http://www.osoa.org/xmlns/sca/1.0" xmlns="http://www.osoa.org/xmlns/sca/1.0" name="TestRestaurantServiceComponent" targetNamespace="http://eclipse.org/sample/sca"> <!-- Test Component --> <sca:component name="TestComponent"> <sca:implementation.java class="org.eclipse.stp.sca.test.sample.impl.RestaurantServiceComponentRTSImpl"/> <sca:service name="RunTestService"> <tuscany:binding.rmi xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0" host="localhost" port="8098" serviceName="TestSca"/> </sca:service> <sca:service name="BillService"><sca:binding.sca/></sca:service> <sca:service name="MenuService"><sca:binding.sca/></sca:service> <sca:reference name="restaurantService"> <tuscany:binding.rmi xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0" host="localhost" port="8099" serviceName="RestaurantServiceRMI" /> </sca:reference> </sca:component> <!-- Tested Component --> <sca:component name="RestaurantServiceComponent"> <sca:implementation.java class="restaurant_rmi_service.lib.RestaurantServiceImpl"/> <sca:service name="RestaurantService"> <sca:interface.java interface="restaurant_rmi_service.api.RestaurantService"/> <tuscany:binding.rmi xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0" host="localhost" port="8099" serviceName="RestaurantServiceRMI" /> </sca:service> <sca:reference name="billService"><sca:binding.sca/></sca:reference> <sca:reference name="menuService"><sca:binding.sca/></sca:reference> </sca:component> <sca:wire source="TestComponent/restaurantService" target="RestaurantServiceComponent/RestaurantService"/> <sca:wire source="RestaurantServiceComponent/billService" target="TestComponent/BillService"/> <sca:wire source="RestaurantServiceComponent/menuService" target="TestComponent/MenuService"/> <sca:service name="RunTestService" promote="TestComponent/RunTestService"/> </sca:composite>
- The signature of the composite itself is
- The signature of the first component service is
- The signature of the last wire is
composite[TestRestaurantServiceComponent,http://eclipse.org/sample/sca]/wire[RestaurantServiceComponent/menuService -> TestComponent/MenuService]
Although they are readable, you should rather see SCA signatures like a long string identifier.
As you may have noticed also, an SCA signature is made up of segments. Each segment corresponds to an element in the XML tree.
An element signature has the signature of its ancestor (eContainer) as prefix.
Parts between square brackets are attributes which identify the given element. If one of these attributes changes, the element signature changes too.
Now, let's take a look at the way SCA signature segments are computed.
- For a composite, it is the element name "composite", followed by the two attributes that identify in a unique way a composite in a project scope: the name and the target namespace. In a project, you can't have two composites with the same name and target namespace. Otherwise, SCA composite inclusions can't work.
- For a component, a service, a reference and a property, it is the element name and the name attribute.
- For an include, it is the element name (include) and the name and target namespace of the included composite.
- For a wire, it is the element name (wire) and the source and target attributes (two wires can't have the same ones).
- For interfaces, implementations and bindings, the element name is enough. You can't have one of their ancestor having two such elements. That would be an invalid SCA application.
- For other elements, by default, only the element name is taken. It may change if new requirements appear.
To compute the signature of an SCA element, use one of the following:
new ScaSignature( EObject scaEObject ).toString();
new ScaSignature( Node scaNode ).toString();
SCA IDs and use cases
SCA signatures solved an important problem for SCA tools.
But they may also interest other tools.
Let's take the example of the STP-IM component.
The STP-IM aims at bridging STP tools thanks to a central meta-model defining SOA concepts and their relations. Each STP tool can then map the concepts it works on with the concepts represented in the intermediate model. One of the features the IM component provides is a builder to synchronize the different views within the tooling. As an example, we could imagine two BPMN and SCA models being linked through an IM instance. In this situation, some BPMN elements would be associated with certain SCA elements, and vice-versa. The association would be made through an STP-IM instance.
The IM builder aims at reporting modifications made in one model (e.g. the BPMN one) in the associated models (e.g. the SCA model in this example).
The issue is that it is not possible to intrinsically associate SCA elements with STP-IM elements. With BPMN, it is possible. The BPMN specification defines the graphical representation, not the way this representation is written. In the STP BPMN modeler, BPMN elements are associated a unique ID (UUID) by the modeler. This ID will never change as long as the element exists. Therefore, it is possible to associate this element with an IM element.
With SCA, this is not possible.
The specification defines the XML schemas (and also the graphical representation). Add an ID attribute, like in the BPMN modeler, would not be a clean solution. XML and EMF parsers would be able to deal with that. But only the editor which defines this ID would understand its meaning. Within SCA Tools, there are four editors, relying on 3 different model representations. Such an attribute would have to be strongly required in order to be correctly handled by all the editors. With BPMN, there is only one editor. That's the reason why it is difficult to imagine the IM builder remain synchronized with SCA resources.
But now, with SCA signatures, there is a basis of solution. An incomplete solution, but better than nothing.
SCA signatures are computed SCA IDs. They can be stored as string objects by the IM builder. To determine what has changed in an SCA model, the IM builder could proceed the following way:
- For very element of the first SCA model...
- Compute and store the SCA signature of the element.
- For every element of the second SCA model...
- Compute the SCA signature of the element. Search this signature in the first model signatures.
- If it is found, compare all the properties / attributes to determine what has changed.
- If it does not have it, then it may be a new element (store it).
- Process orphan the elements from both models (i.e. which were not found in the other SCA model).
- These elements may have been removed.
- Or their identifiers may have changed (e.g. if the name of a component has changed, then its signature has changed).
- In any case, the STP-IM builder would have to find a solution to deal with this last situation (it must be possible to compute the proximity between two signatures and/or provide a merge view). If we see the IM component as a helping tool, one nice approach could be to simply add markers on unresolved resources and let the user deal with that (rather than wanting the perfect matching in any situation and provide a wrong mapping).
Anyway, this is a suggestion of another use case for SCA signatures.
The discussion about this use case is obviously open.