Chapter 6. Implementing components using other technologies

This chapter covers

  • Using Spring to implement components
  • Using BPEL processes to implement components
  • Using scripts to implement components

An SCA application is an assembly of components. Each component has an implementation type. In chapter 5 we looked at how you can implement components using the Java language implementation type (implementation.java). In this chapter we’ll look at three more popular implementation types:

  • implementation.spring
  • implementation.bpel
  • implementation.script

Both implementation.bpel and implementation.spring are described in SCA specifications. But implementation.script was created by the Tuscany community and appears in the Tuscany namespace. You can safely skip the implementation types that aren’t of immediate interest to you.

The list of implementation types supported by the Tuscany runtime is growing as the community adds new extensions. Please check the project for the latest supported implementation types. Chapter 14 explains how a new implementation type can be added if the implementation type that you require isn’t already available.

We’ll continue using the Payment composite that we used in the last chapter to explain how Spring, BPEL, and scripting implementation types can be used. Let’s start by looking at how you can use a Spring application context to implement an SCA component.

6.1. Implementing components using Spring

Applications developed with the Spring framework can participate in SCA composite applications by using the implementation.spring component implementation type. This is defined in the SCA Spring Component Implementation Specification (http://www.osoa.org/download/attachments/35/SCA_SpringComponentImplementationSpecification-V100.pdf?version=1). SCA components implemented using Spring application contexts can interact with other SCA components using any of the flexible Tuscany bindings. Feel free to skip this section if you’re not planning to use Spring in your SCA application.

An SCA component implemented using implementation.spring is a Spring application that’s created using a Spring application context. The Spring application context can contain one or more beans, and we’ll show this in our example in this section. In Spring, a bean is the most basic configuration unit. In SCA, a component is the most basic configuration unit. An SCA composite provides a higher granularity of composition that can include SCA components implemented using Spring application contexts as well as SCA components written using other technologies such as scripting and BPEL.

The Spring application participates in an SCA composite by exposing its beans through WSDL or Java interfaces. Because Spring is a Java-based technology, service interfaces in the implementation are defined using Java interfaces. The mechanism by which these are mapped to component service and reference interfaces is the same as for implementation.java. Spring beans can participate in SCA composition as references or services without introducing any new metadata into the Spring application.

A Spring bean that provides a service implementation handles errors by throwing exceptions using normal Java language mechanisms. Assuming they’re checked exceptions, the Java interface that describes the service will describe the exceptions that are thrown. In this way the Tuscany runtime can process exceptions and ensure that they’re returned by binding extensions correctly.

We’re going to use the Payment component again as the basis for the examples in this chapter. Before we delve into the details of how implementation.spring works, let’s look at how the Spring-based Payment component fits into the overall TuscanySCATours composite application and the beans that the Spring application context could define. Figure 6.1 gives an overview of the payment part of the application found in the payment-spring sample contribution. Note that the Credit-Card component can be found in the creditcard-payment-jaxb sample contribution.

Figure 6.1. The Payment component implemented using implementation.spring, which, in turn, references a Spring application context, called Payment-context.xml, containing three beans

In this configuration the Payment component is implemented by three Spring beans, Payment, CustomerRegistery, and EmailGateway. The credit card payment function is provided by an external CreditCardPayment component accessed via an SCA reference. The Payment component uses the CreditCardPayment component to authorize the card payment and then uses the EmailGateway bean to send a payment confirmation email. The transaction fee property specifies how much TuscanySCATours charges to take a payment by credit card. With this configuration we’re showing integration between local Spring beans and between Spring beans and SCA components.

An existing Spring application can be incorporated into an SCA composition using two different approaches. In the first approach, no changes are made to the Spring application context. The SCA runtime determines which beans are exposed as services and references. The second approach involves adding SCA metadata to the Spring application context to identify services and references explicitly. We’ll first look at how to use an unmodified Spring context.

6.1.1. Using Spring services and references without SCA tags

The Payment-context.xml is a Spring application context defined in the sample contributions directory under contributions/payment-spring. It includes Payment, CustomerRegistry, and EmailGateway beans. The SCA runtime maps the Payment-context.xml application context to the SCA Payment component in the following way. Every top-level bean that has an ID or a name gets exposed as an SCA service. If a bean is nested within another bean, it’s considered anonymous and isn’t exposed as a service. Each Spring <property> that’s of ref type gets exposed as an SCA reference. Each Spring <property> that’s of value type gets mapped to an SCA component property. SCA services can be exposed without adding SCA-specific metadata to the Spring application context of the Payment component. Instead, the SCA composite file contains enough information to help the Tuscany runtime locate services and references in the payment application context. The sample that demonstrates how this is done can be found in the contributions directory of the travel-booking sample. Figure 6.2 provides a graphical view of how the Payment bean in the Payment-context.xml is mapped to SCA Payment component.

Figure 6.2. The mapping between the unannotated Spring Payment bean and SCA services, references, and properties

We’ve just looked at the Spring application context itself. In this case it doesn’t have any SCA tags in it. Now let’s look at the SCA composite description that references the Spring application context.

The payment.composite file from the payment-spring sample contribution defines the Payment component using the Payment-context.xml Spring application context for the component implementation.

<component name="Payment">
<implementation.spring location="Payment-context.xml"/>
<service name="Payment">
<binding.ws uri="http://localhost:8080/Payment"/>
</service>
<reference name="creditCardPaymentReference">
<binding.ws uri="http://localhost:8081/CreditCardPayment"/>
</reference>
<property name="transactionFee">1.23</property>
</component>

The Payment component is implemented using an implementation.spring type. The business logic for this component is identified by the location attribute, which, according to the SCA specifications, can point to either an archive file or a directory that contains the Spring application context file. Tuscany extends the specification and also allows the location attribute to be set to the name of a Spring application context file that resides in the same directory as the composite file.

The <service> element within the <component> element shows that Payment-context.xml provides a Payment service. Messages sent to this service are forward by Tuscany to the Spring Payment bean. The <reference> element within the <component> element shows that creditCardPaymentReference is a web service and will be available as a reference within the Spring Payment bean.

It’s important that the component service and reference names included in the composite file match the bean names that are specified in the Spring application context. Otherwise, the Tuscany runtime won’t be able to match the SCA description of the component with the Spring application context.

Our first listing shows the Spring Payment application context for the SCA Payment component.

Listing 6.1. The Payment application context, Payment-context.xml, without SCA tags
<beans ...>
<bean id="Payment"
class="com.tuscanyscatours.payment.impl.PaymentImpl">
<property name="creditCardPayment"
ref="creditCardPaymentReference"/>
<property name="emailGateway" ref="EmailGatewayBean"/>
<property name="transactionFee" value=".5f"/>
</bean>

<bean id="EmailGateway"
class="com.tuscanyscatours.emailgateway.impl.EmailGatewayImpl">
</bean>
</beans>

By default, all the beans defined in the Spring application context become available as services. Therefore, the Payment bean is automatically available as a service. The first property defined for the Payment bean is named creditCardPayment and refers to a creditCardPayment web service that isn’t shown here. The reference creditCardPaymentReference is also referred to by the SCA Payment component in the composite file. The reference name creditCardPaymentReference in the composite file matches the name of the creditCardPaymentReference reference in the Spring application context. This is how the Tuscany runtime realizes which of the beans act as services or are references to other services. The second property defined for the Payment bean refers directly to the local EmailGateway bean defined in the same Spring application context, and the Tuscany runtime respects the local Spring reference in this case and doesn’t try to reconfigure it.

In this example, the payment application context is unmodified. The Tuscany runtime identifies references and services for the SCA Payment component by first finding the Spring application context that provides the implementation for the Payment component. It then introspects it to determine services and references for the Payment component.

This default mechanism may not be ideal at all times. For example, a Spring application developer may want to control precisely which of the beans in the application context are exposed as SCA services. This is possible through custom SCA Spring tags.

6.1.2. Using Spring services and references with SCA tags

The Spring tags that SCA defines can be used in the application context to identify the beans that will be used as SCA services or references. The sample that demonstrates how this is done can be found in the contributions/payment-spring-scatag sample directory.

Figure 6.3 shows how Spring Payment-context.xml can be modified to include SCA extension tags that define SCA services, references, and properties.

Figure 6.3. The mapping between the modified Spring application context and SCA services, references, and properties

As shown in the diagram, the creditCardPayment reference and Payment service are tagged with sca:reference and sca:service, respectively. These tags explicitly describe the artifacts from the Spring application context that can be used in the SCA composition. On the other hand, the EmailGateway bean isn’t described using an SCA tag and can’t be used in the composition. Notice that once SCA tags are used, the defaulting mechanism that was explained in the previous section does not apply. Again the local wiring to the EmailGateway bean is preserved. The next listing shows Payment-context.xml Spring with SCA tags for services, references, and properties.

Listing 6.2. The payment application context, Payment-context.xml, with SCA tags
<beans ...>
<sca:service name="Payment"
type="com.tuscanyscatours.payment.Payment"
target="Payment"/>

<bean id="Payment"
class="com.tuscanyscatours.payment.impl.PaymentImpl">
<property name="creditCardPayment" ref="creditCardPayment"/>
<property name="emailGateway" ref="EmailGateway"/>
<property name="transactionFee" ref="transactionFee"/>
</bean>

<bean id="EmailGateway"
class="com.tuscanyscatours.emailgateway.impl.EmailGatewayImpl">
</bean>

<sca:reference name="creditCardPayment"
type="com.tuscanyscatours.payment.creditcard.CreditCardPayment"/>

<sca:property name="transactionFee"
type="java.lang.Float"/>
</beans>

We’ve looked at how services, references, and properties are mapped to a component’s description in the composite file. Now let’s look in more detail at how properties are set in the SCA composite.

6.1.3. Setting Spring properties

A Spring application can have configuration properties that control how beans should behave. You’ve seen in the previous payment.composite listing that the Payment component defines a property called transactionFee. Let’s change the initial value of this property to 9.73.

<component name="Payment">
<implementation.spring location="Payment-context.xml"/>
...
<property name="transactionFee">9.73</property>
</component>

The section of the Spring application context related to properties follows. Here we’re using SCA tags in the Spring context file. Again, note that the names for the property, as it appears in the composite file and in the application context, need to match in order for Tuscany to map the Spring property to the SCA property.

<bean id="Payment" class="com.tuscanyscatours.payment.impl.PaymentImpl">
<property name="creditCardPayment" ref="creditCardPayment"/>
<property name="emailGateway" ref="EmailGateway"/>
<property name="transactionFee" ref="transactionFee"/>
</bean>

...

<sca:property name="transactionFee"
type="java.lang.Float"/>

If no SCA property tags are included in the Spring context, then the Tuscany runtime will try to match property elements in the SCA composite file with property names it finds in the Spring application context.

6.1.4. Using other SCA Java annotations

Tuscany has added support for annotations in SCA components that are implemented as Spring beans. This is an extension to the SCA Spring Component Implementation Specification. The idea behind this is to add SCA annotations to a Java implementation that will be used as a Spring bean. The annotations describe the behavior of the bean in the overall application composition. We talked about Java annotations in chapter 5. Currently, the basic SCA annotations @Service, @Reference, @Property, @Init, @Destroy, and @ComponentName are recognized in a Spring bean. Because Spring also defines an @Service annotation, you should fully qualify the SCA version of the annotation. For example, the following listing shows the PaymentImpl bean that’s annotated with SCA annotations @Service and @Reference to identify services and references.

Listing 6.3. The Payment Spring bean with SCA annotations
@org.osoa.sca.annotations.Service(Payment.class)
public class PaymentImpl implements Payment {

protected CreditCardPayment creditCardPayment;
protected EmailGateway emailGateway;
protected float processingCharge = 0;

@Reference
public void setCreditCardPayment(CreditCardPayment creditCardPayment) {
this.creditCardPayment = creditCardPayment;
}

public void setEmailGateway(EmailGateway emailGateway) {
this.emailGateway = emailGateway;
}
}

Support for more annotations may be introduced in the future.

6.1.5. Finding the Spring application context

We mentioned earlier that the location attribute of the <implementation.spring> element identifies where the implementation for the implementation.spring type can be found. A Spring context that’s intended to be used as a component implementation must be in the same contribution as the composite file containing the component being implemented. The Tuscany runtime uses the following rules to find it:

  • If the location attribute points directly at a Spring context file, then this file is used as the component implementation.
  • If the location attribute represents an archive file, the META-INF/MANIFEST. MF file is read from the archive.
  • If the location attribute represents a directory, the file META-INF/MANIFEST. MF is expected to appear under this directory.

When a MANIFEST.MF file has been located, the following rules apply as defined by the SCA Spring Component Implementation Specification:

  • If the manifest file contains a header of the following format, then the set of paths specified in the header identify the Spring context configuration files: Spring-Context ::= path( ‘;’ path)*. In this case, path is a relative path with respect to the location URI.
  • If the MANIFEST.MF file isn’t present or there is no Spring-Context header in the MANIFEST.MF, by default Tuscany will build the application context using the application-context.xml file available in the META-INF/spring directory.

Within a Spring application context, further location information can be specified. For example, the Spring framework’s ClassPathXmlApplicationContext bean can be used to reference further Spring application contexts. When used in an application context that’s being used to implement an SCA component in Tuscany, the paths to the application contexts that will be used are assumed to be given relative to the root of the current contribution.

The Spring FileSystemXmlApplicationContext bean isn’t supported when implementing SCA components in Tuscany because this could allow the application context to reference other application contexts outside the SCA contribution.

Let’s conclude this section with a reminder that because implementation.spring is defined by the SCA specifications and isn’t a Tuscany extension, it resides under the OSOA SCA specification namespace (http://www.osoa.org/xmlns/sca/1.0). The implementation type that supports BPEL processes is also defined in an SCA specification, so we’ll look at that next.

6.2. Implementing components using BPEL

The SCA Client and Implementation Model Specification for WS-BPEL describes the extension implementation type implementation.bpel and can be found at the following URL: http://www.osoa.org/download/attachments/35/SCA_ClientAndImplementationModelforBPEL_V100.pdf. The implementation.bpel type plays the same role as any other implementation extension in SCA, as shown in figure 6.4. Feel free to skip this section if you’re not planning to use BPEL in your SCA application.

Figure 6.4. Implementation.bpel provides a WS-BPEL implementation for an SCA component.

Generally a BPEL process is used to describe business processes in software. Typically a business process captures a sequence of ordered activities that must be performed. Decisions made during the process are captured as branches in the sequence of activities.

The idea of developing business process management software to coordinate business-level activities grew out of a desire to describe and automatically manage business processes at a higher level than in a programming language such as Java.

An application based on SOA principles typically consists of a number of loosely coupled interacting services. The processes within a business define the way that these services interact, and hence BPEL and SOA fit well together. SCA describes the network of services, whereas BPEL can be used to coordinate their activities.

As you’ve seen in the previous chapter, the job of organizing a set of SCA service interactions, for the Java language programmer, is a simple matter of writing a component implementation in the Java language that calls the right operations on the available references in the correct order. But BPEL has been specifically designed to express a business process as a sequence of web service calls, so it offers a useful alternative.

In this section we’ll take a quick look and refresh our memory of how BPEL processes are laid out in XML. This is important, because we’ll then move on to look at how SCA and Tuscany map BPEL concepts to component services, references, and properties.

Don’t worry if you’re not a BPEL expert. This is the first time we’ve presented a component implementation technology that isn’t based on the Java language. If you’ve reached this point because you’re interested in alternative implementation technologies, then you’ll be glad to know that the SCA bits remain the same. The part that changes is how these map onto the BPEL programming model. This is true for any component implementation technology. You just need to find the parts of the technology that represent services, references, and properties.

6.2.1. The structure of a BPEL process document

The Web Service Business Process Execution Language standards have been developed in the OASIS WSBPEL Technical Committee (http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsbpel). BPEL allows developers to describe a business process as a sequence of calls to web services. As a language for describing business processes, it has many things that a programmer would recognize, such as variables and conditional statements.

Space in this book doesn’t allow for a detailed description of all of the many features of BPEL, but in this section we’ll highlight the main structure of a BPEL document. This will help us describe how these features are mapped to the familiar SCA concepts of component services, references, and properties and hence how a BPEL process can be used to implement an SCA component.

Listing 6.4 shows the outline of a BPEL process used to implement the Payment component. As before, this component is expected to take payments from customers. To achieve this, the Payment component must arrange for a credit card payment to be taken and then must send an email to the customer confirming that the payment has been taken. This is becoming a familiar scenario now, and it’s a simple process when expressed in BPEL.

Listing 6.4. The outline of a BPEL process document
<process name="Payment" ...>
<import location="Payment.wsdl" .../>
<import location="CreditCardPayment.wsdl" .../>
<import location="EmailGateway.wsdl" .../>

<partnerLinks>
<partnerLink name="paymentProcessPartnerLink" .../>
<partnerLink name="creditCardPaymentPartnerLink" .../>
<partnerLink name="emailGatewayPartnerLink" .../>
</partnerLinks>

<variables>
<variable name="makePaymentRequestMessage"
messageType="pp:MakePaymentRequest"/>
...
</variables>

<sequence>
<receive name="start" .../>

<assign name="createCreditCardRequest">
...
</assign>

<invoke name="invokeCreditCardPayment" .../>

<assign name="createEmailGatewayRequest">
...
</assign>

<invoke name="invokeEmailGateway" ... />

<assign name="createResponse">
...
</assign>

<reply name="end" .../>
</sequence>
</process>

Some of the detail has been omitted in order to clearly show how the main elements in the BPEL process appear. The <partnerLink> elements describe how the process interacts with other services, the <variable> elements hold data as the process progresses, and the <sequence> element holds the activities that describe the steps in the business process.

Partner Links

To be useful, a BPEL process has to be able to call and be called by other services or partners. Partner links describe connections with other services in terms of WSDL 1.1 port types. A partner link can describe the roles of both communicating parties and therefore can be associated with two roles. myRole refers to the role that the BPEL process plays, and partnerRole refers to the role that the partner plays in any interaction.

Variables

As a business process continues, state can be accumulated using variables. Variables can, for example, hold incoming message data or the data that results from calling other services. Variables can be further transformed and assigned to other variables and then used as the input to other services.

Activities

The main building blocks of a BPEL process are activities. A number of activities are defined by BPEL, including

  • <receive>—Wait for a message to arrive
  • <invoke>—To invoke a web service
  • <if>—Branch based on an expression

Activities are strung together within a BPEL <sequence> and can be nested in various ways in order to represent decisions, concurrency, and asynchronicity in a business process.

Much more detailed information can be found by looking at the OASIS WSBPEL specifications, but this should provide enough of a refresher in order for you to understand how a BPEL process can be used to implement an SCA component. Let’s carry on now and look at just that.

6.2.2. BPEL in Tuscany and SCA

From the SCA point of view, a BPEL process defines a component type that maps partner links to SCA component services and references. The sample that demonstrates how this is done can be found in the contributions/payment-bpel and contributions/ payment-bpel-process directories of the travel-booking sample.

Figure 6.5 shows an overview of how the mapping takes place.

Figure 6.5. Mapping partner links to SCA component services and references

The SCA specification also maps the variables of a BPEL process to SCA properties, although the Tuscany runtime doesn’t support this at the time of writing.

For the payment process example, the following listing shows the component type derived from the partner links in the BPEL process shown in figure 6.4.

Listing 6.5. The component type derived from the payment BPEL process
<componentType xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:wsdli="http://www.w3.org/2006/01/wsdl-instance"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">


<service name="paymentProcessPartnerLink">
<interface.wsdl interface=
"http://www.example.org/PaymentProcess/#wsdl.interface(PaymentProcess)"/>
</service>

<reference name="creditCardPaymentPartnerLink">
<interface.wsdl interface=
"http://.../CreditCardPayment/#wsdl.interface(CreditCardPayment)"/>
</reference>

<reference name="emailGatewayPartnerLink">
<interface.wsdl interface=
"http://www.example.org/EmailGateway/#wsdl.interface(EmailGateway)"/>
</reference>


</componentType>

Note that the service and reference names map directly to the names of the partner links as they appear in the BPEL process. Figure 6.6 gives a pictorial overview of how the BPEL partner links from our payment process resolve to SCA services and references.

Figure 6.6. Mapping between SCA service and references and BPEL partner links

The arrows in figure 6.6 show the flow of control from the SCA service, through the BPEL process partner links and activities, and out through SCA references.

A message arrives, via an SCA binding, at an SCA service. The SCA service equates to a BPEL partner link. In this case, the incoming message gives rise to the BPEL <receive> action executing. Within the <receive> action, two <invoke> actions create messages that are sent out via related partner links. These partner links relate to SCA references, and hence the messages are sent out over SCA bindings to the target services configured in the composite file.

The BPEL concept of a partner link corresponds to both SCA services and references. In BPEL a partner link is designed to describe the relationship between two services where both services can originate messages. A partner link type can include two roles to describe the role at each end of the link and what interface the role implies.

Partner links themselves explicitly describe myRole and partnerRole with reference to the WS-BPEL process in question. Figure 6.7 shows how these roles map to the interfaces of services and references.

Figure 6.7. The mapping between partner link roles and SCA interfaces on services and references

If you’re at the service end, then the forward interface describes the interface that the BPEL process exposes and hence maps to myRole, the role that the WS-BPEL process is playing. The partnerRole then describes the role that the calling service plays and the interface that it exposes. In SCA terminology, this is the callback interface.

At the reference end it’s the other way round, where the forward interface corresponds to the partner role as the BPEL process calls the partner service. The myRole for the WS-BPEL process in this case is to provide a callback interface. Note, though, that Tuscany doesn’t yet support callbacks for components implemented using implementation.bpel.

Partner link roles map to WSDL port types. Hence, the forward and callback interfaces that a partner link represents are clearly described in a language that the Tuscany runtime understands. The Tuscany runtime is able to read the WSDL descriptions associated with partner links, and no special mapping is required to interpret the interfaces that BPEL scripts provide or require.

Let’s look in detail at how BPEL partner links map to SCA services.

6.2.3. Mapping WS-BPEL partner links to SCA services

The SCA Client and Implementation Model Specification for BPEL describes in detail the set of rules that should be applied for identifying the services and references for BPEL processes. SCA services map to those partner links whose roles are set such that the BPEL process is the receiver of a message. All other partner links map to SCA references.

The payment BPEL process can be found in the payment.bpel file from the payment-bpel-process contribution. Looking at this BPEL process in more detail, you can see that the process is initiated by a <receive> action:

<receive name="start"
partnerLink="paymentProcessPartnerLink"
portType="pp:PaymentProcess"
operation="makePayment"
variable="makePaymentRequestMessage"
createInstance="yes"/>

Clearly this action waits to receive a message. The paymentProcessPartnerLink is referred to here, and the forward interface that this partner link specifies will be a service interface for this process.

A BPEL process can also be started by <onMessage> and <onEvent> elements. These result in the BPEL process taking some action based on an incoming message, and so partner links associated with these elements will also map to SCA services.

Looking in more detail at the paymentProcessPartnerLink, you can see how it’s defined within the BPEL process:

<partnerLink name="paymentProcessPartnerLink"
partnerLinkType="pp:PaymentProcessLinkType"
myRole="forward" />

The partner link type pp:PaymentProcessLinkType defines the forward interface for this partner link. As we said, in this scenario, this partner link defines the service interface that the BPEL process exposes. Typically, the partner link type will be defined in the WSDL file for the payment process, Payment.wsdl in this case, in the following way:

<plnk:partnerLinkType name="PaymentProcessLinkType">
<plnk:role name="forward" portType="tns:PaymentProcess"/>
</plnk:partnerLinkType>

The partner link type refers to a WSDL port type called tns:PaymentProcess, and hence the interface contract for the service that the BPEL process exposes can be established.

Note that in this case the partner link type defines only a single role named forward. Notice also that the myRole="forward" attribute of the partner link matches the defined role on the partner link type. In partner link terminology, myRole is the role of the BPEL process, and this specifies that the BPEL process provides a service with the interface defined by the port type tns:PaymentProcess. With a single role, this partner link defines a forward-only service interface. If a partnerRole were defined, then this would describe a callback interface that the partner provides.

Looking back, you see that the <receive> action exploits the same port type as the forward role. Hence, when it comes time to specify the SCA service, you see that the interface refers to the same PaymentProcess port type:

<service name="paymentProcessPartnerLink">
<interface.wsdl interface=
"http://www.example.org/PaymentProcess/#wsdl.interface(PaymentProcess)"/>
</service>

Note that the names of the services and references that you specify in the composite file must match the names of the partner links that appear in the BPEL process.

The Tuscany runtime is able to introspect the BPEL process and generate a component-type model based on the partner links that it finds. Any services and references that are identified can then be configured with information, such as binding configuration, in the composite file.

Partner links that describe the role of the BPEL process as the receiver of a message are mapped to services. Any other partner links are mapped to references, so let’s look at references in a little more detail.

6.2.4. Mapping WS-BPEL partner links to SCA references

Any partner links that aren’t identified as services map to SCA references. In the case of the payment process, let’s look at the <invoke> elements and the partner links that they use. A good example is the invoke element that calls the EmailGateway service.

<invoke name="invokeEmailGateway"
operation="sendEmail"
inputVariable="sendEmailRequestMessage"
outputVariable="sendEmailResponseMessage"
partnerLink="emailGatewayPartnerLink"
portType="eg:EmailGateway" />

Note that a partner link is referenced. In this case it’s the emailGatewayPartnerLink, which is defined in the following way:

<partnerLink name="emailGatewayPartnerLink"
partnerLinkType="eg:EmailGatewayLinkType"
partnerRole="forward"
initializePartnerRole="yes" />

The partner link type in this case is as follows:

<plnk:partnerLinkType name="EmailGatewayLinkType">
<plnk:role name="forward" portType="tns:EmailGateway"/>
</plnk:partnerLinkType>

Again the partner link has only one role, and it defines the forward interface between the payment process and the email gateway. In this case, the forward role is defined as being the partnerRole. The partner role refers to the partner with which the BPEL process is interacting, the email gateway service in this case. The EmailGateway port type is associated with the forward role, so this is the port type that the email gateway service provides and that the reference to the email gateway will use.

In the composite file we can define a reference with the same name as the partner link and define the reference’s interface and bindings in the normal way.

<reference name="emailGatewayPartnerLink">
<interface.wsdl interface=
"http://www.example.org/EmailGateway/#wsdl.interface(EmailGateway)"/>
</reference>

This reference has the default multiplicity of 1..1 and hence can only be connected to a single service. The SCA Client and Implementation Model Specification for WS-BPEL describes the set of rules that determine how references with other multiplicities are identified, but these depend on SCA extensions being included in the BPEL script, and these aren’t yet supported by the Tuscany runtime.

6.2.5. Handling errors

BPEL defines an extensive set of mechanisms for catching and throwing business and systems faults during the execution of a business process. If you look at the SCA Client and Implementation Model Specification for WS-BPEL, you’ll note that it doesn’t describe how faults are dealt with.

Currently the Apache Tuscany runtime will return faults thrown by the BPEL script but won’t pass faults through references that are returned by services that the WSBPEL script itself calls. Lifting this limitation would be good place to start for those who are interested in BPEL and who are also interested in contributing to the Tuscany code base.

6.2.6. Limitations of implementation.bpel in Tuscany 1.x

The SCA Client and Implementation Model Specification for WS-BPEL defines a set of BPEL extensions. None of these extensions are yet supported by the Tuscany runtime. The lack of support for these extensions means that the following features aren’t supported:

  • Properties
  • Multivalued references

The Tuscany runtime also lacks support for the following features:

  • interface.partnerLinkType
  • Local partner links
  • Conversations
  • Callbacks
  • Faults across references
  • Implementation policies

It’s hoped that these restrictions will be lifted as more features are added to the implementation.bpel module in Tuscany.

 

Locating the Apache ODE runtime database

Tuscany relies on the Apache ODE BPEL engine to provide support for running BPEL scripts. The ODE engine itself relies on a Derby database being in place, and in our samples you’ll see that Maven is configured, through a maven-dependency-plugin target, to unpack the following artifact:

<groupId>org.apache.ode</groupId>

<artifactId>ode-dao-jpa-ojpa-derby</artifactId>

The result of this is that, when run from Maven, each sample has a Derby database automatically added to its arget est-classesjpadb directory before the test cases are run. Hence, the ODE engine is able to find the database that it requires.

 

Now that you’ve seen how WS-BPEL can be exploited from within an SCA composite application, let’s move on and look at how scripts can similarly be used to implement SCA components.

6.3. Implementing components using scripts

The SCA specifications don’t yet define any implementation types that allow scripting languages to be used to provide component implementations. Tuscany does provide an extension that exploits the Apache Bean Scripting Framework (BSF) to provide a scripting implementation type. You can implement components using BSF-compliant scripts by using the <implementation.script> element. Feel free to skip this section if you’re not planning to use scripts in your SCA application.

6.3.1. BSF-based script implementations in Tuscany and SCA

BSF is a subproject of the Apache Jakarta project (http://jakarta.apache.org/bsf/) and is designed to provide a generic interface for embedding various types of scripting engines, such as Python (using Jython), Ruby, and Groovy, into Java applications.

Therefore, by using implementation.script you can build component implementations using any of the scripting languages that BSF 3 supports. Figure 6.8 shows how the implementation.script type provides an SCA component implementation.

Figure 6.8. Implementation.script allows SCA components to be implemented using those scripting languages supported by the Bean Scripting Framework from the Apache Jakarta project.

Again we’ll use the Payment component example to show how a script can be used for a component implementation. We’ll use Groovy as the scripting language of choice here to show how services, references, and properties are mapped. The principles applied here apply to the other scripting languages supported by BSF. You can find the sample in contribution/contributions/payment-groovy.

If you want to see one of the other script environments supported by BSF in action, we’ve also provided a Python version of the Payment component. You can find this in the payment-python contribution. It’s similar to the Groovy version, so we’ll stick with Groovy for following discussion.

Following is the Groovy script that provides the Payment component implementation. This script can be found in the file payment/PaymentImpl.groovy.

Listing 6.6. A Groovy script payment component implementation
def makePaymentMember(customerId, amount) {

def finalAmount = amount + transactionFee;

scatours.emailgateway.EmailType email =
new scatours.emailgateway.EmailType();
email.setTo(customerId);
email.setTitle("Payment " + finalAmount + " Received");

emailGateway.sendEmail(email);

return "Success";
}

In this example we’ll show the makePaymentMember() operation, where the customer is expected to already be a registered member of the TuscanySCATours website. The call to the credit card details component is omitted in this case. The code shows the call being made to the email gateway component. The component is defined in the payment composite file in the following way:

<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
targetNamespace="http://tuscanyscatours.com/"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
name="payment">
<component name="PaymentComponent">
<tuscany:implementation.script script="payment/PaymentImpl.groovy"/>
<service name="Payment">
<interface.java interface="payment.Payment" />
</service>
<reference name="emailGateway" target="EmailGatewayComponent">
<interface.java interface="scatours.emailgateway.EmailGateway" />
</reference>
<property name="transactionFee" type="xsd:float">9.73</property>
</component>
<composite/>

Note that <implementation.script> is in the Tuscany namespace because it’s not defined in the SCA specifications.

6.3.2. Defining interfaces for script-based SCA services and references

Scripting languages tend to be dynamically typed and generally don’t provide a mechanism for statically describing the interfaces exposed by the services they provide or for the references they consume.

Apache Tuscany exploits the information provided by the developer through the composite file and through a component type file, if present, to determine the type of the various interfaces that a script uses.

If interface information isn’t available through one of these two files, then the Tuscany runtime assumes that a dynamic invocation is required. In this case, it takes the operation name from the incoming message and invokes BSF. In this way, script writers can either construct a component type file manually to explicitly identify services, references, and properties or rely on the information in the script and the composite file to form the component type. This approach for determining the interfaces in use is the same regardless of which scripting language is used.

6.3.3. Mapping between SCA services and scripts

In general, each operation declared in the script maps to a service defined on the component in the composite file. In our payment example, the Groovy script declares an operation called makePaymentMember. In the composite file, the service is defined in the usual way:

<service name="Payment">
<interface.java interface="payment.Payment" />
</service>

The interface is defined using the Java payment.Payment interface. The Tuscany runtime introspects the Java payment.Payment interface and finds the makePaymentMember operation. The runtime then uses BSF to locate the makePaymentMember in the Groovy script. When a message arrives, Tuscany is able to direct the message to the correct function in the script and uses BSF to load the script and run that operation.

Because scripts tend to be dynamically typed, Tuscany relies on the interface information provided through the composite file or optionally through the component type file in order to perform appropriate transformations on messages arriving from a service binding.

6.3.4. Mapping between SCA references and scripts

A similar approach works for references. You’ll note that there’s no annotation in the Groovy script that identifies references. The Tuscany runtime injects fields into the script context based on the references it finds in the component definition. In this case, the emailGateway reference is injected:

<reference name="emailGateway" target="EmailGatewayComponent">
<interface.java interface="scatours.emailgateway.EmailGateway" />
</reference>

Again a Java interface is used to describe the reference interface. This reference is now available in the script environment and is used as follows:

emailGateway.sendEmail(email);

The script writer didn’t explicitly define the emailGateway variable but used it in the knowledge that the Tuscany runtime will inject it automatically. References are differentiated from properties based on the configuration that appears in the composite file.

6.3.5. Mapping between SCA properties and scripts

The property definitions that appear in the composite file are used by the runtime to inject property values into the script context:

<property name="transactionFee" type="xsd:float">9.73</property>

The runtime then makes a property, called transactionFee, available in the script without the script having to define the property. You can see in our example that the processing charge is added to the amount being charged:

def finalAmount = amount + transactionFee;

You can define properties in the script itself if you need to use the script outside the context of the SCA component.

The automatic insertion of references and properties may look a little odd because the script developer hasn’t defined these variables explicitly. You may be wondering how they know what variable names to use, but implementation.script has been designed with the expectation that the script developer will develop the script in conjunction with the component description. This gives the developer an easy way of associating any of the Tuscany bindings with a script without any script-specific code being required.

6.3.6. Handling errors

If the Bean Scripting Framework experiences a problem in executing a script that it’s hosting, then, in theory, it will throw a ScriptException. Currently the Tuscany runtime is set up to catch this exception and add it to the response message. At the time of writing, however, there’s an issue with the runtime in that BSF isn’t throwing exceptions when it should.

Improving the way that script errors are handled would be a good project for those interested in contributing to the Tuscany and possibly the BSF code bases.

6.4. Summary

In the early chapters of the book you learned how SCA offers a technology-agnostic component model. Its support of various component implementation types enables different technologies to work with one another in an SCA composite application. Two components implemented using different technologies can communicate with each other across any of the Tuscany bindings.

This chapter has offered a technical introduction to three of the many component implementation types that Tuscany supports today. By now, you’ve learned how to implement components using Spring, BPEL, and scripting languages. This provides a good demonstration of the flexibility of SCA to embrace implementation technologies.

Tuscany has more implementation types in development, for example, EJB, Java EE, and Web, and the list is growing as the community contributes new implementation types by leveraging Tuscany’s extensible architecture. Look forward to chapter 14 if you want to know how new implementation types can be added using Tuscany’s implementation extensibility point.

Now that you have a good grounding in implementing SCA components, let’s move on and explore how you can connect components using different communication protocols by configuring SCA bindings.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.32.76