You can create services that use Service Component Architecture
(SCA) OASIS specifications to asynchronously run request-response
services.
Before you begin
To learn about asynchronous invocations of SCA services,
see the SCA OASIS Java Common Annotations and APIs specification.
For a list of common annotations in SCA OASIS specifications, see http://docs.oasis-open.org/opencsa/sca-j/javadoc/index.html.
About this task
To develop an asynchronous SCA service, you can create
three files:
- A Java service interface
that uses the SCA OASIS @AsyncInvocation annotation
and, for exception errors, the @AsyncFault annotation
- A Java service implementation that has an @Service annotation
which refers to the service interface
- An SCA OASIS composite
Procedure
- Create an asynchronous service interface.
You
can derive an interface from the business interface between the client
and the service. For example, suppose that the service has the following
business interface:
package broker;
public interface StockQuote {
float getPrice(String symbol) throws UnknownSymbolException;
}
Copy the business interface and modify it to create
an equivalent asynchronous service interface:
package broker.impl;
import broker.UnknownSymbolException;
import org.oasisopen.sca.ResponseDispatch;
import org.oasisopen.sca.annotation.AsyncFault;
import org.oasisopen.sca.annotation.AsyncInvocation;
@AsyncInvocation
public interface StockQuote {
@AsyncFault(UnknownSymbolException.class)
void getPriceAsync(String symbol, ResponseDispatch<Float> dispatch); }
An asynchronous service interface is a contract between the
SCA container and the service implementation. It is not used by the
client.
Use the @AsyncInvocation annotation
on the interface to indicate it is asynchronous. Derive each method
from its equivalent method in the business interface as follows:
- Append the characters Async to the method name.
- Change the return type to void.
- Add a ResponseDispatch argument which is typed
by the method’s original return type.
- Move exceptions from the throws clause to @AsyncFault annotations.
For simplicity, use the same simple name for the asynchronous
service interface as for the business interface, but specify a different
package name. By default, an SCA service name is the simple name of
its interface, so using the same interface names helps to ensure that
a consistent SCA service name is used.
- Create the asynchronous service implementation.
For example, create an implementation that references
the StockQuote SCA service interface:
package broker.impl;
import broker.UnknownSymbolException;
import org.oasisopen.sca.ResponseDispatch;
import org.oasisopen.sca.annotation.Service;
@Service(StockQuote.class)
public class StockQuoteImpl {
public void getPriceAsync(String symbol, ResponseDispatch<Float> dispatch) {
if (!isValidSymbol(symbol))
dispatch.sendFault(new UnknownSymbolException());
else
dispatch.sendResponse(getPrice(symbol));
}
private boolean isValidSymbol(String symbol) {
// fill in
}
private Float getPrice(String symbol) {
// fill in
}
}
The @Service annotation
must refer to the asynchronous service interface.
Each method
is passed a ResponseDispatch object which must be
used to return a response to the client. The example shows the response
being sent inside the method body but this is not required. The method
can save the input arguments, including the ResponseDispatch object,
for another thread to handle.
Do not perform a long-running
computation directly in the method body because this might cause the
client to receive a timeout exception. Instead, queue the work to
another thread. One approach for queueing work to another thread is
to use an asynchronous bean.
- Create a composite file.
For example,
create an SCA OASIS composite that defines an implementation.java component
which uses the implementation StockQuoteImpl class:
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
targetNamespace="http://www.example.com" name="StockQuoteComposite">
<component name="StockQuoteComponent">
<implementation.java class="broker.impl.StockQuoteImpl"/>
</component>
</composite>
Asynchronous services
must use the binding.sca binding type because it
is the only binding that supports asynchronous invocation. However, binding.sca is
the default binding so you do not need to include it in the composite
file.
What to do next
Develop an asynchronous SCA client to run an SCA service.