How do I create an SCA component/Composite?
The below sections use the SCA java programming model to describe the annotations that are available, followed by an example.
Brief Overview of Annotations
The below is a very brief overview of the Annotations in SCA. This is just meant as a cursory reference. Please refer the SCA spec for details.
@Service
A Java class component uses @Service annotation to specify the interface of the services implemented.
A Java class component uses @Service annotation to specify the interface of the services implemented.
@Remotable
This annotation defines a remotable service in the Java interface of the service. Remotable services use by-value data exchange semantics.
This annotation defines a remotable service in the Java interface of the service. Remotable services use by-value data exchange semantics.
Local service
A local service can only be invoked by clients that are part of the same module. A Java local service interface is defined without a @Remotable annotation.
@AllowPassByReference
@AllowPassByReference
This annotation on the implementation of a remotable service is used to declare that whether
it allows pass by reference data exchange semantics on calls to it.
Local services use by-reference data exchange semantics, so changes made to parameters are seen by both the client and the service provider.it allows pass by reference data exchange semantics on calls to it.
A @Scope annotation on either the service's interface definition or on the service class denotes a scoped service. The scope values could be:
- stateless: This is the default and each request in this mode is handled separately.
- request: In this mode the requests are directed to the same Java interface for all local service invocations that occur while servicing a remote service request.
- session : In this mode the requests are directed to the same Java instance for all requests in the same "session".
- module :In this mode the requests are directed to the same Java instance for all requests within the same "module".
The SCA runtime will prevent concurrent execution of methods on an instance of these implementations except for the module scoped one.
Lifecycle methods on a scoped service are implemented using @Init(called only once at the start of its scope and after its properties and references have been injected) annotation and @Destroy(called when its scope ends) annotation.This annotation on a field or method in the Java class defines the configuration properties of a Java component implementation. It takes the name of the property and the boolean to specify whether injection is required.
@ReferenceThis annotation is used to acquire access to a service using reference injection it takes the name of the reference and whether it is required.
@ContextThis annotation along with a field of type ModuleContext is used to access a service.
@OnewayThis annotation is used to mark a non-blocking method. The method returns immediately allowing the client to continue execution.
These annotations along with @Scope is used to implement conversational services. A session is used to maintain information about a single conversation between a client and a remotable service. Thus, SCA simplifies the design of conversational services while leaving the details of ID generation, state management and routing to the SCA container.
@Callback
This annotation can be used to provide callback services on a remotable service interface. It takes the Java Class object of the interface as a parameter. The Callback service provides asynchronous communication from a service provider to its client.
Examples (Taken from Apache Tuscany)
Catalog Interface
package abc;
import org.oasisopen.sca.annotation.Remotable;
@Remotable
public interface Catalog {
Item[] get();
}
Cart Interface
@Remotable
public interface Cart extends Collection<String, Item> {
}
Total Interface
@Remotable
public interface Total {
String getTotal();
}
Catalog Interface Implementation
package abc;
import org.oasisopen.sca.annotation.Init;
import org.oasisopen.sca.annotation.Property;
import org.oasisopen.sca.annotation.Reference;
public class FruitsCatalogImpl implements Catalog {
@Property
public String currencyCode = "USD";
@Reference
public CurrencyConverter currencyConverter;
private List<Item> catalog = new ArrayList<Item>();
@Init
public void init() {
//some code
}
public Item[] get() {
return catalogArray;
}
}
Shopping Cart Implementation
package abc;
import org.apache.tuscany.sca.data.collection.Entry;
import org.apache.tuscany.sca.data.collection.NotFoundException;
import org.oasisopen.sca.annotation.Init;
import org.oasisopen.sca.annotation.Scope;
@Scope("COMPOSITE")
public class ShoppingCartImpl implements Cart, Total {
private Map<String, Item> cart;
@Init
public void init() {}
public Entry<String, Item>[] getAll() {
return entries;
}
public Item get(String key) throws NotFoundException {
//return item
}
public String post(String key, Item item) {
//put in cart and return key.
return key;
}
public void put(String key, Item item) throws NotFoundException {
//update item
}
public void delete(String key) throws NotFoundException {}
public Entry<String, Item>[] query(String queryString) {
}
public String getTotal() {
//return total
}
}
SCDL File
<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1"
targetNamespace="http://store"
name="store">
<component name="Store">
<tuscany:implementation.widget location="uiservices/store.html"/>
<service name="Widget">
<tuscany:binding.http uri="/store"/>
</service>
<reference name="catalog" target="Catalog"/>
<reference name="shoppingCart" target="ShoppingCart/Cart"/>
<reference name="shoppingTotal" target="ShoppingCart/Total"/>
</component>
<component name="Catalog">
<implementation.java class="services.FruitsCatalogImpl"/>
<property name="currencyCode">USD</property>
<service name="Catalog">
<tuscany:binding.jsonrpc uri="/Catalog"/>
</service>
<reference name="currencyConverter" target="CurrencyConverter"/>
</component>
<component name="ShoppingCart">
<implementation.java class="services.ShoppingCartImpl"/>
<service name="Cart">
<tuscany:binding.atom uri="/ShoppingCart/Cart"/>
</service>
<service name="Total">
<tuscany:binding.jsonrpc uri="/ShoppingCart/Total"/>
</service>
</component>
<component name="CurrencyConverter">
<implementation.java class="services.CurrencyConverterImpl"/>
</component>
<service name="CompositeWidget" promote="Store/Widget">
<tuscany:binding.http uri="/compositestore"/>
</service>
</composite>
No comments:
Post a Comment