1 2 Previous Next 23 Replies Latest reply: Feb 9, 2012 7:28 AM by Paul Robinson RSS

Can I modify the HandlerChain at deploy time?

Paul Robinson Master

I am improving the usability of JBoss XTS by providing annotation support. I have one class level annotation that when applied to a JAX-WS service implementation, indicates to the middleware to carry out a few pieces of work, removing a lot of burden from the developer.

 

One of these "pieces of work" is to add two handlers to the JAX-WS handler chain. Using CDI I can intercept the calls to the service, but this occurs after the handler chain has been invoked. I was thinking that at some point in the deployment process, I could query the Service Impl class for the required annotation, and if found, setup the appropriate handler chain.

 

I was wondering:

 

a) Is what I am proposing the right way to do this?

b) If so, can you point me at the right place to hook into?

c) Do you know of a better way for me to achieve this?

 

Any help would be greatly appreciated,

 

Thanks,

 

Paul.

  • 1. Re: Can I modify the HandlerChain at deploy time?
    Alessio Soldano Master

    Hi Paul,

    first of all, I moved this discussion to the development section of the forum.

     

    Now, I see some alternatives for you to achieve what you need:

     

    1) The user is supposed to specify handlers either using JAXWS annotation (@HandlerChain) or through the jbossws endpoint configurations (@EndpointConfig and then provide a configuration file with handlers specification in the deployment or reference a configuration in the AS7 domain). So the first option is asking users to properly annotate endpoint classes, not sure this is acceptable for your use case.

     

    2) You could make sure a webservices.xml descriptor (JSR-109) is added to the deployment and specify the handlers in there. The descriptor is parsed during the Phase.PARSE in AS7.

     

    3) You could also hook in a little bit later then what you'd do for 2) and modify the jbossws spi metadata that are created after parsing the webservices.xml descriptor. To be honest, you'd need actually create them most of the time, given it's not that common to have webservices.xml for JAXWS deployments. Btw, there's a little bug I just discovered here, I'm going to fix it later today or tomorrow.

     

    4) Another alternative is using the Apache CXF API, but that would bind you to implementation details of cxf and still require some changes in jbossws for you to hook into the proper point in the endpoint publish process.. so not really a good option.

  • 2. Re: Can I modify the HandlerChain at deploy time?
    Alessio Soldano Master

     

    3) You could also hook in a little bit later then what you'd do for 2) and modify the jbossws spi metadata that are created after parsing the webservices.xml descriptor. To be honest, you'd need actually create them most of the time, given it's not that common to have webservices.xml for JAXWS deployments. Btw, there's a little bug I just discovered here, I'm going to fix it later today or tomorrow.

     

     

    Actually this would be better then 2) because you could *add* stuff over metadata info coming from a webservices.xml a user already provided.

  • 3. Re: Can I modify the HandlerChain at deploy time?
    Paul Robinson Master

    Alessio,

     

    Thanks for the reply. I was in two minds whether to post on the dev or user section. I'll stick to the dev section in future, for issues like this.

     

    1) & 2) arn't really an option as:

     

    A. They don't remove the burden from the developer.

    B. Different handlers will be deployed depending on the annotation. This is not something I want the user to have to understand or remember to do.

     

    4) Doesn't sound like a good idea, due to the reasons you mention.

     

    3) Sounds most promising. I have the following questions:

     

    A. Will this require any changes to jbossws?

    B. Will the code I plug in have access to the service implementation class? I will need to pull off the annotations to decide what to do with the handler chain. I don't need access to the actual instance.

    C. Would I need to do anything special, in the situation where the developer has included a webservices.xml for an unrelated purpose?

     

    To be clear, I think I need two things:

     

    1) Access to the handlerchain in order to insert my own handler.

    2) Access to the service impl class so that I can read off the annotations.

     

    Thanks,

     

    Paul.

  • 4. Re: Can I modify the HandlerChain at deploy time?
    Alessio Soldano Master

    3) Sounds most promising. I have the following questions:

     

    A. Will this require any changes to jbossws?

     

    Besides the bug I need to fix, no.

     

    B. Will the code I plug in have access to the service implementation class? I will need to pull off the annotations to decide what to do with the handler chain. I don't need access to the actual instance.

     

    Well, you can get access to the annotations attached to a given class by looking into the AS7 jandex annotation index. You just need to have your code run in the proper phase / sequence order, iow you'll need to have the annotation index already created and the webservices install processors not run yet (so that the ws deployers already see the metadata that have been modified by you).

     

     

    C. Would I need to do anything special, in the situation where the developer has included a webservices.xml for an unrelated purpose?

     

     

    You'll need to add your handlers to the other the user might have already specified and the other information in the metadata for that descriptor. We can have another discussion about the details of the org.jboss.wsf.spi.metadata.webservices.WebservicesMetaData if you want/need. In the mean time, you can have a look at that in the jbossws-spi project. The handlers stuff lives in WebserviceDescriptionMetaData -> PortComponentMetaData -> UnifiedHandlerChainsMetaData . To get an idea, the code here (processWSDDContribution method) is what will be processing those metadata: http://anonsvn.jboss.org/repos/jbossws/stack/cxf/tags/jbossws-cxf-4.0.0.CR1/modules/server/src/main/java/org/jboss/wsf/stack/cxf/metadata/MetadataBuilder.java

     

    Hope this helps :-)

  • 5. Re: Can I modify the HandlerChain at deploy time?
    Paul Robinson Master

    Thanks Alessio,

     

    I'll take a look at the code you refer to, and get back to you once I have digested it.

     

    Paul.

  • 6. Re: Can I modify the HandlerChain at deploy time?
    Alessio Soldano Master

    3) Sounds most promising. I have the following questions:

     

    A. Will this require any changes to jbossws?

     

    Besides the bug I need to fix, no.

     

    For the records, the bug is https://issues.jboss.org/browse/JBWS-3398 , which should be solved now.

  • 7. Re: Can I modify the HandlerChain at deploy time?
    Paul Robinson Master

    Alessio,

     

    I've been looking at the code, and I have a rough idea of where I need to begin.

     

    1) I think I need to impliment an AbstractDeploymentAspect and specify it in jbossws-cxf-config-as7.xml? Is there another place that I can specify my AbstractDeploymentAspect impl as I'd prefer not to require the JBossWS code to be changed. I'm sure you wouldn't want me to do that either.

     

    2) When registering my AbstractDeploymentAspect impl, I need to specify that I depend on some other AbstractDeploymentAspect implimentations. This will ensure my code is invoked at the right time.

     

    3) My impl of AbstractDeploymentAspect should query the Deployment object to find out what services are being deployed.

     

    4) I then look up the service classes in jandex and obtain for my annotations.

     

    5) I make some call on the Deployment object to specify the handler(s) I wish to add to the handler chain. This handler is put in place when the  MetadataBuilder is invoked from DescriptorDeploymentAspect.

     

    Does this make sense so far?

     

    Thanks,

     

    Paul.

  • 8. Re: Can I modify the HandlerChain at deploy time?
    Alessio Soldano Master

    Hi Paul,

    you shouldn't (need) to play with the JBossWS integration deployment aspects. Your additional deployer (DeploymentUnitProcessor (DUP) in AS7) would likely live in the AS7 XTS subsystem and use the JBossWS SPI to modify the org.jboss.wsf.spi.metadata.webservices.WebservicesMetaData that is created during Phase.PARSE of AS7.

    I would wire that new DUP into the deployers chain after the Phase.PARSE_JBOSS_WEBSERVICES_XML, so once the WebservicesDescriptorDeploymentProcessor and JBossWebservicesDescriptorDeploymentProcessor have run. Those two basically create the WebservicesMetaData into the deployment unit if a webservices.xml is found in the deployment. You'd need to update that object or create it if the webservices.xml was not in the deployment. Once that's done, the jboss-as7 / jbossws deployment can go on as is and your additional info will be considered.

    If you want to have get an idea of the DUP that are involved in the ws part of the deployment process, the class that adds them is org.jboss.as.webservices.dmr.WSDeploymentActivator

  • 9. Re: Can I modify the HandlerChain at deploy time?
    Alessio Soldano Master

    Forgot to say, the deployment aspect you saw are wrapped into DUP by the AS7 Webservices subsystem integration, and are executed in the later phases; you won't need to touch them at all.

     

    In your new DUP, you will have to retrieve the annotation index (should be attached to the deployment unit) and use it to decide wether to install your handlers or not.

  • 10. Re: Can I modify the HandlerChain at deploy time?
    Paul Robinson Master

    Alessio,

     

    I've finally got all my EAP 6.0 issues off my plate (for now), so I can return to this.

     

    I've implimented a DeploymentActivator and it is succesfully registering a DeploymentUnitProcessor when the XTS subsytem boots, I've even got it reading off the annotations, looking for the one I am interested in. I'm now ready to add a handler to the handler chain.

     

    The problem I have is with getting the DeploymentUnitProcessor#deploy method be invoked after WSHandlerChainAnnotationProcessor#deploy. My understanding was that I should add an entry to Phase:

     

     

        ...

        public static final int PARSE_JAXWS_HANDLER_CHAIN_ANNOTATION        = 0x2055;

        public static final int PARSE_TXFRAMEWORK_HANDLERS                  = 0x2056;

        ...

     

     

    I've added it after PARSE_JAXWS_HANDLER_CHAIN_ANNOTATION and set the value as above. I was thinking the value represented the order in which they should be invoked. However, I've tried changing the values and the ordering does not change. My TXFramework DUP is always invoked before the WSHandlerChainAnnotationProcessor DUP. I've tried to find out where else in the code, the ordering is impossed and I'm having no luck. Can you point me at the code that sets the order?

     

    Thanks,

     

    Paul.

  • 11. Re: Can I modify the HandlerChain at deploy time?
    Paul Robinson Master

    Alessio,

     

    I did an "mvn clean install", and the ordering is now as I would expect. From looking at the code, and from observing the order that the DUPs are called, the priority value is absoerved.

     

    Short answer is, I've fixed the problem in my previous message.

     

    Paul.

  • 13. Re: Can I modify the HandlerChain at deploy time?
    Paul Robinson Master

    Allessio

     

    I'm at the point where I think I have correctly configured the metadata to include the handler. In my example, I have an existing handler (org.my.simple.server.MyServerHandler) defined by a @HandlerChain annotation on the WS impl. I then add another Handler (org.jboss.as.xts.TXFrameworkHandler) to the mapping at deployment time in my DUP.

     

    I put a breakpoint in WSIntegrationProcessorJAXWS_HANDLER#processAnnotation, on the following line:

     

    final WSEndpointHandlersMapping mapping = getRequiredAttachment(unit, WS_ENDPOINT_HANDLERS_MAPPING_KEY);

     

     

    The debugger provides the following output:

     

     

    mapping = {org.jboss.as.webservices.injection.WSEndpointHandlersMapping@626}
         endpointHandlersMap = {java.util.HashMap@646} size = 1
              [0] = {java.util.HashMap$Entry@653} org.my.simple.server.EchoServiceImpl -> [org.my.simple.server.MyServerHandler, org.jboss.as.xts.TXFrameworkHandler]
                   key: java.lang.String = {java.lang.String@657}"org.my.simple.server.EchoServiceImpl"
                   value: java.util.HashSet = {java.util.HashSet@627} size = 2
                        [0] = {java.lang.String@638}"org.my.simple.server.MyServerHandler"
                        [1] = {java.lang.String@664}"org.jboss.as.xts.TXFrameworkHandler"
    
    
    

     

    So, it looks to me like I have setup the WSEndpointHandlersMapping correctly. However, The only handler that is invoked is the MyServerHandler. I've tried removing this handler from the set, in my DUP, and it is still invoked. This suggests to me that I'm either adding the wrong informtion, or doing it too late.

     

     

    The order in which the relevent (IMO) DUPS are invoked is as follows:

     

    1. WSHandlerChainAnnotationProcessor
    2. TXFrameworkDeploymentProcessor (mine)
    3. WSIntegrationProcessorJAXWS_HANDLER
    4. WSRefAnnotationProcessor

     

    In particular, here's the relavent (IMO) Phase priorities:

     

     


    public static final int PARSE_WEBSERVICES_XML       
    = 0x2050;

    public static final int PARSE_JBOSS_WEBSERVICES_XML             = 0x2051;

    public static final int PARSE_JAXWS_EJB_INTEGRATION             = 0x2052;

    public static final int PARSE_JAXRPC_POJO_INTEGRATION           = 0x2053;

    public static final int PARSE_JAXRPC_EJB_INTEGRATION            = 0x2054;

    public static final int PARSE_JAXWS_HANDLER_CHAIN_ANNOTATION    = 0x2055;

    public static final int PARSE_TXFRAMEWORK_HANDLERS              = 0x2056;

    public static final int PARSE_WS_JMS_INTEGRATION                = 0x2057;

    public static final int PARSE_JAXWS_ENDPOINT_CREATE_COMPONENT_DESCRIPTIONS = 0x2058;

    public static final int PARSE_JAXWS_HANDLER_CREATE_COMPONENT_DESCRIPTIONS = 0x2059;

     

    Do you have any idea why the WSEndpointHandlersMapping seems to be ignored?

     

    Thanks,

     

    Paul.

  • 14. Re: Can I modify the HandlerChain at deploy time?
    Alessio Soldano Master

    Hi Paul,

    the WS-AS7 integration evolved a lot after we initially discussed about this in December.

    AFAIU the changes you've been doing basically add your handler to the list (map, actually) that used to create AS7 component descriptors; that ensures things like proper jndi context propagation etc.

    What you should still do are the changes I described in my previous posts, ie. modify the WebServicesMetaData (in the handlerchain section) to include your own handler. See https://community.jboss.org/message/641748#641748message #8 (Dec 15, 2011 6:30 AM)

    We can IRC chat a bit on this tomorrow if you want.

1 2 Previous Next