You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Gabo Manuel <km...@solegysystems.com> on 2009/06/04 10:46:25 UTC
[CXF-2.2.2][JAXWS] Resource injection problem
Hi All,
Problem #1 :
I am implementing a service with both WS and RS annotations. I encounter
the following problem:
@Resource
private Exchange exchange;
@GET
@Path("/")
@WebMethod
@WebResult(name="object")
public Object getObject(long id) {
System.out.println("exchange: " + exchange);
}
If I try to access it via SOAP, the exchange object IS null; but if I
try to access the method via ReST, the exchange object is NOT null. As a
follow-up question, would the exchange object be different for each
transaction, i.e. thread-safe?
Problem #2 :
How do I access the context from an interceptor? Given the following:
public class SoapInHandler extends AbstractPhaseInterceptor<SoapMessage>{
private static Logger logger = Logger.getLogger(SoapInHandler.class);
public SoapInHandler() {
// not sure which phase to use.
// super(Phase.UNMARSHAL);
// super(Phase.PRE_INVOKE);
// super(Phase.READ);
super(Phase.POST_PROTOCOL);
}
@Override
public void handleMessage(SoapMessage message) throws Fault {
// i need to get the UserPrincipal here...
// i need to get the UserPrincipal here...
try {
SoapHeader security = (SoapHeader)message.getHeader(new
QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd","Security"));
//this always returns empty
logger.info("actor: " + security.getActor());
} catch(Exception e){
logger.warn("unable to retrieve actor.." + e.getMessage(), e);
}
}
}
I tried retrieving the wsse:Security header, but I am not able to
retrieve the username token or any of it's child nodes.
Any suggestions?
Again, thanks in advance.
Gabo
Re: [CXF-2.2.2][JAXWS] Resource injection problem
Posted by Gabo Manuel <km...@solegysystems.com>.
Hi Dan,
Daniel Kulp wrote:
> You could do it without the injection since you are relying on CXF specific
> code making it non portable. Just do:
>
> PhaseInterceptorChain.getCurrentMessage().getExchange().
>
> That should give you the exchange you need.
>
Thanks!! That did exactly what I needed.
Gabo
Re: [CXF-2.2.2][JAXWS] Resource injection problem
Posted by Daniel Kulp <dk...@apache.org>.
You could do it without the injection since you are relying on CXF specific
code making it non portable. Just do:
PhaseInterceptorChain.getCurrentMessage().getExchange().
That should give you the exchange you need.
Dan
On Sun June 7 2009 11:25:35 pm Gabo Manuel wrote:
> Hi Sergey,
>
> > If you use exchange to get to one of the message properties inside the
> > application code then I believe you can use JAXWS WebServiceContext and
> > CXF JAX-RS MessageContext extension...
>
> That is exactly the work-around I mentioned. However, it would be nice
> if I could reduce it to just one, i.e. Exchange. I am using the exchange
> to store business specific information that needs to be accessed at
> multiple points.
>
> Just to confirm, the context object injected would be unique per
> transaction, right? Regardless of how many simultaneous transactions
> there are? Or would there be some additional settings I need to set?
>
> Gabo
--
Daniel Kulp
dkulp@apache.org
http://www.dankulp.com/blog
Re: [CXF-2.2.2][JAXWS] Resource injection problem
Posted by Sergey Beryozkin <sb...@progress.com>.
Hi Gabo
> Hi Sergey,
>
>> If you use exchange to get to one of the message properties inside the
>> application code then I believe you can use JAXWS WebServiceContext and
>> CXF JAX-RS MessageContext extension...
>
> That is exactly the work-around I mentioned. However, it would be nice if I could reduce it to just one, i.e. Exchange. I am using
> the exchange to store business specific information that needs to be accessed at multiple points.
There's no much 'cooperation' at the moment happening between JAXWS and JAXRS runtimes except that they depend a lot on the common
core runtime, but I agree it would be good to reuse the same thread-local Exchange context. I hope we will manage to improve things
in this area a bit.
>
> Just to confirm, the context object injected would be unique per transaction, right? Regardless of how many simultaneous
> transactions there are? Or would there be some additional settings I need to set?
Yes, there will be unique objects. The actual instance injected in your class is a thread-local proxy which will
use thread-local values...
cheers, Sergey
>
> Gabo
Re: [CXF-2.2.2][JAXWS] Resource injection problem
Posted by Gabo Manuel <km...@solegysystems.com>.
Hi Sergey,
> If you use exchange to get to one of the message properties inside the
> application code then I believe you can use JAXWS WebServiceContext and
> CXF JAX-RS MessageContext extension...
>
That is exactly the work-around I mentioned. However, it would be nice
if I could reduce it to just one, i.e. Exchange. I am using the exchange
to store business specific information that needs to be accessed at
multiple points.
Just to confirm, the context object injected would be unique per
transaction, right? Regardless of how many simultaneous transactions
there are? Or would there be some additional settings I need to set?
Gabo
RE: [CXF-2.2.2][JAXWS] Resource injection problem
Posted by Sergey Beryozkin <sb...@progress.com>.
Hi Gabo
If you use exchange to get to one of the message properties inside the
application code then I believe you can use JAXWS WebServiceContext and
CXF JAX-RS MessageContext extension...
Cheers, Sergey
-----Original Message-----
From: Gabo Manuel [mailto:kmanuel@solegysystems.com]
Sent: 05 June 2009 07:57
To: users@cxf.apache.org
Subject: Re: [CXF-2.2.2][JAXWS] Resource injection problem
Hi Dan, Sergey,
> On Thu June 4 2009 4:46:25 am Ga
>> @Resource
>> private Exchange exchange;
>>
> The main reason is that JAX-RS, by default, creates a new instance per
request
> and thus is injected per request.
Not sure what exactly I changed and I cannot trace it anymore, the
Exchange is now null even for JAX-RS transactions. It's ok though, I
have a work-around to get what I need. :)
> Hmmm... that should have worked I would think. Maybe the wss4j
removes the
> header if it's processed? Not really sure.
>
> That said, if you run after the Wss4jInInterceptor, you can do one of:
> Principal p =
(Prinicpal)message.get(Wss4jInInterceptor.PRINCIPAL_RESULT)
> or
> SecurityContext c = message.get(SecurityContext.class);
> Principal p = c.getUserPrincipal();
>
Both of them worked! I'll just use the first. Thanks for that.
Gabo
Re: [CXF-2.2.2][JAXWS] Resource injection problem
Posted by Gabo Manuel <km...@solegysystems.com>.
Hi Dan, Sergey,
> On Thu June 4 2009 4:46:25 am Ga
>> @Resource
>> private Exchange exchange;
>>
> The main reason is that JAX-RS, by default, creates a new instance per request
> and thus is injected per request.
Not sure what exactly I changed and I cannot trace it anymore, the
Exchange is now null even for JAX-RS transactions. It's ok though, I
have a work-around to get what I need. :)
> Hmmm... that should have worked I would think. Maybe the wss4j removes the
> header if it's processed? Not really sure.
>
> That said, if you run after the Wss4jInInterceptor, you can do one of:
> Principal p = (Prinicpal)message.get(Wss4jInInterceptor.PRINCIPAL_RESULT)
> or
> SecurityContext c = message.get(SecurityContext.class);
> Principal p = c.getUserPrincipal();
>
Both of them worked! I'll just use the first. Thanks for that.
Gabo
RE: [CXF-2.2.2][JAXWS] Resource injection problem
Posted by Sergey Beryozkin <sb...@progress.com>.
Hi,
At the moment, When Spring is used, JAX-RS resources are always
singletons, there's a JIRA though to ensure prototypes are supported. So
in such cases contexts are thread-safe. That said, JAX_RS runtime does
not support
Exchange injections. Gabo - are you sure it's a RESTful invocation ? I'm
not sure how you see it being not null. Can you please print the name of
Exchange class instance ?
Thanks, Sergey
-----Original Message-----
From: Daniel Kulp [mailto:dkulp@apache.org]
Sent: 04 June 2009 17:45
To: users@cxf.apache.org
Cc: Gabo Manuel
Subject: Re: [CXF-2.2.2][JAXWS] Resource injection problem
On Thu June 4 2009 4:46:25 am Gabo Manuel wrote:
> Hi All,
>
> Problem #1 :
>
> I am implementing a service with both WS and RS annotations. I
encounter
> the following problem:
>
> @Resource
> private Exchange exchange;
>
> @GET
> @Path("/")
> @WebMethod
> @WebResult(name="object")
> public Object getObject(long id) {
> System.out.println("exchange: " + exchange);
> }
>
> If I try to access it via SOAP, the exchange object IS null; but if I
> try to access the method via ReST, the exchange object is NOT null. As
a
> follow-up question, would the exchange object be different for each
> transaction, i.e. thread-safe?
The main reason is that JAX-RS, by default, creates a new instance per
request
and thus is injected per request. JAX-WS, on the other hand, creates a
single instance and injects everything up front (and no Exchange is live
at
that point). You CAN configure in a new factory that WOULD create a
new
instance per request, but even then I'm not sure if the exchange would
get
injected. I doubt it. Performance would suffer though.
And no, access to the Exchange in that instance would not be thread
safe, but
with a new instance per request, it doesn't matter.
> Problem #2 :
> How do I access the context from an interceptor? Given the following:
> public class SoapInHandler extends
AbstractPhaseInterceptor<SoapMessage>{
> private static Logger logger =
Logger.getLogger(SoapInHandler.class);
> public SoapInHandler() {
> // not sure which phase to use.
> // super(Phase.UNMARSHAL);
> // super(Phase.PRE_INVOKE);
> // super(Phase.READ);
> super(Phase.POST_PROTOCOL);
> }
>
> @Override
> public void handleMessage(SoapMessage message) throws Fault {
> // i need to get the UserPrincipal here...
> // i need to get the UserPrincipal here...
> try {
> SoapHeader security = (SoapHeader)message.getHeader(new
>
QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurit
y-s
>ecext-1.0.xsd","Security")); //this always returns empty
> logger.info("actor: " + security.getActor());
> } catch(Exception e){
> logger.warn("unable to retrieve actor.." + e.getMessage(),
e);
> }
> }
> }
Hmmm... that should have worked I would think. Maybe the wss4j
removes the
header if it's processed? Not really sure.
That said, if you run after the Wss4jInInterceptor, you can do one of:
Principal p =
(Prinicpal)message.get(Wss4jInInterceptor.PRINCIPAL_RESULT)
or
SecurityContext c = message.get(SecurityContext.class);
Principal p = c.getUserPrincipal();
Dan
> I tried retrieving the wsse:Security header, but I am not able to
> retrieve the username token or any of it's child nodes.
>
> Any suggestions?
>
> Again, thanks in advance.
>
> Gabo
--
Daniel Kulp
dkulp@apache.org
http://www.dankulp.com/blog
Re: [CXF-2.2.2][JAXWS] Resource injection problem
Posted by Daniel Kulp <dk...@apache.org>.
On Thu June 4 2009 4:46:25 am Gabo Manuel wrote:
> Hi All,
>
> Problem #1 :
>
> I am implementing a service with both WS and RS annotations. I encounter
> the following problem:
>
> @Resource
> private Exchange exchange;
>
> @GET
> @Path("/")
> @WebMethod
> @WebResult(name="object")
> public Object getObject(long id) {
> System.out.println("exchange: " + exchange);
> }
>
> If I try to access it via SOAP, the exchange object IS null; but if I
> try to access the method via ReST, the exchange object is NOT null. As a
> follow-up question, would the exchange object be different for each
> transaction, i.e. thread-safe?
The main reason is that JAX-RS, by default, creates a new instance per request
and thus is injected per request. JAX-WS, on the other hand, creates a
single instance and injects everything up front (and no Exchange is live at
that point). You CAN configure in a new factory that WOULD create a new
instance per request, but even then I'm not sure if the exchange would get
injected. I doubt it. Performance would suffer though.
And no, access to the Exchange in that instance would not be thread safe, but
with a new instance per request, it doesn't matter.
> Problem #2 :
> How do I access the context from an interceptor? Given the following:
> public class SoapInHandler extends AbstractPhaseInterceptor<SoapMessage>{
> private static Logger logger = Logger.getLogger(SoapInHandler.class);
> public SoapInHandler() {
> // not sure which phase to use.
> // super(Phase.UNMARSHAL);
> // super(Phase.PRE_INVOKE);
> // super(Phase.READ);
> super(Phase.POST_PROTOCOL);
> }
>
> @Override
> public void handleMessage(SoapMessage message) throws Fault {
> // i need to get the UserPrincipal here...
> // i need to get the UserPrincipal here...
> try {
> SoapHeader security = (SoapHeader)message.getHeader(new
> QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-s
>ecext-1.0.xsd","Security")); //this always returns empty
> logger.info("actor: " + security.getActor());
> } catch(Exception e){
> logger.warn("unable to retrieve actor.." + e.getMessage(), e);
> }
> }
> }
Hmmm... that should have worked I would think. Maybe the wss4j removes the
header if it's processed? Not really sure.
That said, if you run after the Wss4jInInterceptor, you can do one of:
Principal p = (Prinicpal)message.get(Wss4jInInterceptor.PRINCIPAL_RESULT)
or
SecurityContext c = message.get(SecurityContext.class);
Principal p = c.getUserPrincipal();
Dan
> I tried retrieving the wsse:Security header, but I am not able to
> retrieve the username token or any of it's child nodes.
>
> Any suggestions?
>
> Again, thanks in advance.
>
> Gabo
--
Daniel Kulp
dkulp@apache.org
http://www.dankulp.com/blog