In Part 1 of this series, we introduced the Service Component Architecture (SCA) as a programming model for building and assembling integration solutions with an overview of what SCA is, and with definitions of some related terminology. We also provided an example of building an SCA component in Java™ using IBM WebSphere Integration Developer, tested the SCA component, and built a sample JSP file that invoked the SCA component using the SCA client programming model. In Part 2, we continue by describing references and wires, and show how to use them to assemble SCA components.
The big picture
In the example we presented in Part 1, we used a simple JSP client to invoke an SCA component. This example was for demonstration purposes only; when building your own actual custom applications, you will probably want to use the standard J2EE™ component model to implement the application logic. J2EE Web applications will continue to invoke Enterprise JavaBeans to access application-specific functions. The SCA programming model is really about business integration, application composition, and solution assembly, not J2EE application development. An SCA client (which could be J2EE) will typically be external to the process manager and might, for example, use BPEL flows to orchestrate workflow. Web applications co-deployed with BPEL flows can also use the SCA programming model to invoke application-specific functionality. Figure 1 shows an example of an SCA ecosystem.
Figure 1. SCA ecosystem
SCA lives in the integration layer. SCA components can use imports to invoke applications outside the SCA runtime. SCA components can be invoked by non-SCA clients using exports. Within the integration layer, SCA components can be composed by defining references and using wires, which we will focus on in this article. With wires and references, you can define characteristics of the run time invocation at development time; for example, making the invocation synchronous or asynchronous, marking transaction boundaries of the invocation, and so on. These characteristics are read at deployment time and enable the desired run time behavior. Figure 2 illustrates these high level concepts.
Figure 2. High level view of references and wires
Again, the focus is within the integration layer and not necessarily the application layer. Furthermore, we are referring to higher level integration, such as workflow orchestration or advanced integration with EIS systems. However, for illustration purposes we are using simple Java examples to show how to wire together components within the integration layer, stressing the functionality of the wires and references rather than the implementation of the components themselves. (In subsequent articles, we will see how SCA components can be implemented as BPEL flows and state machines, and how the same wiring techniques can be applied.) We will therefore illustrate references and wires using a scaled down model, as shown in Figure 3; however, keep in mind the vision of appropriate SCA usage in Figure 2.
Figure 3. Simplified reference and wire model
As discussed in Part 1, SCA components are packaged into an SCA module. SCA components within a module interact with each other by defining references on the calling SCA component, and wiring those references to other SCA components within the same module. Figure 4 illustrates this concept.
Figure 4. Reference and wire concepts
A reference is represented in SCDL on the calling component as shown below:
<scdl:component xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:java="http://www.ibm.com/xmlns/prod/websphere/scdl/java/6.0.0" xmlns:ns1="http://CreditApproval/CreditRequest" xmlns:scdl="http://www.ibm.com/xmlns/prod/websphere/scdl/6.0.0" xmlns:wsdl="http://www.ibm.com/xmlns/prod/websphere/scdl/wsdl/6.0.0" displayName="CreditApproval" name="CreditApproval"> <interfaces> <interface xsi:type="wsdl:WSDLPortType" portType="ns1:CreditRequest"> <method name="calulateCreditScore"/> </interface> </interfaces> <references> <reference name="CreditHistoryPartner"> <interface xsi:type="java:JavaInterface" interface="approval.credit.credit.history.CreditHistory"> <method name="getCreditLimit"/> </interface> <wire target="CreditHistory"/> </reference> <reference name="CreditAgencyPartner"> <interface xsi:type="java:JavaInterface" interface="approval.credit.credit.agency.CreditAgency"> <method name="getCreditScore"/> </interface> <wire target="CreditAgency"/> </reference> </references> <implementation xsi:type="java:JavaImplementation" class="sca.component.java.impl.CreditApprovalImpl"/> </scdl:component>
One of the benefits of references is the ability to define the quality of service during the invocation. Quality of service (QoS) qualifiers can be specified when wiring components in the assembly editor. These qualifiers define the requirements imposed on the SCA runtime to manage a component during an invocation.
SCA lets you apply QoS qualifiers (such as transactions, security, and reliable asynchronous invocation) to components without requiring programming or changes to the services implementation code. When wiring the components, you can specify qualifiers to provide extended quality of service to the components, as well as to the clients accessing the service. Within IBM WebSphere Process Server, you can define SCA qualifiers in three places:
At run time, these specifications determine how the clients interact with the target components. Depending on the qualifiers specified, the runtime environment supplies any required additional processing.
Qualifiers for references
Reference qualifiers can specify asynchronous invocation reliability, and whether a target component's methods should be federated as part of any client transaction.
The reference qualifiers are:
Asynchronous reliability - Enables invocations to occur asynchronously. These qualifiers also let you specify the reliability of the message, request, and response timeouts. In turn, the Service Integration Bus, which provides the messaging platform within the IBM WebSphere Application Server runtime and thus is available to WebSphere Process Server, will be configured under the covers. (See Resources for information on the Service Integration Bus.)
Suspend transaction - For synchronous invocation, client global transaction context is always propagated to a target component when it is invoked using the synchronous programming model. (This qualifier only affects client global transactions because local transactions are never propagated to target components.) To address use cases where the client does not want a target component to federate with the client's transaction, further qualification of the reference is required using the suspend transaction qualifier settings:
- True suspends the current global transaction before invoking a component via a service reference.
- False (default) instructs the runtime not to suspend a global transaction before invoking a component via a service reference.
Asynchronous invocation - Determines if asynchronous invocations should occur as part of any client transaction. Values:
- Call (default) instructs the runtime to commit the message to the destination for an asynchronous invocation as soon as the service call is made.
- Commit instructs the runtime to transact the commit of the message to the destination for an asynchronous invocation to the current unit of work scope.
Suspend activity session - Activity sessions enable a higher level of coordination for resources that may not support distributed transactions. Such scenarios are more likely in an integration solution; the client does not want a target component to federate with the client's activity session, further qualification of the reference is required using the suspend activity session qualifier settings:
- True suspends the current activity session (if present) before invoking a component via a service reference.
- False (default) instructs the runtime not to suspend any active activity session before invoking a component via a service reference.
You can specify references qualifiers so that they apply to all the references of a service component or to standalone references. If necessary, you can also specify these qualifiers for each individual reference, in which case they would override any top level qualifier setting. Inherited qualifiers listed in the Properties view appear in gray and the assigned ones in black. Inherited qualifiers cannot be changed unless you select the element on which they are defined.
Qualifiers for interfaces
Interface qualifiers advertise the QoS supported by a target service, and therefore represent a contract with a client of the service.
The interface qualifiers are:
Join activity session - Determines whether the target service is willing to join the propagated activity session scope. Values:
- True instructs the runtime not to suspend an activity session (if present) at the interface boundary.
- False (default) instructs the runtime to suspend an activity session (if present) at the interface boundary.
Join transaction - Determines whether the target service is willing to join a propagated global transaction. Values:
- True instructs the runtime not to suspend a global transaction (if present) at the interface boundary.
- False (default) instructs the runtime to suspend a global transaction (if present) at the interface boundary.
Security permission - Enables you to define a J2EE role on an SCA component. Only clients associated with the declared role will be able to invoke the component.
All interface qualifiers can be applied at three levels of a component:
- For all of its interfaces
- For an individual interface
- For an individual operation of an interface.
The qualifier of the operation overrides the qualifier of the interface; the qualifier of the interface overrides the qualifiers for all the interfaces of a component.
Qualifiers for implementations
Implementation qualifiers provide the ability to identify the service's authority and/or express its requirements for a transactional environment.
The implementation qualifiers are:
Activity session - Determines if the component's processing will be executed under an activity session, which provides an alternate unit of work scope to the one provided by global transaction contexts. Values:
- True: Component will execute in the context of an activity session. If an activity session is present on invocation, the component will be added.
- False (default): Component will execute in the context of the existing global transaction (if present) or a local transaction. Components with an implementation qualifier of activitySession=false must use the interface qualifier joinActivitySession=false.
- Any: If an activity session is present, the component will join the current activity session. If an activity session is not present, the component will execute in the context of the existing unit of work scope or a local transaction.
Transaction - Determines the logical unit of work that the component's processing executes. For a logical unit of work, all of the data modifications made during a transaction are either committed together as a unit or rolled back as a unit:
- Global: Component will execute in the context of a global transaction. If a global transaction is present on invocation the component will be added to this global transaction scope. If a global transaction is not present, a new transaction scope will be established.
- Local (Default): Component will execute in the context of a local transaction.
- Any: If a global transaction is present the component will join the current global transaction scope. If a global transaction is not present, the component will execute in the context of a local transaction.
Security identity - Enables you to specify the identity the component acts as, similar to the J2EE Run-As constraint on the deployment descriptor.
Qualifiers are defined in the SCDL file: interface qualifiers are defined in the interface section, implementation qualifiers are defined in the implementation section, and reference qualifiers are defined in the reference section. (See the WebSphere Process Server Information Center for more details.)
Wire your components
With our new understanding of references, we can now wire some components together. The example we will use is quite simple, but in the process we will get to examine the various qualities of services available. We will continue with the credit approval example we used in Part 1.
In our example:
- The Credit Approval component will have to invoke a Credit History component as well as a Credit Agency Component.
- The Credit Approval component will serve as a facade for the two services.
- The Credit Approval component needs to be wired to these other components.
The materials you will need for this exercise are available in the download file included with this article.
Set up your workspace
Start WebSphere Integration Developer and create a new workspace (Figure 5).
Figure 5. Create a workspace in WebSphere Integration Developer
Close the Welcome screen (Figure 6).
Figure 6. WebSphere Integration Developer Welcome screen
To import the project interchange file from the download file, right-click in the Business Integration view and select Import (Figure 7).
Figure 7. Import download file
Select Project Interchange, then Next (Figure 8).
Figure 8. Import project
Assuming you unzipped the download materials to the C: drive, select the CreditApprovalPart2.zip file, then Select All and Finish (Figure 9).
Figure 9. Import project
Examine the components
In our example, we will use the bottom-up style of development: we have an existing set of SCA components and we are going to integrate them. From within the Business Integration View, you can examine the SCA module:
Expand the CreditApproval Module (Figure 10).
Figure 10. Credit Approval module expanded
Notice that there are three interfaces and three Java implementations. Open the CreditApprovalImpl Java implementation and go to the calculateCreditScore() method. Notice that calculateCreditScore interacts with both the CreditAgency component and the CreditHistory component to complete its services. You can easily imagine that the CreditApproval Service could be implemented as a BPEL process or other component type, but in this case, we have a simple Java component acting as a facade.
To open the assembly editor, double-click the CreditApproval assembly (Figure 11). When the assembly editor opens, the three components will be displayed (Figure 12).
Figure 11. Open assembly editor
Figure 12. Components in assembly editor
The CreditApproval component interacts with both the CreditAgency and CreditHistory by using a simple SCA client API. However, for the runtime to invoke these services properly, the components need to be "wired" together, which is rather simple using WebSphere Integration Developer. In our example, we will accept the defaults.
Select the CreditAproval component and drag a wire to the CreditAgency component (Figure 13).
Figure 13. Wire components
A dialog box (Figure 14) will indicate that a reference will be created on the CreditApproval component. Select OK.
Figure 14. Matching reference dialog
Since the CreditApproval component is a Java component, we need WebSphere Integration Developer to generate a Java interface so that the component can be invoked. Therefore, select Yes on the next dialog box (Figure 15). If CreditApproval were a full BPEL process, then we would choose No. (Keep in mind, that in most cases, you will use WSDL as your interface choice in the integration layer. If the User Interface is co-deployed with the integration solution, then, Java Interfaces can be used.)
Figure 15. Generate Java interface dialog
Repeat steps 9 through 11 to wire the CreditApproval component to the CreditHistory component. The result should appear similar to Figure 16.
Figure 16. Component wiring completed
Unit test components
Since we are using Java as our implementation, we can unit test the component within a Java SE environment. As we did in Part 1, we can easily bring up the unit testing tool within WebSphere Integration Developer:
Right-click on the CreditApproval component and select Test Component (Figure 17).
Figure 17. Test component
The unit tester will display. One nice thing about the unit test feature is that it lets you test the components in isolation, and can detect the references and create emulators. In our case, we our testing integration, so we need to remove the emulators.
Switch to the Configurations tab.
Expand Module CreditApproval module, highlight both CreditAgency and CreditHistory, and Remove them from the Emulators list (Figure 18). Testing the CreditApproval component will now cause an invocation of the CreditHistory and CreditAgency component rather than emulating the interaction.
Figure 18. Remove emulators
Switch back to the Events tab and highlight the Invoke item (Figure 19).
Figure 19. Events tab
Populate the input as shown in Figure 20.
Figure 20. Data parameters
Select the Eclipse 1.4 JVM option (Figure 21).
Figure 21. Select deployment location
Examine the flow of each step. You can actually see the data as it flows through the components (Figure 22).
Figure 22. Event flow
The final result should look similar to Figure 23.
Figure 23. Test results
Close the test editor without saving.
Examine Quality of Service
References and wires are key to integrating solution, as they abstract the how and where of the call. When running inside WebSphere Process Server, you can define the quality of service you want for the call. For example, you can make the call asynchronous, you can change the transaction context, or make asynchronous calls more reliable. We will look at the various QoS options here by examining the reference properties.
Select the CreditAgency reference on the CreditApproval component shown in Figure 24.
Figure 24. Component references
Go to the Properties view. You will notice the reference is selected.
Figure 25. Selected reference
On the Details tab (Figure 26), the interface being called and the multiplicity are displayed, along with the wire as the target. You can change the multiplicity of the call; for asynchronous calls, this could enable several components to be called in a publish/subscribe manner.
Figure 26. Reference details
Switch to the Qualifiers tab (Figure 27) to set certain qualities of service.
Figure 27. Qualifiers tab
Press the Add button to view several qualities of service available (Figure 28).
Figure 28. Quality of Service qualifiers
You can experiment with these as a self-exercise, keeping in mind that these qualities need to be tested inside the WebSphere Process Server runtime. These qualifiers include transaction qualities as well as asynchronous qualities; to test transactional work, you will need components that interact with resources. Certain Qualities of Service are defined on the interface. This enables the component some control on how others call it.
Highlight the CreditApproval Interface in the assembly editor (Figure 29), or navigate to it on the Properties editor.
Figure 29. CreditApproval selected in assembly editor
Examine the Quality of Service qualifiers (Figure 30) and the implementation qualifiers. Notice that these qualifiers are defined on the called service as opposed to the calling service.
Figure 30. Examine qualifiers
Test in the WebSphere Process Server test environment
To test the Qualities of Service, you often need to be running in WebSphere Process Server, or the WebSphere Process Server runtime provided in WebSphere Integration Developer for testing.
In the Servers view, right-click the server and select Start (Figure 31).
Figure 31. Start server in the test environment
Figure 32. Server has started
When the server has started, as indicated on the administrative console (Figure 32), you can add the SCA module to the server in much the same way you can a J2EE application, since an SCA module is wrapped by an EAR file (as mentioned in Part 1). Right-click the server again and select Add and remove projects... (Figure 33).
Figure 33. Add and remove projects
Select CreditApprovalApp and Add it to the configured projects side (Figure 34).
Figure 34. Add project to the server
Examine the administrative console to ensure the SCA module has started (Figure 35).
Figure 35. Console message showing SCA module has started
To test the component using the same WebSphere Integration Developer unit test function, right-click the component again, then select Test Component as before (Figure 36).
Figure 36. Test SCA component
Again, remove the emulators to enable the test to flow through the SCA components (Figure 37).
Figure 37. Remove emulators
Enter the input parameters shown in Figure 38.
Figure 38. Data parameters
Select WebSphere Process Server V6.0 for the deployment location (Figure 39).
Figure 39. Select deployment location
Examine the test results.
As a self exercise, change the components to make a database update, then experiment with the transactional properties. You can also make the calls asynchronous and check the underlying Service Integration Bus configuration on the administrative console.
This article examined references and wires in the context of assembling Service Component Architecture components with WebSphere Integration Developer. The next article in this series will discuss imports and exports so that you can integrate SCA modules. Later in the series, we will examine more complex components and integration with non-SCA components.
The authors would like to thank Eric Herness, Keys Botzum, and Paul Ilechko for reviewing the article.
More articles in this series
- Part 1: Oh great, another programming model?
- Part 3: Integrating SCA modules with imports and exports
- Part 4: Integrating with JMS and Web services
|Code sample||CreditApprovalPart2.zip ( HTTP | FTP )||23 KB|
- Building SOA solutions with the Service Component Architecture, Part 1: Oh great, another programming model?
- IBM WebSphere: Deployment and Advanced Configuration
- WebSphere Process Server: IBM's new foundation for SOA
- Introduction to Service Data Objects
- Simplified Data Access with SDO