You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by Sergey Beryozkin <se...@iona.com> on 2007/06/14 13:56:45 UTC

Re: Support for stateful services in CXF

Hi Gary

I'd like to revive this thread for a bit :-)
As you mentioned, 

>The 'value' of WS-Context IMHO is that the context is not tied
>to a particular EPR but can flow with a request to any EPR.

Which is indeed quite a good thing. Do you reckon there's any space
for pushing the support for stateful services a bit further and providing an alternate
implementation built around WS-Context so that people can choose between the two ones ?

I reckon both approaches have their value. It seems that "statefullness" is always associated with the use of WS-Addressing under the hood [1] in the WS-Services world. I think with WS-Context one might afford for a more loose interaction model between the client and the service endpoint...

Cheers, Sergey


[1] http://weblogs.java.net/blog/kohsuke/archive/2007/06/stateful_web_se_1.html


----- Original Message ----- 
From: "Tully, Gary" <Ga...@iona.com>
To: <cx...@incubator.apache.org>
Sent: Thursday, April 05, 2007 10:24 AM
Subject: RE: Support for stateful services in CXF


Hi Sergey,
I agree and as you spotted, AbstractHTTPDestination can ensure that HTTP
works with the address rather than with a WS-A reference parameter. 
It would also be possible to use WS-Context as a strategy to transmit
the Id. The 'value' of WS-Context IMHO is that the context is not tied
to a particular EPR but can flow with a request to any EPR. This 'value'
is not apparent to my use case, hence the punt of WS-Context in to the
orthogonal sphere earlier.


The real motivator for WS-A is that it is transport neutral and as such
would work for any potential CXF transport that wants to support
multiplexing. This makes it an architecturally good choice for a default
propagation strategy. 
In the realm of HTTP and yoko, the best return will come from the native
approach of embedding the id in the address as these addresses can still
be accessible to native consumers.

Thanks for the input, academic? No :-)
Gary.

> -----Original Message-----
> From: Sergey Beryozkin [mailto:sergey.beryozkin@iona.com] 
> Sent: 05 April 2007 09:53
> To: cxf-dev@incubator.apache.org
> Subject: Re: Support for stateful services in CXF
> 
> Hi
> 
> "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" ...
> 
> IMHO this is what should happen for HTTP because this will 
> make individul number services addressable...Using EPR 
> parameters to convey the unique id looses the identity of the 
> service endpoint.
> Sorry if my comments would seem a bit academic in the scope 
> of your very interesting and more important, *practical* 
> proposal. It's just that CXF shows the lead in letting people 
> to build resful services, etc, so I feel that trying to 
> pursue the general idea of bringing even purely SOAP-based 
> services closer to the web, when possible, would be good. We 
> can imagine then SOAP Number services being able to GET-reply 
> with their state while still being able to process soap post 
> increment/decrement requests, etc...This will increase the 
> value of the Number service. Actually, have just seen your 
> comment that AbstractHTTPDestination can be used for this, 
> sounds great, perhaps this can be used to enhance the way 
> things work with http in the future !
> If even for HTTP the WSA header will be sent to the service 
> to indicate what instance the invocation should be made 
> againt then it would be in general mean the explicit context 
> is used, which is good, but I hope you can see now why I was 
> referring to WS-Context earlier, one can imagine passing a 
> WS_Context header to the Number service indicating an 
> application level context, the number on which the service 
> should perform the even check....so even though WS-Context is 
> probably more natural for dealing with higher-level 
> activities, it may work with the application-level ones too
> 
> Overall it's a great start...
> 
> Thanks, Sergey
> 
> ----- Original Message -----
> From: "Tully, Gary" <Ga...@iona.com>
> To: <cx...@incubator.apache.org>
> Sent: Wednesday, April 04, 2007 5:40 PM
> 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
> >
> > 
> 
>

----------------------------
IONA Technologies PLC (registered in Ireland)
Registered Number: 171387
Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland

Re: Support for stateful services in CXF

Posted by Sergey Beryozkin <se...@iona.com>.
I was rather hoping to initiate some discussion on how stateful web services can be done under the hood. CXF does it one way which is very good, this is similar how other providers do it too, and it works. 
I'm really after trying to explore if there's anything that can be learnt or borrowed from the WS-Context spec and put into the practical surface, as far as bulding stateful services is concerned. 
WS-Context is about supporting distributed activities (those spanning muliple services), so I'm wondering, can it all be applied to the issue of supporting the application-level stateful interactions or not...as the alternate strategy
Thanks, Sergey 

----- Original Message ----- 
From: "Jeff Genender" <jg...@apache.org>
To: <cx...@incubator.apache.org>
Sent: Thursday, June 14, 2007 3:03 PM
Subject: Re: Support for stateful services in CXF


> If I think I understand what you are asking for, I believe I added
> support for stateful services by setting the
> "javax.xml.ws.session.maintain" in your request context to a Boolean.TRUE.
> 
> You can enable stateful WS by setting:
> 
> requestContext.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, Boolean.TRUE);
> 
> Thanks,
> 
> Jeff
> 
> 
> Sergey Beryozkin wrote:
>> Hi Gary
>> 
>> I'd like to revive this thread for a bit :-)
>> As you mentioned, 
>> 
>>> The 'value' of WS-Context IMHO is that the context is not tied
>>> to a particular EPR but can flow with a request to any EPR.
>> 
>> Which is indeed quite a good thing. Do you reckon there's any space
>> for pushing the support for stateful services a bit further and providing an alternate
>> implementation built around WS-Context so that people can choose between the two ones ?
>> 
>> I reckon both approaches have their value. It seems that "statefullness" is always associated with the use of WS-Addressing under the hood [1] in the WS-Services world. I think with WS-Context one might afford for a more loose interaction model between the client and the service endpoint...
>> 
>> Cheers, Sergey
>> 
>> 
>> [1] http://weblogs.java.net/blog/kohsuke/archive/2007/06/stateful_web_se_1.html
>> 
>> 
>> ----- Original Message ----- 
>> From: "Tully, Gary" <Ga...@iona.com>
>> To: <cx...@incubator.apache.org>
>> Sent: Thursday, April 05, 2007 10:24 AM
>> Subject: RE: Support for stateful services in CXF
>> 
>> 
>> Hi Sergey,
>> I agree and as you spotted, AbstractHTTPDestination can ensure that HTTP
>> works with the address rather than with a WS-A reference parameter. 
>> It would also be possible to use WS-Context as a strategy to transmit
>> the Id. The 'value' of WS-Context IMHO is that the context is not tied
>> to a particular EPR but can flow with a request to any EPR. This 'value'
>> is not apparent to my use case, hence the punt of WS-Context in to the
>> orthogonal sphere earlier.
>> 
>> 
>> The real motivator for WS-A is that it is transport neutral and as such
>> would work for any potential CXF transport that wants to support
>> multiplexing. This makes it an architecturally good choice for a default
>> propagation strategy. 
>> In the realm of HTTP and yoko, the best return will come from the native
>> approach of embedding the id in the address as these addresses can still
>> be accessible to native consumers.
>> 
>> Thanks for the input, academic? No :-)
>> Gary.
>> 
>>> -----Original Message-----
>>> From: Sergey Beryozkin [mailto:sergey.beryozkin@iona.com] 
>>> Sent: 05 April 2007 09:53
>>> To: cxf-dev@incubator.apache.org
>>> Subject: Re: Support for stateful services in CXF
>>>
>>> Hi
>>>
>>> "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" ...
>>>
>>> IMHO this is what should happen for HTTP because this will 
>>> make individul number services addressable...Using EPR 
>>> parameters to convey the unique id looses the identity of the 
>>> service endpoint.
>>> Sorry if my comments would seem a bit academic in the scope 
>>> of your very interesting and more important, *practical* 
>>> proposal. It's just that CXF shows the lead in letting people 
>>> to build resful services, etc, so I feel that trying to 
>>> pursue the general idea of bringing even purely SOAP-based 
>>> services closer to the web, when possible, would be good. We 
>>> can imagine then SOAP Number services being able to GET-reply 
>>> with their state while still being able to process soap post 
>>> increment/decrement requests, etc...This will increase the 
>>> value of the Number service. Actually, have just seen your 
>>> comment that AbstractHTTPDestination can be used for this, 
>>> sounds great, perhaps this can be used to enhance the way 
>>> things work with http in the future !
>>> If even for HTTP the WSA header will be sent to the service 
>>> to indicate what instance the invocation should be made 
>>> againt then it would be in general mean the explicit context 
>>> is used, which is good, but I hope you can see now why I was 
>>> referring to WS-Context earlier, one can imagine passing a 
>>> WS_Context header to the Number service indicating an 
>>> application level context, the number on which the service 
>>> should perform the even check....so even though WS-Context is 
>>> probably more natural for dealing with higher-level 
>>> activities, it may work with the application-level ones too
>>>
>>> Overall it's a great start...
>>>
>>> Thanks, Sergey
>>>
>>> ----- Original Message -----
>>> From: "Tully, Gary" <Ga...@iona.com>
>>> To: <cx...@incubator.apache.org>
>>> Sent: Wednesday, April 04, 2007 5:40 PM
>>> 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
>>>>
>>>>
>>>
>> 
>> ----------------------------
>> IONA Technologies PLC (registered in Ireland)
>> Registered Number: 171387
>> Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland
>>

----------------------------
IONA Technologies PLC (registered in Ireland)
Registered Number: 171387
Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland

Re: Support for stateful services in CXF

Posted by Jeff Genender <jg...@apache.org>.
If I think I understand what you are asking for, I believe I added
support for stateful services by setting the
"javax.xml.ws.session.maintain" in your request context to a Boolean.TRUE.

You can enable stateful WS by setting:

requestContext.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, Boolean.TRUE);

Thanks,

Jeff


Sergey Beryozkin wrote:
> Hi Gary
> 
> I'd like to revive this thread for a bit :-)
> As you mentioned, 
> 
>> The 'value' of WS-Context IMHO is that the context is not tied
>> to a particular EPR but can flow with a request to any EPR.
> 
> Which is indeed quite a good thing. Do you reckon there's any space
> for pushing the support for stateful services a bit further and providing an alternate
> implementation built around WS-Context so that people can choose between the two ones ?
> 
> I reckon both approaches have their value. It seems that "statefullness" is always associated with the use of WS-Addressing under the hood [1] in the WS-Services world. I think with WS-Context one might afford for a more loose interaction model between the client and the service endpoint...
> 
> Cheers, Sergey
> 
> 
> [1] http://weblogs.java.net/blog/kohsuke/archive/2007/06/stateful_web_se_1.html
> 
> 
> ----- Original Message ----- 
> From: "Tully, Gary" <Ga...@iona.com>
> To: <cx...@incubator.apache.org>
> Sent: Thursday, April 05, 2007 10:24 AM
> Subject: RE: Support for stateful services in CXF
> 
> 
> Hi Sergey,
> I agree and as you spotted, AbstractHTTPDestination can ensure that HTTP
> works with the address rather than with a WS-A reference parameter. 
> It would also be possible to use WS-Context as a strategy to transmit
> the Id. The 'value' of WS-Context IMHO is that the context is not tied
> to a particular EPR but can flow with a request to any EPR. This 'value'
> is not apparent to my use case, hence the punt of WS-Context in to the
> orthogonal sphere earlier.
> 
> 
> The real motivator for WS-A is that it is transport neutral and as such
> would work for any potential CXF transport that wants to support
> multiplexing. This makes it an architecturally good choice for a default
> propagation strategy. 
> In the realm of HTTP and yoko, the best return will come from the native
> approach of embedding the id in the address as these addresses can still
> be accessible to native consumers.
> 
> Thanks for the input, academic? No :-)
> Gary.
> 
>> -----Original Message-----
>> From: Sergey Beryozkin [mailto:sergey.beryozkin@iona.com] 
>> Sent: 05 April 2007 09:53
>> To: cxf-dev@incubator.apache.org
>> Subject: Re: Support for stateful services in CXF
>>
>> Hi
>>
>> "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" ...
>>
>> IMHO this is what should happen for HTTP because this will 
>> make individul number services addressable...Using EPR 
>> parameters to convey the unique id looses the identity of the 
>> service endpoint.
>> Sorry if my comments would seem a bit academic in the scope 
>> of your very interesting and more important, *practical* 
>> proposal. It's just that CXF shows the lead in letting people 
>> to build resful services, etc, so I feel that trying to 
>> pursue the general idea of bringing even purely SOAP-based 
>> services closer to the web, when possible, would be good. We 
>> can imagine then SOAP Number services being able to GET-reply 
>> with their state while still being able to process soap post 
>> increment/decrement requests, etc...This will increase the 
>> value of the Number service. Actually, have just seen your 
>> comment that AbstractHTTPDestination can be used for this, 
>> sounds great, perhaps this can be used to enhance the way 
>> things work with http in the future !
>> If even for HTTP the WSA header will be sent to the service 
>> to indicate what instance the invocation should be made 
>> againt then it would be in general mean the explicit context 
>> is used, which is good, but I hope you can see now why I was 
>> referring to WS-Context earlier, one can imagine passing a 
>> WS_Context header to the Number service indicating an 
>> application level context, the number on which the service 
>> should perform the even check....so even though WS-Context is 
>> probably more natural for dealing with higher-level 
>> activities, it may work with the application-level ones too
>>
>> Overall it's a great start...
>>
>> Thanks, Sergey
>>
>> ----- Original Message -----
>> From: "Tully, Gary" <Ga...@iona.com>
>> To: <cx...@incubator.apache.org>
>> Sent: Wednesday, April 04, 2007 5:40 PM
>> 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
>>>
>>>
>>
> 
> ----------------------------
> IONA Technologies PLC (registered in Ireland)
> Registered Number: 171387
> Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland
>