cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Tully, Gary" <Gary.Tu...@iona.com>
Subject RE: Support for stateful services in CXF
Date Thu, 19 Apr 2007 19:10:53 GMT
Hi,
I have submitted a patch[1] via
https://issues.apache.org/jira/browse/CXF-542 that provides support for
stateful services.
The implementation uses WS-A referenceParameters to encode the state
which is provided in the form of a String. It works for HTTP and JMS and
any other transport that want to extend AbstractMultiplexDestination.
The HTTP destination supports a config attribute called
multiplexWithAddress which forces it to embesd the id in the URL context
and negates the need for WS-A. This property is false by default.

The API used by application programmers is in EndpointReferenceUtils.
Once  a single template or multiplex service is published, the
getEndpointReferenceWithId() method allows unique (identified by a
String id) references to this service to be generated. During dispatch,
the template or multiplex service can determine the current id using
getEndpointReferenceId(). This state can then be used to service the
request. A typical scenario would use the state as a key to a database
table. 

The salient server side API is as follows:
 
   /**
     * Obtain a multiplexed endpoint reference for the deployed service
that contains the provided id
     * @param serviceQName identified the target service
     * @param portName identifies a particular port of the service, may
be null
     * @param id that must be embedded in the returned reference
     * @param bus the current bus
     * @return a new reference or null if the target destination does
not support destination multiplexing  
     */
    public static EndpointReferenceType getEndpointReferenceWithId(QName
serviceQName, 
 
String portName, 
 
String id, 
                                                                   Bus
bus);
    
    /**
     * Obtain the id String from the endpoint reference of the current
dispatch. 
     * @param contextMap the current message context 
     * @return the id embedded in the current endpoint reference or null
if not found
     */
    public static String getEndpointReferenceId(Map messageContext);


On the client, ServiceImpl now supports getPort(EndpointReferenceType),
an API that is not unlike JAX-WS 2.0 that makes it easy for a client to
directly use an EndpointReference. More details can be found below in
this thread. 

I had a quick chat with Eoghan via IM who will give this the once over
tomorrow and with a bit of luck the required blessing.
Comments welcome.

Thanks,
Gary.

[1]
https://issues.apache.org/jira/secure/attachment/12355834/multiplex-cxf-
542.1.patch

> -----Original Message-----
> From: Glynn, Eoghan [mailto:eoghan.glynn@iona.com] 
> Sent: 05 April 2007 11:16
> To: cxf-dev@incubator.apache.org
> Subject: RE: Support for stateful services in CXF
> 
> 
> 
> All good stuff, Gary.
> 
> Just one small point to clarify ... suppose the transport in 
> use (say HTTP or CORBA) has a native mechanism for encoding 
> the uniqueID (burned into the URI or object key). Would it 
> make sense to *also* slap the uniqueID in the EPR reference 
> params, so that if the client happens to have WS-A enabled, 
> then the uniqueID is passed in the transport neutral way? 
> Whereas if WS-A is not enabled in the client-side dispatch 
> chain, then the "redundant" reference params in the EPR have 
> no real effect on the client processing, so no harm done. 
> This belt'n'braces approach could be configurably enabled. 
> 
> Or maybe it would make more sense to just allow these 
> special-case transports (HTTP or CORBA) to choose either the 
> native XOR the transport-neutral uniqueId encodings, again 
> driven by config.
> 
> Cheers,
> Eoghan
>  
> 
> > -----Original Message-----
> > From: Tully, Gary [mailto:Gary.Tully@iona.com]
> > Sent: 04 April 2007 17:40
> > To: cxf-dev@incubator.apache.org
> > Subject: RE: Support for stateful services in CXF
> > 
> > Hi Bernd, all,
> > 
> > I have been toying around with my default servant test cases and 
> > implementing as I go. My test case determines if Numbers 
> are even by 
> > accessing a particular Number instance from a NumberFactory (via 
> > create) and using the returned reference to invoke the isEven() 
> > operation.
> > Trivial but illustrative I hope. 
> > To make the implementation work/scale on the Server, a single 
> > stateless servant represents all possible numbers and 
> determines its 
> > current identity based on the details of its current/target 
> Endpoint 
> > Reference.
> > 
> > My client code does the following:
> > 
> >         NumberFactoryService service = new NumberFactoryService();
> >         NumberFactory factory = service.getNumberFactoryPort();
> > 
> > 
> > 	  EndpointReferenceType numberTwoRef = factory.create("2");    
> >         
> >         NumberService numService = new NumberService();
> > A.      ServiceImpl serviceImpl =
> > ServiceDelegateAccessor.get(numService);
> >         
> > B.      Number num =  (Number)serviceImpl.getPort(numberTwoRef,
> > Number.class);
> >         assertTrue("2 is even", num.isEven().isEven());
> >    
> > Of interest here is:
> > A: JAX-WS is correctly particular about denying access to the 
> > underlying implementation and with 2.1, EndpointReferences 
> are first 
> > class citizens so the need will no longer arise.
> > Long term we probably need to start a jax-ws-2.1-frontend. 
> > Short term, implementing the functionality in the CXF 
> implementation 
> > objects and providing this accessor is a fast win.
> > B: the ServiceImpl.getPort(EndpointReferenceType epr,..) 
> simply uses 
> > the address info of the epr to override the address of the 
> > EndpointInfo.
> > There is an issue with duplication of information between 
> EndpointInfo 
> > and EPRs in the Conduit that I will address in another post.
> > 
> > 
> > The Server side is more interesting.
> > NumberFactoryServiceImpl.create() needs to produce 
> > EndpointReferenceTypes (EPRs) for the NumberService that identity a 
> > particular number. First it inits and publishes a NumerServiceImpl 
> > servant. On the trunk this requires working with 
> > EndpointReferenceUtils to flesh out a valid EPR. My default 
> > implementation uses EPR referenceParameters to contain the 
> unique Id 
> > and WS-A to propagate the target address. This has the advantage of 
> > being transport neutral but it is over kill for some 
> transports. For 
> > example, for a transport like http or Yoko, it is possible to embed 
> > the unique Id into the endpoint address, append it to the 
> context in 
> > http (context match based on
> > startsWith) or for Yoko, burn it into a default servant object key. 
> > Then the need for WS-A disappears. This pushes the detail of EPR 
> > creation with a unique Id onto the transport/Destination.
> > 
> > I am thinking along the lines of an extension to Destination that 
> > transports can optionally support.
> > 
> > /**
> >  * A MultiplexDestination is a transport-level endpoint capable of 
> > receiving
> >  * unsolicited incoming messages from different peers for multiple 
> > targets
> >  * identified by a unique id.
> >  * The disambiguation of targets is handled by higher layers as the 
> > target
> >  * address is made available as a context property or as a WS-A-To 
> > header  */
> > 
> > public interface MultiplexDestination extends Destination {
> >     
> >     /**
> >      * @return the a reference containing the id that is 
> >      * associated with this Destination
> >      */
> >     EndpointReferenceType getAddressWithId(String id);
> >     
> >    /**
> >      * @param contextMap for this invocation, for example from 
> >      * JAX-WS WebServiceContext.getMessageContext(). The 
> context will
> >      * either contain the WS-A To content and/or some property that 
> >      * identifies the target address, eg 
> MessageContext.PATH_INFO for
> >      * the current invocation
> >      * @return the id associated with the current invocation
> >      */
> >     String getId(Map contextMap);
> > }
> > 
> > The default implementation in AbstractMultiplexDestination 
> can map the 
> > uniqueId to an EPR referenceParameter and propagate via WSA in a 
> > transport neutral way.
> > AbstractHttpDestination can optionally override the default to make 
> > use of the address context for a more efficient and natural http 
> > implementation.
> > 
> > From a users perspective, a unique server side epr would be 
> > resolved/created from a existing published service using
> > 
> >    EndpointRefernceType epr =
> > 	
> > EndpointReferenceUtils.getEndpointReferenceWithId(NUMBER_SERVI
> > CE_QNAME,
> >          null, // portName
> >          uniqueId, 
> >          BusFactory.getDefaultBus());
> > 
> > Note: The portName should allow a particular port among many in a 
> > service, to be identified.
> > 
> > Where EndpointReferenceUtils goes as follows:
> > 
> > public static EndpointReferenceType
> > getEndpointReferenceWithId(QName serviceQName, String 
> portMame, String 
> > id, Bus bus) {
> >         EndpointReferenceType epr = null;
> >         ServerRegistry serverRegistry = (ServerRegistry) 
> > bus.getExtension(ServerRegistry.class);
> >         List<Server> servers = serverRegistry.getServers();
> >         for (Server s : servers) {
> >             QName targetServiceQName = 
> > s.getEndpoint().getEndpointInfo().getService().getName();
> >             if (serviceQName.equals(targetServiceQName)) {
> >                 Destination dest = s.getDestination();
> >                 if (dest instanceof MultiplexDestination) {
> >                     epr =
> > ((MultiplexDestination)dest).getEndpointReferenceWithId(id);
> >                 break;
> >             }
> >         }
> >         return epr;
> > 
> > Also
> >  public static String getCurrentEndpointReferenceId(Map context, Bus
> > bus) {
> >     ...
> >  }
> > 
> > During an invocation (server dispatch) accessing the current target 
> > EndpointReference needs a little work however. The JAX-WS 
> > MessageContext Map contains all the required information as 
> > properties. The MultiplexedDestination can use this information to 
> > locate and extract the uniqueId for this current request. 
> The use of 
> > Map in the api keeps the EndpointReferenceUtils front-end 
> neutral and 
> > the MultiplexedDestination transport neutral.
> > 
> > 
> > Having to traverse the list of registered services in is a 
> > bit cumbersome, would it be possible to have services 
> > registered by Service QName? Or would that restrict us to 
> > single instance services. It could be map<QName, List<Service>>.
> > 
> > 
> > Bernd, does this nail your use case? 
> > 
> > All, Does it make sense? 
> > 
> > Comments appreciated, I would like to further this into a 
> > proposal in the near future.
> > 
> > Thanks,
> > Gary.
> > 
> > 
> > 
> > > -----Original Message-----
> > > From: Bernd Schuller [mailto:b.schuller@fz-juelich.de]
> > > Sent: 23 March 2007 13:13
> > > To: cxf-dev@incubator.apache.org
> > > Subject: Re: Support for stateful services in CXF
> > > 
> > > Hi Gary,
> > > 
> > > thanks a lot for your reply.
> > > 
> > > Tully, Gary wrote:
> > > > 
> > > > Only yesterday I started to investigate providing simple
> > > support for a
> > > > single instance service that can represent many WS-addressing 
> > > > identities.
> > > > 
> > > > What I am after at the moment is a simpler version of what is 
> > > > supported by @Stateful in the JAX-WS RI. The only state is
> > > a unique-id
> > > > that is encapsulated in the WS-Address.
> > > 
> > > That looks like a starting point...
> > > 
> > > [...]
> > > 
> > > > At the moment I am capturing the FactoryPattern use-case as
> > > a system
> > > > test in order to provide a starting proof-point for an
> > > implementation.
> > > > 
> > > > The use of WS-Context (thanks Sergey) or HTTP session
> > > information as a
> > > > means of determining unique id would be neat but I 
> think this is 
> > > > orthogonal.
> > > 
> > > agreed.
> > > 
> > > > From a WS-RF point of view, what are the usage scenarios
> > > that you will
> > > > need? Do they lend them selves to capture as system tests?
> > > 
> > > The basic scenario is approximately
> > >   - allow for instance creation on a stateful service, 
> for example 
> > > using a
> > >     Factory service
> > >   - deal with state, e.g. persist instances to some 
> > permanent storage
> > >   - manage instance lifecycle, manage their lifetime, destroy them
> > >   - allow clients to access instances by EPR / 
> > WS-Addressing This can 
> > > be captured by system tests, I guess.
> > > 
> > > > Like you, I am learning as I go here, so any input is 
> > appreciated, 
> > > > especially your ideas on improving @Stateful and your 
> experiences 
> > > > doing something similar with Xfire.
> > > 
> > > My main improvements on the JAX-WS RI @Stateful would be 
> to try and 
> > > make the whole instance resolving process, instance lifecycle 
> > > management and EPR creation much more flexible, and give 
> > more control 
> > > to the application programmer.
> > > Of course all this should fit in as nicely as possible in the CXF 
> > > environment, which I unfortunately don't know much about yet...
> > > 
> > > In my XFire implementation, things were fairly easy, 
> > because I could 
> > > hook into the mechanism that XFire uses to get the service 
> > object (the 
> > > Invoker). Figure out the unique id from the message 
> > context, re-create 
> > > the requested service instance from permanent storage, 
> restore its 
> > > state, and invoke the operation.
> > > 
> > > Maybe something similar can be done in CXF.
> > > 
> > > > As I am only starting on my quest for a design, you may as
> > > well give
> > > > it a try from your perspective. We can swap ideas or 
> > experiences to 
> > > > come up with a working solution. It need not be a race :-)
> > > 
> > > Perfect!
> > > 
> > > Thanks, and best regards,
> > > Bernd.
> > > 
> > > 
> > > >> -----Original Message-----
> > > >> From: Bernd Schuller [mailto:b.schuller@fz-juelich.de]
> > > >> Sent: 23 March 2007 07:36
> > > >> To: CXF devel
> > > >> Subject: Support for stateful services in CXF [...] I was
> > > wondering
> > > >> about whether you think it is a good idea to add support
> > > for stateful
> > > >> services to CXF.
> > > [...]
> > > 
> > > --
> > > Dr. Bernd Schuller
> > > 
> > > Central Institute for Applied Mathematics 
> Forschungszentrum Juelich 
> > > GmbH
> > > 
> > > mail  b.schuller@fz-juelich.de
> > > phone +49 2461 61 8736
> > > fax   +49 2461 61 6656
> > > blog  http://www.jroller.com/page/gridhaus
> > > 
> > > 
> > 
> 

Mime
View raw message