Using this page to document/track our thoughts on Milestone 1 functionality. The related forum discussion can be found here.
The goal for M1 is a basic end-to-end service implementation and composition scenario:
- Create service "A" using the Bean component
- Unit test service "A"
- Add an invocation of service "B" from service "A"
- Create service "B" using the Bean component
- Test service "A" including dependency on "B"
- Bind service "A" to SOAP for external consumption
- Deploy packaged application
Notes on each step in the scenario:
Step 1 : Create service "A" using the Bean component
- I probably should have included a step '0' for creating the actual SwitchYard project. Before we can create any services, we will need a project structure with the appropriate dependencies setup, etc. Need to create a maven archetype for a SwitchYard project (SWITCHYARD-6) and add dependencies for core-api at compile scope and core-runtime at test scope (alternatively, test-util can pull in the core-runtime dependency transitively).
- For M1 we will need a dependency on Bean component annotations and runtime for testing. I consider this to be a temporary hack as I'm hoping tooling will ultimately generate the dependencies for us as we choose to include certain components in our project (e.g. add a bean service, appropriate dependencies are generated in the pom).
- Need to publish SwitchYard artifacts for M1 so that people can try it out without a source checkout and local build (SWITCHYARD-35).
- Once the project is created, user creates a new Java interface representing the service contract.
- User then creates a new Java class implementing the service interface. The implementation class is annotated with @Service.
- Build the project - user now has a service which can be hosted in SwitchYard.
Step 2 : Unit test service "A"
- Need a base test class which makes it easy to create, send, and receive messages (SWITCHYARD-36) without having to get into the nitty gritty core API details (create domain, register service, create and handle exchanges, etc.). This will likely be more than just a single base class, but we can start there.
- The scope of the unit test should be testing a service provided by a single component.
- For M1, we need a way to bootstrap the CDI runtime for each test as is currenty done in AbstractCDITest. It would be nice to have a uniform pattern for creating component-specific tests without reimplementing the basic send/receive logic in each component test. For example, AbstractCDITest could extend SwitchYardTest, which would have the utility logic described above.
- For testing multiple components together, I think we will want to test "in-container", which means Arquillian.
Step 3 : Add an invocation of service "B" from service "A"
- I debated the order of this and step 4 - i.e. should we implement the service or declare a reference to it first? I decided to put the reference first because it highlights some cool things about how CDI integration works.
- First thing to do is create a Java interface representing our contract with service B.
- Note that the interface used for the reference could come from anywhere. We might have pulled it from a service repository, generated it off of a WSDL in our workspace, etc.
- Also worth noting is that the Java interface does not have to be the same interface (as in class) used by the service provider. The interface is actually just a proxy to an exchange and the method name and parameter are mapped to an exchange.
- Now we add an @Inject and @Reference to the our bean service. The SwitchYard CDI extension takes care of injecting the service proxy as part of the CDI lifecycle.
- It would be nice if our testing framework could create "mock" responses for references, which would allow us to unit test a service without requiring the services identified by @Reference to be loaded. Behind the scenes, the test would register for each service with @Reference and return the mock payload identified in the test.
Step 4 : Create service "B" using the Bean component
- Same as step 1, but we don't need to create the project (created in step 1) or the Java interface (created in step 3).
- Probably a good idea to add another unit test for service B.
Step 5 : Test service "A" including dependency on "B"
- This is an integration test for our SwitchYard application, testing the wiring between the consuming and providing components.
- Technically, we could do this with AbstractCDITest today, but I would like to explore the use of Arquillian(SWITCHYARD-7) to handle this with embedded AS7.
Step 6 : Bind service "A" to SOAP for external consumption
- We should be able to take an existing service and expose it to the outside world using any gateway. In this case, it will be SOAP.
- Add necessary SOAP binding configuration to the SwitchYard config file (SWITCHYARD-10).
Step 7 : Deploy packaged application
- Build the project and produce a deployable SwitchYard archive (SWITCHYARD-5).
- Need a deployer implementation to handle the deployment for each target container (SWITCHYARD-38).