Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

The implementation of the single template Number service needs a mechanism to dynamically determine its current state or value at runtime. It gets this from CXF based on the target EndpointReference. It then proceeds to determine if the current value is even and returns the result to the caller.

...

No Format
EndpointReferenceType create(int val) {
   synchronized (this) {
     if (!servicePublished) {
        publishSingleInstanceServant(SERVICE_QNAME);
        servicePublished = true;
     }
   }
   String state = String.valueOf(val);
   String portName = null; // unless there are multiple ports in the service 
   return EndpointReferenceUtils.getEndpointReferenceWithId(SERVICE_QNAME, 
              portName, state, BusFactory.getDefaultBus()); 
 }

Here is the skeleton implementation of Number.isEven():

No Format
 

    @Resource
    protected WebServiceContext wsContext;
    
    public boolean isEven() {

        MessageContext messageContext = wsContext.getMessageContext();
        String state = EndpointReferenceUtils
            .getCurrentEndpointReferenceId(messageContext);
        
        int val = Integer.parseInt(state);
        return valIsEven(val);
    }
How does it Work

The API uses WS-Addressing(WS-A) reference parameters to embed the users state in an EndpointReference. The reference parameters are part of the EPR that is returned to the caller. WS-A interceptors are used to propagate the reference parameters as a soap header on subsequent invocations using the returned EPR. On the receiving side, the current WS-A MEPs are queried to extract the state from the reference parameters.

...

WS-A provides a transport/protocol neutral approach to state transfer and is the default mechanism for multiplexing supported by CXF. However some transports, notably HTTP, have implicit support for multiplexing in the form of contexts and query parameters. The CXF HTTP transport supports a multiplexWithAddress configuration attribute that when enabled, negates the use of WS-A and forces the state to be embedded in the URL context.

For example, in the Number scenario above, the single Number service endpoint would publish a URL of the form: http://host:port/NumberService/Number/Image Removed with a URL matching strategy of stem. A call to NumberFactory.create(22) would result in an EPR that contained the address element http://localhost:9080/NumberService/Number/22Image Removed. In this way, the multiplex state becomes a natural part of the HTTP endpoint address URL which can be consumed by native HTTP clients.

The multiplexWithAddress property for HTTP is enabled by adding the following to cxf.xml

No Format

<bean name="<port name>.http-destination" abstract="true">
  <property name="multiplexWithAddress" value="true"/>
</bean>

<!-- or for all http ports (using a wildcard) -->
<bean name="*" abstract="true" class="org.apache.cxf.transport.http_jetty.JettyHTTPDestination">
  <property name="multiplexWithAddress" value="true"/>
</bean>
Using EndpointRefernces with a JAX-WS Service

...

Sample JAX-WS client code would do the following to access a Number instance using an EPR -

No Format
 

    NumberFactoryService service = new NumberFactoryService();
    NumberFactory factory = service.getNumberFactoryPort();
        
    EndpointReferenceType epr = factory.create("20");
    NumberService numService = new NumberService();
    ServiceImpl serviceImpl = ServiceDelegateAccessor.get(numService);                   
    Number num = (Number)serviceImpl.getPort(epr, Number.class);
    ...