I got the code done last week but I'm only just now finishing up the build.xml file. So, as promised, here's what I did (a bit of a long post but I think I got it all)
Firstly to get more familiar with the workspace I followed Sebastien's instructions from the Domain/Contribution repository thread [1] and ran up the workspace to have a play. "You can use the latest tutorial modules to see the end to end integration, with the following steps: 1. Start tutorial/domain/.../LaunchTutorialAdmin. 2. Open http://localhost:9990/ui/composite in your Web browser. You should see all the tutorial contributions and deployables that I've added to that domain. 3. Click the feeds in the "composite install image" to see the resolved composites. 4. Start all the launch programs in tutorial/nodes, you can start them in any order you want. 5. Open tutorial/assets/tutorial.html in your Web browser, follow the links to the various store implementations." The workspace is allowing you to organize the relationships between contributions/composites, the domain composite that describes the whole application and the nodes that will run the composites. It processes all of the contributions that have been provided, the composites they contain, the association of composite with the domain and with nodes and produces fully resolved composites in terms of the contributions that are require to run them and the service and reference URIs that they will use. This resolved composite information is available from the workspace through composite specific feeds. From this feed you can get URLs to the required contributions and the composite. In fact what happens each time you do a GET on the composite URL is that all of the composites assigned to the domain are read and the domain composite is "built" in full using the composite builder. The individual composite that was requested is then extracted and returned. In this way policy matching, cross domain wiring, autowiring etc is manged at the domain level using the same code used by the nodes to build individual composites. This is very similar in layout with what is happening with our current domain/node implementation where you add contributions to the domain and nodes run the resulting composites. However there is a big difference here in that there is now an implication that the domain is fully configured before you start the nodes as the workspace is responsible for configuring service / reference URIs based on prior knowledge of node configurations. Previously you could start nodes and have them register with the domain without having to provide this knowledge manually to the domain. I guess automatic node registration could be rolled into this if we want. In making the calculator-distributed sample work I wanted to be able to test the sample in our maven build so having a set of HTTP forms (which the workspace does provide) to fill in is interesting but not that useful. So immediately I went looking for the files that the workspace writes to see if I could create those and install them pre-configured ready for the test to run. I used the tutorial files as templates and made the following to match the calculator-distributed scenario. Firstly there is a file (workspace.xml) [2] that describes all each contribution's location and URI <workspace xmlns="http://tuscany.apache.org/xmlns/sca/1.0" xmlns:ns1=" http://tuscany.apache.org/xmlns/sca/1.0"> <contribution location="file:./target/classes/nodeA" uri="nodeA"/> <contribution location="file:./target/classes/nodeB" uri="nodeB"/> <contribution location="file:./target/classes/nodeC" uri="nodeC"/> <contribution location="file:./target/classes/cloud" uri=" http://tuscany.apache.org/xmlns/sca/1.0/cloud"/> </workspace> Then there is a file (domain.composite) [3] that is a serialized version of the domain composite, i.e. what you would get from the specs getDomainLevelComposite() method. This shows which composites are deployed at the domain level. <composite name="domain.composite" targetNamespace="http://tuscany.apache.org/xmlns/sca/1.0" xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:ns1=" http://www.osoa.org/xmlns/sca/1.0"> <include name="ns2:CalculatorA" uri="nodeA" xmlns:ns2="http://sample"/> <include name="ns2:CalculatorB" uri="nodeB" xmlns:ns2="http://sample"/> <include name="ns2:CalculatorC" uri="nodeC" xmlns:ns2="http://sample"/> </composite> Lastly there is a file (cloud.composite) [4] that is another SCA composite that describes the nodes that are going to run composites. <composite name="cloud.composite" targetNamespace="http://tuscany.apache.org/xmlns/sca/1.0" xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:ns1=" http://www.osoa.org/xmlns/sca/1.0"> <include name="ns2:NodeA" uri=" http://tuscany.apache.org/xmlns/sca/1.0/cloud" xmlns:ns2=" http://sample/cloud"/> <include name="ns2:NodeB" uri=" http://tuscany.apache.org/xmlns/sca/1.0/cloud" xmlns:ns2=" http://sample/cloud"/> <include name="ns2:NodeC" uri=" http://tuscany.apache.org/xmlns/sca/1.0/cloud" xmlns:ns2=" http://sample/cloud"/> </composite> Each included node composite looks something like <composite xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:t="http://tuscany.apache.org/xmlns/sca/1.0" targetNamespace="http://sample/cloud" xmlns:s="http://sample" name="NodeA"> <component name="NodeA"> <t:implementation.node uri="nodeA" composite="s:CalculatorA"/> <service name="Node"> <binding.sca uri="http://localhost:8100"/> </service> </component> </composite> You will note that the node holds default binding URI information. With these files the workspace can produce the fully configured composites that will run on each node. Having done this I rewrote the code in the "node" package to create a set of launchers for the various parts of the sample. node.LaunchDomain [5] was the first and simply calls the DomainAdminLauncher from the workspace-admin package. This starts an SCA application, reads all these files, makes some web pages available and more importantly make the resolved composite information available at URLs starting http://host:9990/. .. node.LaunchCalculatorNodeA, B, C [6] allows each node to be started. You will note that in each of these a node gets started with a line something like node = nodeFactory.createSCANode("http://localhost:9990/node-image/NodeA"); This is a slightly different take on the node creation process we had before (this new node code is in the node2-* packages). It lets you create a node given a composite information. This is derived from the helper method Simon Nash put on the factory and in this case is the URI of an Atom feed that provides a link to a composite and the contributions required to run that composite. The node runs, pulls down this information. Based on this information it pulls down each of the contributions and the composite and starts up the composite. As all the composites are fully configured the nodes simply build, activate and start them. They don't need to go looking for service endpoints. The actual distributed calculator application is the same as it was before. I hope this makes some kind of sense. Please ask if you want more details. Regards Simon [1] http://www.mail-archive.com/tuscany-dev@ws.apache.org/msg28711.html [2] http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/samples/calculator-distributed/workspace.xml [3] http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/samples/calculator-distributed/domain.composite [4] http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/samples/calculator-distributed/cloud.composite [5] http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/samples/calculator-distributed/src/main/java/node/LaunchDomain.java [6] http://svn.apache.org/repos/asf/incubator/tuscany/java/sca/samples/calculator-distributed/src/main/java/node/LaunchCalculatorNodeA.java