cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Glynn, Eoghan" <eoghan.gl...@iona.com>
Subject RE: Support for stateful services in CXF
Date Fri, 20 Apr 2007 13:41:09 GMT

Thanks Gary, lovely green bar on Linux for the latest version of the
patch, committing now ...

Cheers,
Eoghan  

> -----Original Message-----
> From: Tully, Gary [mailto:Gary.Tully@iona.com] 
> Sent: 19 April 2007 20:11
> To: cxf-dev@incubator.apache.org
> Subject: RE: Support for stateful services in CXF
> 
> 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/mult
> iplex-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