This chapter covers ■ Advanced SCA features
95Configuration using component types
4.1
Configuration using component types
Component types, like the SCA Java annotations shown in this book’s examples so far, are used to define the configurable aspects of an implementation. By this, we’re refer- ring to the ability to configure, at runtime, dependencies such as properties and refer- ences. The SCA Java annotations we’ve used so far were essentially metadata used to notify the SCA engine of the relationships that existed between the classes. When using non-Java languages (section 4.5), the option of using annotations isn’t always available, and so component types must be used. In certain scenarios, you may not find it desirable to use annotations, even if they’re available. For example, since anno- tations are defined within the code, they aren’t suitable when runtime configuration flexibility is required. Or perhaps you’re exposing existing Java classes as components, and can’t or don’t want to make any source modifications. Let’s take a look at how the component type facility works.
NOTE You can mix and match using component types and annotations, if you so desire. For example, you can use a component type file to identify properties but annotations for references and services.
To use component types, you first create a component type file, which is an XML doc- ument that follows a naming convention of
<component-implementation-class>.componentType
where component-implementation-class is the name of the implementation class associated with the component. The file location is also important, and must be within the same relative classpath as the implementation object. What’s inside the file? Let’s create an example.
NOTE In the source code that accompanies this section, the component type files are located under the src/main/resources folder.
The ProblemTicketComponentImpl class, which we created in listing 3.2 in the previ- ous chapter, used the @Service, @Property, and @Reference annotations to identify what services are being offered by the implementation class. Let’s assume we’ve cre- ated a new class called ProblemTicketComponentImplNA, which is function-wise identi- cal to the original but without the use of the Java annotations (the class is in the sample code for this section). The component type definition used in lieu of the annotations is shown in listing 4.1.
<componentType xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <service name="ProblemTicketComponent"> <interface.java interface="opensoa.book.chapter4_1.ProblemTicketComponent"/> </service>
Listing 4.1 Component type file used in lieu of SCA implementation class annotations
b
Defines new servicec
Defines service96 CHAPTER 4 Advanced SCA
<reference name="createTicket"> <interface.java
interface="opensoa.book.chapter4_1.CreateTicketComponent"/> </reference>
<property name="username" type="xsd:string"/> <property name="password" type="xsd:string"/> </componentType>
The service element is used in lieu of the @Service annotation to describe the ser- vices being offered by the component
b
. In this case, the interface for the service is defined by the method signatures found in the ProblemTicketComponent interface classc
. The reference element similarly identifies, by its @name attribute, which class member variable it’s associated with, as well as the interfaced
for the referenced object. The property entriese
are used instead of @Property annotations to indicate which member variables in the class will be receiving the injected property values at runtime.NOTE It may seem a bit superfluous for the reference and property elements to require an interface or type to be specified. We believe this may be because the target component class associated with the type file isn’t reflected (per- haps because of the multilanguage nature of SCA). Without reflection, the reference interface and property types must be manually identified.
As you can see, using a component type file allows you to declaratively define your configuration in a way that’s more flexible, though less convenient, than using anno- tations. We’ll touch on component types again in our coverage of scripting language support in section 4.3. Next up, we’ll look at SCA interaction models, which provide the ability to make more complex, long-running interactions between a client applica- tion and the service.
4.2
SCA interaction models
The services we’ve defined so far have all followed the commonly used stateless request/response pattern. In chapter 1, we discussed how using stateless services rep- resents SOA best practice. This is because stateless services are more stand-alone, self- contained, and amenable to clustering for high performance. However, in certain sce- narios statelessness isn’t always an option and, in fact, can sometimes cause its own performance-related problems. For example, if a request typically takes a while to respond, the calling service must “block-and-hold” while the service completes its work. This can cause unacceptable delays, particularly when real-time user interac- tions are required, such as within a web application. So in certain scenarios using stateful conversations and callbacks can be worthwhile.
4.2.1 Using conversations
What is an example where we might want a conversational stateful service? Many third-party APIs, such as the one offered by Salesforce, require that you first call a
d
Identifies reference to be injected97