The SCA Assembly model provides a very flexible way for users to define the structure of their applications. However, the specification is still in the process of defining how these assemblies should be deployed to physical servers. Further the Assembly specification itself is still developing.
In light of that, we have tried to develop a very flexible solution for deployment in Tuscany that allows us to modularize the process and react to evolutionary (and even revolutionary) changes in the assembly and deployment models. This solution assumes that as an application is deployed its configuration goes through three different forms:
- Persistent artifacts that have been provided by the user. These may be simple XML files, they may be bundles of code (e.g. in JAR or CAB files), they may be values in some global configuration system. When a user deploys an application, Tuscany needs to locate and load all these different artifacts and assemble them together into a consistent and complete desciption of what the user wants to run.
The complete model of the application created in memory. This is an intermediate form created from the persistent artifacts which describes the application - we call it the logical configuration model. It is designed to consistently represent the application. This model is described in ../ConfigurationModel
- A set of runtime contexts that actually run the application. These are optimized and wired together in a way that maximises the performance of the system. The emphasis is on short code paths that can be carefully tested so that we increase the stability of a production server.
[ editors note: a diagram would be really good here ]
We call the process of gathering together the persistent artifacts and building the logical configuration model "loading" as the primary activity is reading files, parsing them and building a consistent view. We call the process of converting the configuration model into runtime contexts "building" as the primary activity is building and optimizing runtime structures from the description in the model.
We have tried to keep a very clear separation between the two activities. There may be many ways in which persistent configuration information is stored and we may well need to support several concurrently. For example, in a clustered environment a management node may load the configuration from some central location but each of the worker nodes may just copy the configuration from it. Or, users may want to configure the system in different ways, for example using Groovy script instead of XML; we make use of this in our test environment by constructing the model programatically as part of the test suite.
We currently provide just one loader mechanism based on StAX which is descibed in ../StAXLoading
The building phase can itself be subdivided into two phases:
Context building, where the runtime context for each component implementation is built. This allows component implementations to set up the context for a component in isolation. The output is a "hairy" context containing the implementation of the component itself with a set of stubs (the hairs) that need to be connected to other components. For more details see ../ContextFactoryBuilder
Wire building, where the wires that connect components are created. This involves connecting the "hairs" from each isolated component to each other to create a fully connected runtime. Wire builders are reponsible for finding the most optimized connection between two components and for making sure all the policies needed by the service contract are present. For more details see ../WireBuilder