Creating services using Apache Tuscany
91The SCA assembly model
To test the JMS binding, let’s develop a client assembly that posts messages to the des- ignated JMS queue. This will be used to simulate a regular JMS client that interfaces with the service. Although we could do this without using SCA, the exercise is beneficial because it demonstrates how SCA can be used within a client capacity. To develop this assembly, we’ll create a new component that remotely references the SystemErrorService via JMS. This reference will then be used to invoke the JMS call and return the results (the default SOAP over JMS binding supports synchronous JMS
calls). The assembly for the JMS client is shown in listing 3.14.
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" targetNamespace="http://opensoa.book.chapter3" name="jmsclient"> <component name="JMSComponent"> <implementation.java class="opensoa.book.chapter3_27.impl.JMSClientImpl" /> </component> <reference name="JMSClientReference" promote="JMSComponent/jmsClient"> <interface.wsdl interface="http://chapter3.book.opensoa# ➥wsdl.interface(SystemErrorComponentPortType)" /> <binding.ws wsdlElement="http://chapter3.book.opensoa/system# ➥wsdl.binding(SystemErrorServiceJMSBinding)" uri="jms:/SystemErrorInQueue? ➥transport.jms.ConnectionFactoryJNDIName= ➥QueueConnectionFactory&java.naming.factory.initial= ➥org.apache.activemq.jndi.ActiveMQInitialContextFactory& ➥java.naming.provider.url=tcp://localhost:61616? ➥wireFormat.maxInactivityDuration=0" /> </reference> </composite>
Listing 3.14 Assembly for the JMS client used to submit remote requests
Using SCA to rationalize your existing services
One of the big challenges encountered by most enterprises is that they may already have a scattershot of services exposed via JMS or SOAP. Rationalizing them to pro- vide for a consistent interface or to enforce governance requirements can be chal- lenging, especially when making wholesale modifications is out of the question. Historically, ESBs were useful in such scenarios, because you could create new ser- vices that simply call or wrap the existing ones. Because SCA is equally adept acting as a server or client, it could also perform a similar role. That is, you could use SCA to repackage or provide new binding protocol support for an existing set of services.
b
Assigns reference to JMSComponent Uses interface defined by WSDL portTypeUses SOAP over JMS binding
92 CHAPTER 3 Creating services using Apache Tuscany
The reference element injects an object into JMSComponent’s jmsClient instance variable that adheres to the specification provided by interface.wsdl element
b
. Since we can’t directly inject a WSDL interface into the Java component, we used the class JMSClientImpl for the concrete implementation, as it was created with the same method and parameters defined in the WSDL (indeed, interface.java could have been used in lieu of interface.wsdl). The JMSClient interface implemented by JMSClientImpl is shown here:@Remotable
public interface JMSClient {
public int systemProblem(SystemErrorDO ticket); }
To simplify what’s happening, consider the reference being injected as a remote “han- dle” that’s provided to the local component, JMSClientImpl. The handle’s interface can be defined either via a Java class or through a WSDL (in this case, we used the
WSDL). If a WSDL is used, then an implementation class that adheres to the WSDL
specification must be used for receiving the handle with the component class. In other words, the interface defines the contract or structure of the reference and it can be defined using either a Java class or WSDL. The implementation of that interface can be satisfied using any of the supported implementation types, such as implemen- tation.java or implementation.spring. Listing 3.15 displays a Java component class implementation for our JMS client.
public class JMSClientImpl implements JMSClient { @Reference
public JMSClient jmsClient;
public int systemProblem(SystemErrorDO ticket) { int rval = jmsClient.systemProblem(ticket); System.out.println("rval: " + rval);
return rval; }
}
When the systemProblem method is invoked, it uses the remote JMS handle repre- sented by the jmsClient variable
b
to invoke the remove servicec
. To invoke this component, a Main class is then used to instantiate the SCA domain and invoke the component:SCADomain scaDomain = SCADomain.newInstance("jmsclient.composite"); JMSClient jmsClient = scaDomain.getService(JMSClient.class,
"JMSComponent");
SystemErrorDO ticket = new SystemErrorDO(); ticket.setProblem("test problem");
ticket.setSystem("test system"); ticket.setTitle("test title");
Listing 3.15 JMSClientImpl component class
b
Injects reference to JMS clientc
Invokes method on JMS client93 Summary
jmsClient.systemProblem(ticket); scaDomain.close();
As previously pointed out, you’re obviously not limited to using SCA to populate the remote JMS message. You can also use the ActiveMQ administrative console to submit a test messages.
To recap: We added a new binding to the SystemErrorService that enabled it to receive SOAP over JMS in addition to the SOAP over HTTP we previously set up. Then we created a JMS client using an SCA assembly for purposes of creating test requests. Adding the new JMS binding didn’t result in any changes to the underlying target components. This exemplifies some of the great power and flexibility afforded by SCA. We’ve now covered all of the core SCA technologies and illustrated their usage.
3.3
Summary
One of the biggest challenges software developers face today is selecting the right framework. As you know, we’re awash in frameworks, ranging from those used to cre- ate web applications and web services to application assembly. So there’s probably a healthy dose of skepticism about the Service Component Architecture (SCA), regard- ing both its ability to fulfill its promise of an easy-to-use component assembly model with protocol and language neutrality as well as its vendor commitment. After all, we’ve seen in the past standards like Java Business Integration (JBI), which was launched with great fanfare, only to die and whither on the vine as vendor support, once so promising, quickly evaporated. Will SCA suffer from the same grim future? While my crystal ball may not always be accurate, We do think the future is bright for
SCA. Why? Because SCA is the product of SOA best practices that have been learned over the past several years, and it also recognizes the heterogeneous environment in which most enterprises operate.
The SCA assembly framework, centered on the notion of components and services, nurtures a SOA mind-set of creating discrete, reusable units of code that can easily be shared and distributed. To demonstrate SCA’s capability, we created in this chapter a hypothetical problem ticket service constructed of SCA components. We used Apache Tuscany, an excellent open source SCA implementation. The services we created were then exposed as SOAP-based web service over both HTTP and JMS. The code used to build the components was completely oblivious to the underlying protocol used when exposing it as a service. This is very exciting stuff, and means that as an architect, you don’t have to worry about locking yourself into having to select up-front a single pro- tocol or language. The power and flexibility of SCA also became apparent as we cre- ated higher-level compositions that consisted of lower-level components. We used Spring-like “inversion of control” dependency injection to configure the classes at runtime with dependent classes or properties.
While this chapter has covered the core SCA functionality, there’s much more to learn about SCA, and we’ll dive into some of the more advanced features in the next chapter.
94