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