Using AOP in CXF service impl

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Using AOP in CXF service impl

Wolf, Chris (IT)
I tried using Spring's AOP support classes to implement service
authorization
code in my CXF service, for the reason of not cluttering up my service
code
with security code (and maybe will also add auditing/tracing).  This
seems to be
to classic use-case for AOP.  

Unfortunately, the AOP implementation appears to use dynamic proxy
techniques (instance of java.lang.reflect.Proxy) but
it also appears that CXF uses dynamic proxies for the service
implementation,
because if I break in the ServiceCallPointcut code, the targetClass
appears
to *also* be an instance of java.lang.reflect.Proxy, so maybe there's an
issue using Spring AOP on dynamic proxies.

Has anyone tried using AOP techniques in CXF service code?

Thanks for any suggestions.

  -Chris
 
[...]
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
 
  static class ServiceCallPointcut extends StaticMethodMatcherPointcut {
      public boolean matches(Method m, Class targetClass) {
          return (targetClass == this.getClass() &&
m.getName().matches("(add.*)|(delete.*)|(fetch.*)|(login.*)"));
      }
  }
 
static class AuthenticationChecker implements MethodBeforeAdvice {
      public void before(Method m, Object[] args, Object target) throws
Throwable {
          System.out.println("*** Calling " + m.getName());
          // transport-portable MessageContext
          MessageContext ctx =
((SecAdminImpl)target).context.getMessageContext();
          // transport-specific request/response, cxf-specific property
names
          HttpServletRequest request = (HttpServletRequest)
ctx.get(MessageContext.SERVLET_REQUEST);
          HttpServletResponse response = (HttpServletResponse)
ctx.get(MessageContext.SERVLET_RESPONSE);
          Cookie[] cookies = request.getCookies();
      }
  }
 
MyServiceImpl svc = new MyServiceImpl();
 
ProxyFactory factory = new ProxyFactory(svc);
factory.addAdvisor(new DefaultPointcutAdvisor(new ServiceCallPointcut(),
new AuthenticationChecker()));
--------------------------------------------------------

NOTICE: If received in error, please destroy and notify sender. Sender does not intend to waive confidentiality or privilege. Use of this email is prohibited when received in error.
Reply | Threaded
Open this post in threaded view
|

Re: Using AOP in CXF service impl

Daniel Kulp
Administrator

We definitely have seen people using Spring AOP with CXF, but I think  
they've all used Spring configuration for setting up the endpoints and  
stuff.   That said, it should definitely be doable from API's since  
all the spring config does is configure the same objects via the API.

CXF doesn't use proxies on the server side.   Spring must be doing  
something there.

Dan


On May 23, 2008, at 1:52 PM, Wolf, Chris (IT) wrote:

> I tried using Spring's AOP support classes to implement service
> authorization
> code in my CXF service, for the reason of not cluttering up my service
> code
> with security code (and maybe will also add auditing/tracing).  This
> seems to be
> to classic use-case for AOP.
>
> Unfortunately, the AOP implementation appears to use dynamic proxy
> techniques (instance of java.lang.reflect.Proxy) but
> it also appears that CXF uses dynamic proxies for the service
> implementation,
> because if I break in the ServiceCallPointcut code, the targetClass
> appears
> to *also* be an instance of java.lang.reflect.Proxy, so maybe  
> there's an
> issue using Spring AOP on dynamic proxies.
>
> Has anyone tried using AOP techniques in CXF service code?
>
> Thanks for any suggestions.
>
>  -Chris
>
> [...]
> import javax.xml.ws.WebServiceContext;
> import javax.xml.ws.handler.MessageContext;
> org.springframework.aop.framework.ProxyFactory;
> import org.springframework.aop.MethodBeforeAdvice;
> import org.springframework.aop.support.StaticMethodMatcherPointcut;
>
>  static class ServiceCallPointcut extends  
> StaticMethodMatcherPointcut {
>      public boolean matches(Method m, Class targetClass) {
>          return (targetClass == this.getClass() &&
> m.getName().matches("(add.*)|(delete.*)|(fetch.*)|(login.*)"));
>      }
>  }
>
> static class AuthenticationChecker implements MethodBeforeAdvice {
>      public void before(Method m, Object[] args, Object target) throws
> Throwable {
>          System.out.println("*** Calling " + m.getName());
>          // transport-portable MessageContext
>          MessageContext ctx =
> ((SecAdminImpl)target).context.getMessageContext();
>          // transport-specific request/response, cxf-specific property
> names
>          HttpServletRequest request = (HttpServletRequest)
> ctx.get(MessageContext.SERVLET_REQUEST);
>          HttpServletResponse response = (HttpServletResponse)
> ctx.get(MessageContext.SERVLET_RESPONSE);
>          Cookie[] cookies = request.getCookies();
>      }
>  }
>
> MyServiceImpl svc = new MyServiceImpl();
>
> ProxyFactory factory = new ProxyFactory(svc);
> factory.addAdvisor(new DefaultPointcutAdvisor(new  
> ServiceCallPointcut(),
> new AuthenticationChecker()));
> --------------------------------------------------------
>
> NOTICE: If received in error, please destroy and notify sender.  
> Sender does not intend to waive confidentiality or privilege. Use of  
> this email is prohibited when received in error.

---
Daniel Kulp
[hidden email]
http://www.dankulp.com/blog




Reply | Threaded
Open this post in threaded view
|

Re: Using AOP in CXF service impl

Ian Roberts
In reply to this post by Wolf, Chris (IT)
Wolf, Chris (IT) wrote:
>   static class ServiceCallPointcut extends StaticMethodMatcherPointcut {
>       public boolean matches(Method m, Class targetClass) {
>           return (targetClass == this.getClass() &&
> m.getName().matches("(add.*)|(delete.*)|(fetch.*)|(login.*)"));
>       }
>   }

I'm suspicious of the targetClass == this.getClass() - this is only true
if the targetClass is a ServiceCallPointcut...  Did you mean something
like MyServiceImpl.this.getClass()?

As for the "wrong" targetClass issue, if you're only using this advice
with a single instance of MyServiceImpl you could always store the impl
object in a field of the AuthenticationChecker, then you can always get
at the "real" object even if Spring passes a proxy to the before method.

Ian

--
Ian Roberts               | Department of Computer Science
[hidden email]  | University of Sheffield, UK
Reply | Threaded
Open this post in threaded view
|

RE: Using AOP in CXF service impl

Wolf, Chris (IT)
Ian,

Thanks for the "advice" ;)  Your suggestion helped me fix the problem,
in fact, I don't even need to bother with targetClass since the
ServiceCallPointcut is associated with only that class (actually,
object instance) via the ProxyFactory.addAdvisor call.

ProxyFactory factory = new ProxyFactory(svc);
factory.addAdvisor(new DefaultPointcutAdvisor(new ServiceCallPointcut(),
new AuthenticationChecker()));

   -Chris


-----Original Message-----
From: Ian Roberts [mailto:[hidden email]]
Sent: Sun 25/05/2008 12:08 PM
To: [hidden email]
Subject: Re: Using AOP in CXF service impl
 
Wolf, Chris (IT) wrote:
>   static class ServiceCallPointcut extends StaticMethodMatcherPointcut
{
>       public boolean matches(Method m, Class targetClass) {
>           return (targetClass == this.getClass() &&
> m.getName().matches("(add.*)|(delete.*)|(fetch.*)|(login.*)"));
>       }
>   }

I'm suspicious of the targetClass == this.getClass() - this is only true

if the targetClass is a ServiceCallPointcut...  Did you mean something
like MyServiceImpl.this.getClass()?

As for the "wrong" targetClass issue, if you're only using this advice
with a single instance of MyServiceImpl you could always store the impl
object in a field of the AuthenticationChecker, then you can always get
at the "real" object even if Spring passes a proxy to the before method.

Ian

--
Ian Roberts               | Department of Computer Science
[hidden email]  | University of Sheffield, UK
--------------------------------------------------------

NOTICE: If received in error, please destroy and notify sender. Sender does not intend to waive confidentiality or privilege. Use of this email is prohibited when received in error.
Reply | Threaded
Open this post in threaded view
|

RE: Using AOP in CXF service impl

Wolf, Chris (IT)
In reply to this post by Daniel Kulp
Dan,

Thanks for the help.  Yes, it was Spring's AOP "ProxyFactory" that was
wrapping the
SEI implementation class in a dynamic proxy, and that was the only
issue.  I
got confused in the debugger with the mistaken impression that there was
more then
one layer of dynamic proxying occuring.  

In any case, I resolved the issue (with Ian's suggestion).  

Now I am wondering -- why would I not just use a CXF interceptor?

Is there any advantage to using an implementation of
AbstractPhaseInterceptor
vs. using an implementation of javax.xml.ws.handler.soap.SOAPHandler?

In the later case, it seems that being JAX-WS API would mean greater
portability, so wouldn't that be better?

Thanks,

   -Chris

-----Original Message-----
From: Daniel Kulp [mailto:[hidden email]]
Sent: Saturday, May 24, 2008 10:05 PM
To: [hidden email]
Subject: Re: Using AOP in CXF service impl


We definitely have seen people using Spring AOP with CXF, but I think
they've all used Spring configuration for setting up the endpoints and  
stuff.   That said, it should definitely be doable from API's since  
all the spring config does is configure the same objects via the API.

CXF doesn't use proxies on the server side.   Spring must be doing  
something there.

Dan


On May 23, 2008, at 1:52 PM, Wolf, Chris (IT) wrote:

> I tried using Spring's AOP support classes to implement service
> authorization code in my CXF service, for the reason of not cluttering

> up my service code with security code (and maybe will also add
> auditing/tracing).  This seems to be to classic use-case for AOP.
>
> Unfortunately, the AOP implementation appears to use dynamic proxy
> techniques (instance of java.lang.reflect.Proxy) but it also appears
> that CXF uses dynamic proxies for the service implementation, because
> if I break in the ServiceCallPointcut code, the targetClass appears to

> *also* be an instance of java.lang.reflect.Proxy, so maybe there's an
> issue using Spring AOP on dynamic proxies.
>
> Has anyone tried using AOP techniques in CXF service code?
>
> Thanks for any suggestions.
>
>  -Chris
>
> [...]
> import javax.xml.ws.WebServiceContext; import
> javax.xml.ws.handler.MessageContext;
> org.springframework.aop.framework.ProxyFactory;
> import org.springframework.aop.MethodBeforeAdvice;
> import org.springframework.aop.support.StaticMethodMatcherPointcut;
>
>  static class ServiceCallPointcut extends StaticMethodMatcherPointcut
> {
>      public boolean matches(Method m, Class targetClass) {
>          return (targetClass == this.getClass() &&
> m.getName().matches("(add.*)|(delete.*)|(fetch.*)|(login.*)"));
>      }
>  }
>
> static class AuthenticationChecker implements MethodBeforeAdvice {
>      public void before(Method m, Object[] args, Object target) throws

> Throwable {
>          System.out.println("*** Calling " + m.getName());
>          // transport-portable MessageContext
>          MessageContext ctx =
> ((SecAdminImpl)target).context.getMessageContext();
>          // transport-specific request/response, cxf-specific property

> names
>          HttpServletRequest request = (HttpServletRequest)
> ctx.get(MessageContext.SERVLET_REQUEST);
>          HttpServletResponse response = (HttpServletResponse)
> ctx.get(MessageContext.SERVLET_RESPONSE);
>          Cookie[] cookies = request.getCookies();
>      }
>  }
>
> MyServiceImpl svc = new MyServiceImpl();
>
> ProxyFactory factory = new ProxyFactory(svc); factory.addAdvisor(new
> DefaultPointcutAdvisor(new ServiceCallPointcut(), new
> AuthenticationChecker()));
> --------------------------------------------------------
>
> NOTICE: If received in error, please destroy and notify sender.  
> Sender does not intend to waive confidentiality or privilege. Use of
> this email is prohibited when received in error.

---
Daniel Kulp
[hidden email]
http://www.dankulp.com/blog
--------------------------------------------------------

NOTICE: If received in error, please destroy and notify sender. Sender does not intend to waive confidentiality or privilege. Use of this email is prohibited when received in error.
Reply | Threaded
Open this post in threaded view
|

Re: Using AOP in CXF service impl

Daniel Kulp
Administrator

On Jun 5, 2008, at 2:51 PM, Wolf, Chris (IT) wrote:

> Dan,
>
> Thanks for the help.  Yes, it was Spring's AOP "ProxyFactory" that was
> wrapping the
> SEI implementation class in a dynamic proxy, and that was the only
> issue.  I
> got confused in the debugger with the mistaken impression that there  
> was
> more then
> one layer of dynamic proxying occuring.
>
> In any case, I resolved the issue (with Ian's suggestion).
>
> Now I am wondering -- why would I not just use a CXF interceptor?

You definitely could do that if that's easier.   Depends on your  
requirements.   Doing the Spring AOP stuff allows use of the Acegi  
annotations and stuff so if you're used to that, thats very easy.

> Is there any advantage to using an implementation of
> AbstractPhaseInterceptor
> vs. using an implementation of javax.xml.ws.handler.soap.SOAPHandler?
>
> In the later case, it seems that being JAX-WS API would mean greater
> portability, so wouldn't that be better?

It's a "portability" vs "performance/scalability" trade off that you  
need to balance for yourself.    A JAX-WS SOAPHandler has to have the  
entire SAAJ model of the soap message available.  Thus, it kind of  
breaks the streaming aspects of CXF.   It also consumes more memory as  
you have the "DOM" form in memory.   That triggers more garbage  
collections, etc....   If you have really large soap messages, it can  
be really troublesome.

A CXF interceptor can get around that.   If you just need the basic  
auth tokens from the protocol headers, you can just grab those and  
ignore the contents of the message entirely.   If you just need the  
SOAP headers, you can look at them without touching the body stuff.    
etc....

Basically, you have to weigh your priorities and decide which  
direction is right for your project.

Dan




>
>
> Thanks,
>
>   -Chris
>
> -----Original Message-----
> From: Daniel Kulp [mailto:[hidden email]]
> Sent: Saturday, May 24, 2008 10:05 PM
> To: [hidden email]
> Subject: Re: Using AOP in CXF service impl
>
>
> We definitely have seen people using Spring AOP with CXF, but I think
> they've all used Spring configuration for setting up the endpoints and
> stuff.   That said, it should definitely be doable from API's since
> all the spring config does is configure the same objects via the API.
>
> CXF doesn't use proxies on the server side.   Spring must be doing
> something there.
>
> Dan
>
>
> On May 23, 2008, at 1:52 PM, Wolf, Chris (IT) wrote:
>
>> I tried using Spring's AOP support classes to implement service
>> authorization code in my CXF service, for the reason of not  
>> cluttering
>
>> up my service code with security code (and maybe will also add
>> auditing/tracing).  This seems to be to classic use-case for AOP.
>>
>> Unfortunately, the AOP implementation appears to use dynamic proxy
>> techniques (instance of java.lang.reflect.Proxy) but it also appears
>> that CXF uses dynamic proxies for the service implementation, because
>> if I break in the ServiceCallPointcut code, the targetClass appears  
>> to
>
>> *also* be an instance of java.lang.reflect.Proxy, so maybe there's an
>> issue using Spring AOP on dynamic proxies.
>>
>> Has anyone tried using AOP techniques in CXF service code?
>>
>> Thanks for any suggestions.
>>
>> -Chris
>>
>> [...]
>> import javax.xml.ws.WebServiceContext; import
>> javax.xml.ws.handler.MessageContext;
>> org.springframework.aop.framework.ProxyFactory;
>> import org.springframework.aop.MethodBeforeAdvice;
>> import org.springframework.aop.support.StaticMethodMatcherPointcut;
>>
>> static class ServiceCallPointcut extends StaticMethodMatcherPointcut
>> {
>>     public boolean matches(Method m, Class targetClass) {
>>         return (targetClass == this.getClass() &&
>> m.getName().matches("(add.*)|(delete.*)|(fetch.*)|(login.*)"));
>>     }
>> }
>>
>> static class AuthenticationChecker implements MethodBeforeAdvice {
>>     public void before(Method m, Object[] args, Object target) throws
>
>> Throwable {
>>         System.out.println("*** Calling " + m.getName());
>>         // transport-portable MessageContext
>>         MessageContext ctx =
>> ((SecAdminImpl)target).context.getMessageContext();
>>         // transport-specific request/response, cxf-specific property
>
>> names
>>         HttpServletRequest request = (HttpServletRequest)
>> ctx.get(MessageContext.SERVLET_REQUEST);
>>         HttpServletResponse response = (HttpServletResponse)
>> ctx.get(MessageContext.SERVLET_RESPONSE);
>>         Cookie[] cookies = request.getCookies();
>>     }
>> }
>>
>> MyServiceImpl svc = new MyServiceImpl();
>>
>> ProxyFactory factory = new ProxyFactory(svc); factory.addAdvisor(new
>> DefaultPointcutAdvisor(new ServiceCallPointcut(), new
>> AuthenticationChecker()));
>> --------------------------------------------------------
>>
>> NOTICE: If received in error, please destroy and notify sender.
>> Sender does not intend to waive confidentiality or privilege. Use of
>> this email is prohibited when received in error.
>
> ---
> Daniel Kulp
> [hidden email]
> http://www.dankulp.com/blog
> --------------------------------------------------------
>
> NOTICE: If received in error, please destroy and notify sender.  
> Sender does not intend to waive confidentiality or privilege. Use of  
> this email is prohibited when received in error.

---
Daniel Kulp
[hidden email]
http://www.dankulp.com/blog




Reply | Threaded
Open this post in threaded view
|

RE: Using AOP in CXF service impl

Wolf, Chris (IT)
-----Original Message-----
From: Daniel Kulp [mailto:[hidden email]]
Sent: Thursday, June 05, 2008 3:29 PM
To: [hidden email]
Subject: Re: Using AOP in CXF service impl


On Jun 5, 2008, at 2:51 PM, Wolf, Chris (IT) wrote:

> Dan,
>
> Thanks for the help.  Yes, it was Spring's AOP "ProxyFactory" that was

> wrapping the SEI implementation class in a dynamic proxy, and that was

> the only issue.  I got confused in the debugger with the mistaken
> impression that there was more then one layer of dynamic proxying
> occuring.
>
> In any case, I resolved the issue (with Ian's suggestion).
>
> Now I am wondering -- why would I not just use a CXF interceptor?

You definitely could do that if that's easier.   Depends on your  
requirements.   Doing the Spring AOP stuff allows use of the Acegi  
annotations and stuff so if you're used to that, thats very easy.

>>>>>>>>> I was also interested in looking into Acegi are there any
examples
>>>>>>>>> of CXF using it?  I searched around and found some incomplete
info,
>>>>>>>>> e.g.
http://www.mail-archive.com/cxf-user@.../msg04272.html


> Is there any advantage to using an implementation of
> AbstractPhaseInterceptor vs. using an implementation of
> javax.xml.ws.handler.soap.SOAPHandler?
>
> In the later case, it seems that being JAX-WS API would mean greater
> portability, so wouldn't that be better?

It's a "portability" vs "performance/scalability" trade off that you  
need to balance for yourself.    A JAX-WS SOAPHandler has to have the  
entire SAAJ model of the soap message available.  Thus, it kind of  
breaks the streaming aspects of CXF.   It also consumes more memory as  
you have the "DOM" form in memory.   That triggers more garbage  
collections, etc....   If you have really large soap messages, it can  
be really troublesome.

A CXF interceptor can get around that.   If you just need the basic  
auth tokens from the protocol headers, you can just grab those and  
ignore the contents of the message entirely.   If you just need the  
SOAP headers, you can look at them without touching the body stuff.    
etc....

Basically, you have to weigh your priorities and decide which direction
is right for your project.

Dan


>>>>>>> The portability requirement is hypothetical, but the performance
requirements
>>>>>>> are not, so CXF interceptor it will be (plus I see there are
some out-of-the-box
>>>>>>> implementations, i.e. SAAJOutInterceptor, WSS4JOutInterceptor)
>>>>>>> Thanks for clarifying the differences.


>
>
> Thanks,
>
>   -Chris
>
> -----Original Message-----
> From: Daniel Kulp [mailto:[hidden email]]
> Sent: Saturday, May 24, 2008 10:05 PM
> To: [hidden email]
> Subject: Re: Using AOP in CXF service impl
>
>
> We definitely have seen people using Spring AOP with CXF, but I think
> they've all used Spring configuration for setting up the endpoints and
> stuff.   That said, it should definitely be doable from API's since
> all the spring config does is configure the same objects via the API.
>
> CXF doesn't use proxies on the server side.   Spring must be doing
> something there.
>
> Dan
>
>
> On May 23, 2008, at 1:52 PM, Wolf, Chris (IT) wrote:
>
>> I tried using Spring's AOP support classes to implement service
>> authorization code in my CXF service, for the reason of not
>> cluttering
>
>> up my service code with security code (and maybe will also add
>> auditing/tracing).  This seems to be to classic use-case for AOP.
>>
>> Unfortunately, the AOP implementation appears to use dynamic proxy
>> techniques (instance of java.lang.reflect.Proxy) but it also appears
>> that CXF uses dynamic proxies for the service implementation, because

>> if I break in the ServiceCallPointcut code, the targetClass appears
>> to
>
>> *also* be an instance of java.lang.reflect.Proxy, so maybe there's an

>> issue using Spring AOP on dynamic proxies.
>>
>> Has anyone tried using AOP techniques in CXF service code?
>>
>> Thanks for any suggestions.
>>
>> -Chris
>>
>> [...]
>> import javax.xml.ws.WebServiceContext; import
>> javax.xml.ws.handler.MessageContext;
>> org.springframework.aop.framework.ProxyFactory;
>> import org.springframework.aop.MethodBeforeAdvice;
>> import org.springframework.aop.support.StaticMethodMatcherPointcut;
>>
>> static class ServiceCallPointcut extends StaticMethodMatcherPointcut
>> {
>>     public boolean matches(Method m, Class targetClass) {
>>         return (targetClass == this.getClass() &&
>> m.getName().matches("(add.*)|(delete.*)|(fetch.*)|(login.*)"));
>>     }
>> }
>>
>> static class AuthenticationChecker implements MethodBeforeAdvice {
>>     public void before(Method m, Object[] args, Object target) throws
>
>> Throwable {
>>         System.out.println("*** Calling " + m.getName());
>>         // transport-portable MessageContext
>>         MessageContext ctx =
>> ((SecAdminImpl)target).context.getMessageContext();
>>         // transport-specific request/response, cxf-specific property
>
>> names
>>         HttpServletRequest request = (HttpServletRequest)
>> ctx.get(MessageContext.SERVLET_REQUEST);
>>         HttpServletResponse response = (HttpServletResponse)
>> ctx.get(MessageContext.SERVLET_RESPONSE);
>>         Cookie[] cookies = request.getCookies();
>>     }
>> }
>>
>> MyServiceImpl svc = new MyServiceImpl();
>>
>> ProxyFactory factory = new ProxyFactory(svc); factory.addAdvisor(new
>> DefaultPointcutAdvisor(new ServiceCallPointcut(), new
>> AuthenticationChecker()));
>> --------------------------------------------------------
>>
>> NOTICE: If received in error, please destroy and notify sender.
>> Sender does not intend to waive confidentiality or privilege. Use of
>> this email is prohibited when received in error.
>
> ---
> Daniel Kulp
> [hidden email]
> http://www.dankulp.com/blog
> --------------------------------------------------------
>
> NOTICE: If received in error, please destroy and notify sender.  
> Sender does not intend to waive confidentiality or privilege. Use of
> this email is prohibited when received in error.

---
Daniel Kulp
[hidden email]
http://www.dankulp.com/blog
--------------------------------------------------------

NOTICE: If received in error, please destroy and notify sender. Sender does not intend to waive confidentiality or privilege. Use of this email is prohibited when received in error.
Reply | Threaded
Open this post in threaded view
|

RE: Using AOP in CXF service impl

Wolf, Chris (IT)
In reply to this post by Daniel Kulp
Dan,

You mentioned that CXF interceptors have a performance advantage over
JAX-WS interceptors, such as SOAPHandler implementations because
CXF interceptors don't read in the whole message into DOM.

However, I notice that in the code for SAAJInInterceptor that, in fact,
this CXF interceptor does just that - builds a DOM of the whole message
body:

line-109:
                XMLStreamReader xmlReader =
message.getContent(XMLStreamReader.class);
            StaxUtils.readDocElements(soapMessage.getSOAPBody(),
xmlReader, true);
            DOMSource bodySource = new
DOMSource(soapMessage.getSOAPPart().getEnvelope().getBody());
            xmlReader = StaxUtils.createXMLStreamReader(bodySource);

Is it just that this particular implementation happens to do it that
way?

Thanks,
   
  -Chris

P.S. the company mail client, Outlook, makes difficult to properly quote
mail responses - sorry.

-----Original Message-----
From: Daniel Kulp [mailto:[hidden email]]
Sent: Thursday, June 05, 2008 3:29 PM
To: [hidden email]
Subject: Re: Using AOP in CXF service impl


On Jun 5, 2008, at 2:51 PM, Wolf, Chris (IT) wrote:

> Dan,
>
> Thanks for the help.  Yes, it was Spring's AOP "ProxyFactory" that was

> wrapping the SEI implementation class in a dynamic proxy, and that was

> the only issue.  I got confused in the debugger with the mistaken
> impression that there was more then one layer of dynamic proxying
> occuring.
>
> In any case, I resolved the issue (with Ian's suggestion).
>
> Now I am wondering -- why would I not just use a CXF interceptor?

You definitely could do that if that's easier.   Depends on your  
requirements.   Doing the Spring AOP stuff allows use of the Acegi  
annotations and stuff so if you're used to that, thats very easy.

> Is there any advantage to using an implementation of
> AbstractPhaseInterceptor vs. using an implementation of
> javax.xml.ws.handler.soap.SOAPHandler?
>
> In the later case, it seems that being JAX-WS API would mean greater
> portability, so wouldn't that be better?

It's a "portability" vs "performance/scalability" trade off that you  
need to balance for yourself.    A JAX-WS SOAPHandler has to have the  
entire SAAJ model of the soap message available.  Thus, it kind of  
breaks the streaming aspects of CXF.   It also consumes more memory as  
you have the "DOM" form in memory.   That triggers more garbage  
collections, etc....   If you have really large soap messages, it can  
be really troublesome.

A CXF interceptor can get around that.   If you just need the basic  
auth tokens from the protocol headers, you can just grab those and  
ignore the contents of the message entirely.   If you just need the  
SOAP headers, you can look at them without touching the body stuff.    
etc....

Basically, you have to weigh your priorities and decide which direction
is right for your project.

Dan




>
>
> Thanks,
>
>   -Chris
>
> -----Original Message-----
> From: Daniel Kulp [mailto:[hidden email]]
> Sent: Saturday, May 24, 2008 10:05 PM
> To: [hidden email]
> Subject: Re: Using AOP in CXF service impl
>
>
> We definitely have seen people using Spring AOP with CXF, but I think
> they've all used Spring configuration for setting up the endpoints and
> stuff.   That said, it should definitely be doable from API's since
> all the spring config does is configure the same objects via the API.
>
> CXF doesn't use proxies on the server side.   Spring must be doing
> something there.
>
> Dan
>
>
> On May 23, 2008, at 1:52 PM, Wolf, Chris (IT) wrote:
>
>> I tried using Spring's AOP support classes to implement service
>> authorization code in my CXF service, for the reason of not
>> cluttering
>
>> up my service code with security code (and maybe will also add
>> auditing/tracing).  This seems to be to classic use-case for AOP.
>>
>> Unfortunately, the AOP implementation appears to use dynamic proxy
>> techniques (instance of java.lang.reflect.Proxy) but it also appears
>> that CXF uses dynamic proxies for the service implementation, because

>> if I break in the ServiceCallPointcut code, the targetClass appears
>> to
>
>> *also* be an instance of java.lang.reflect.Proxy, so maybe there's an

>> issue using Spring AOP on dynamic proxies.
>>
>> Has anyone tried using AOP techniques in CXF service code?
>>
>> Thanks for any suggestions.
>>
>> -Chris
>>
>> [...]
>> import javax.xml.ws.WebServiceContext; import
>> javax.xml.ws.handler.MessageContext;
>> org.springframework.aop.framework.ProxyFactory;
>> import org.springframework.aop.MethodBeforeAdvice;
>> import org.springframework.aop.support.StaticMethodMatcherPointcut;
>>
>> static class ServiceCallPointcut extends StaticMethodMatcherPointcut
>> {
>>     public boolean matches(Method m, Class targetClass) {
>>         return (targetClass == this.getClass() &&
>> m.getName().matches("(add.*)|(delete.*)|(fetch.*)|(login.*)"));
>>     }
>> }
>>
>> static class AuthenticationChecker implements MethodBeforeAdvice {
>>     public void before(Method m, Object[] args, Object target) throws
>
>> Throwable {
>>         System.out.println("*** Calling " + m.getName());
>>         // transport-portable MessageContext
>>         MessageContext ctx =
>> ((SecAdminImpl)target).context.getMessageContext();
>>         // transport-specific request/response, cxf-specific property
>
>> names
>>         HttpServletRequest request = (HttpServletRequest)
>> ctx.get(MessageContext.SERVLET_REQUEST);
>>         HttpServletResponse response = (HttpServletResponse)
>> ctx.get(MessageContext.SERVLET_RESPONSE);
>>         Cookie[] cookies = request.getCookies();
>>     }
>> }
>>
>> MyServiceImpl svc = new MyServiceImpl();
>>
>> ProxyFactory factory = new ProxyFactory(svc); factory.addAdvisor(new
>> DefaultPointcutAdvisor(new ServiceCallPointcut(), new
>> AuthenticationChecker()));
>> --------------------------------------------------------
>>
>> NOTICE: If received in error, please destroy and notify sender.
>> Sender does not intend to waive confidentiality or privilege. Use of
>> this email is prohibited when received in error.
>
> ---
> Daniel Kulp
> [hidden email]
> http://www.dankulp.com/blog
> --------------------------------------------------------
>
> NOTICE: If received in error, please destroy and notify sender.  
> Sender does not intend to waive confidentiality or privilege. Use of
> this email is prohibited when received in error.

---
Daniel Kulp
[hidden email]
http://www.dankulp.com/blog
--------------------------------------------------------

NOTICE: If received in error, please destroy and notify sender. Sender does not intend to waive confidentiality or privilege. Use of this email is prohibited when received in error.
Reply | Threaded
Open this post in threaded view
|

Re: Using AOP in CXF service impl

Daniel Kulp
Administrator

On Jun 6, 2008, at 4:37 PM, Wolf, Chris (IT) wrote:

> Dan,
>
> You mentioned that CXF interceptors have a performance advantage over
> JAX-WS interceptors, such as SOAPHandler implementations because
> CXF interceptors don't read in the whole message into DOM.
>
> However, I notice that in the code for SAAJInInterceptor that, in  
> fact,
> this CXF interceptor does just that - builds a DOM of the whole  
> message
> body:
>
> line-109:
> XMLStreamReader xmlReader =
> message.getContent(XMLStreamReader.class);
>            StaxUtils.readDocElements(soapMessage.getSOAPBody(),
> xmlReader, true);
>            DOMSource bodySource = new
> DOMSource(soapMessage.getSOAPPart().getEnvelope().getBody());
>            xmlReader = StaxUtils.createXMLStreamReader(bodySource);
>
> Is it just that this particular implementation happens to do it that
> way?

That particular implementation happens to do it that way.   Basically,  
the WSS4J library that we use to do the ws-security processing  
requires the DOM.  There are "talks" about making it more Stax based,  
but that work hasn't started at all.   Thus, for ws-security, we do  
need to do the SAAJ thing.   However, if you aren't doing ws-security,  
normally the SAAJInInterceptor isn't on the chain so that doesn't  
occur.   We stream directly to/from the Stax streams to/from the JAXB  
objects for the Body parts.   The SOAP headers are slightly  
different.   We read the soap headers into DOM elements in the  
ReadHeadersInterceptor and store them in a list in the message.    
Thus, any interceptor after that interceptor can get the headers and  
process them without having the body parsed at all.   Thus, if you  
just need some SOAP headers, it's more performant to use the  
interceptors.   Things like the ws-addressing and ws-rm are  
implemented that way.

Dan



>
>
> Thanks,
>
>  -Chris
>
> P.S. the company mail client, Outlook, makes difficult to properly  
> quote
> mail responses - sorry.
>
> -----Original Message-----
> From: Daniel Kulp [mailto:[hidden email]]
> Sent: Thursday, June 05, 2008 3:29 PM
> To: [hidden email]
> Subject: Re: Using AOP in CXF service impl
>
>
> On Jun 5, 2008, at 2:51 PM, Wolf, Chris (IT) wrote:
>
>> Dan,
>>
>> Thanks for the help.  Yes, it was Spring's AOP "ProxyFactory" that  
>> was
>
>> wrapping the SEI implementation class in a dynamic proxy, and that  
>> was
>
>> the only issue.  I got confused in the debugger with the mistaken
>> impression that there was more then one layer of dynamic proxying
>> occuring.
>>
>> In any case, I resolved the issue (with Ian's suggestion).
>>
>> Now I am wondering -- why would I not just use a CXF interceptor?
>
> You definitely could do that if that's easier.   Depends on your
> requirements.   Doing the Spring AOP stuff allows use of the Acegi
> annotations and stuff so if you're used to that, thats very easy.
>
>> Is there any advantage to using an implementation of
>> AbstractPhaseInterceptor vs. using an implementation of
>> javax.xml.ws.handler.soap.SOAPHandler?
>>
>> In the later case, it seems that being JAX-WS API would mean greater
>> portability, so wouldn't that be better?
>
> It's a "portability" vs "performance/scalability" trade off that you
> need to balance for yourself.    A JAX-WS SOAPHandler has to have the
> entire SAAJ model of the soap message available.  Thus, it kind of
> breaks the streaming aspects of CXF.   It also consumes more memory as
> you have the "DOM" form in memory.   That triggers more garbage
> collections, etc....   If you have really large soap messages, it can
> be really troublesome.
>
> A CXF interceptor can get around that.   If you just need the basic
> auth tokens from the protocol headers, you can just grab those and
> ignore the contents of the message entirely.   If you just need the
> SOAP headers, you can look at them without touching the body stuff.
> etc....
>
> Basically, you have to weigh your priorities and decide which  
> direction
> is right for your project.
>
> Dan
>
>
>
>
>>
>>
>> Thanks,
>>
>>  -Chris
>>
>> -----Original Message-----
>> From: Daniel Kulp [mailto:[hidden email]]
>> Sent: Saturday, May 24, 2008 10:05 PM
>> To: [hidden email]
>> Subject: Re: Using AOP in CXF service impl
>>
>>
>> We definitely have seen people using Spring AOP with CXF, but I think
>> they've all used Spring configuration for setting up the endpoints  
>> and
>> stuff.   That said, it should definitely be doable from API's since
>> all the spring config does is configure the same objects via the API.
>>
>> CXF doesn't use proxies on the server side.   Spring must be doing
>> something there.
>>
>> Dan
>>
>>
>> On May 23, 2008, at 1:52 PM, Wolf, Chris (IT) wrote:
>>
>>> I tried using Spring's AOP support classes to implement service
>>> authorization code in my CXF service, for the reason of not
>>> cluttering
>>
>>> up my service code with security code (and maybe will also add
>>> auditing/tracing).  This seems to be to classic use-case for AOP.
>>>
>>> Unfortunately, the AOP implementation appears to use dynamic proxy
>>> techniques (instance of java.lang.reflect.Proxy) but it also appears
>>> that CXF uses dynamic proxies for the service implementation,  
>>> because
>
>>> if I break in the ServiceCallPointcut code, the targetClass appears
>>> to
>>
>>> *also* be an instance of java.lang.reflect.Proxy, so maybe there's  
>>> an
>
>>> issue using Spring AOP on dynamic proxies.
>>>
>>> Has anyone tried using AOP techniques in CXF service code?
>>>
>>> Thanks for any suggestions.
>>>
>>> -Chris
>>>
>>> [...]
>>> import javax.xml.ws.WebServiceContext; import
>>> javax.xml.ws.handler.MessageContext;
>>> org.springframework.aop.framework.ProxyFactory;
>>> import org.springframework.aop.MethodBeforeAdvice;
>>> import org.springframework.aop.support.StaticMethodMatcherPointcut;
>>>
>>> static class ServiceCallPointcut extends StaticMethodMatcherPointcut
>>> {
>>>    public boolean matches(Method m, Class targetClass) {
>>>        return (targetClass == this.getClass() &&
>>> m.getName().matches("(add.*)|(delete.*)|(fetch.*)|(login.*)"));
>>>    }
>>> }
>>>
>>> static class AuthenticationChecker implements MethodBeforeAdvice {
>>>    public void before(Method m, Object[] args, Object target) throws
>>
>>> Throwable {
>>>        System.out.println("*** Calling " + m.getName());
>>>        // transport-portable MessageContext
>>>        MessageContext ctx =
>>> ((SecAdminImpl)target).context.getMessageContext();
>>>        // transport-specific request/response, cxf-specific property
>>
>>> names
>>>        HttpServletRequest request = (HttpServletRequest)
>>> ctx.get(MessageContext.SERVLET_REQUEST);
>>>        HttpServletResponse response = (HttpServletResponse)
>>> ctx.get(MessageContext.SERVLET_RESPONSE);
>>>        Cookie[] cookies = request.getCookies();
>>>    }
>>> }
>>>
>>> MyServiceImpl svc = new MyServiceImpl();
>>>
>>> ProxyFactory factory = new ProxyFactory(svc); factory.addAdvisor(new
>>> DefaultPointcutAdvisor(new ServiceCallPointcut(), new
>>> AuthenticationChecker()));
>>> --------------------------------------------------------
>>>
>>> NOTICE: If received in error, please destroy and notify sender.
>>> Sender does not intend to waive confidentiality or privilege. Use of
>>> this email is prohibited when received in error.
>>
>> ---
>> Daniel Kulp
>> [hidden email]
>> http://www.dankulp.com/blog
>> --------------------------------------------------------
>>
>> NOTICE: If received in error, please destroy and notify sender.
>> Sender does not intend to waive confidentiality or privilege. Use of
>> this email is prohibited when received in error.
>
> ---
> Daniel Kulp
> [hidden email]
> http://www.dankulp.com/blog
> --------------------------------------------------------
>
> NOTICE: If received in error, please destroy and notify sender.  
> Sender does not intend to waive confidentiality or privilege. Use of  
> this email is prohibited when received in error.

---
Daniel Kulp
[hidden email]
http://www.dankulp.com/blog