8 Replies Latest reply on Aug 1, 2007 11:43 AM by lowecg2004

    Is there a JBossWS client example for invoking a Seam ws?

    lowecg2004

      I've successfully setup a Seam web service, generated the proxies using wsconsume and installed the Seam conversation SOAP handler.

      I'm having real difficulty finding out how to add/read the conversationId SOAP header. Without it I just get this exception:

      Caused by: java.lang.NullPointerException
       at org.jboss.seam.webservice.SOAPRequestHandler.extractConversationId(SOAPRequestHandler.java:137)
       at org.jboss.seam.webservice.SOAPRequestHandler.handleInbound(SOAPRequestHandler.java:75)
       at org.jboss.seam.webservice.SOAPRequestHandler.handleMessage(SOAPRequestHandler.java:56)
       at org.jboss.ws.core.jaxws.handler.HandlerChainExecutor.handleMessage(HandlerChainExecutor.java:295)
       at org.jboss.ws.core.jaxws.handler.HandlerChainExecutor.handleMessage(HandlerChainExecutor.java:140)
       ... 27 more


      Could anyone point me to the right documentation/example/anything that might help?

      Shouldn't the lack of conversationId header just be ignored since that implies all my Seam web services must be conversational? I may wish to have a mix of web services where some may be stateless or just work at the session context?

      I tried implementing a web service without the SOAP handler (because of the aforementioned NPE) using a similar example to a simple stateful web service example suggested by Rama Pulavarthi:

      http://weblogs.java.net/blog/ramapulavarthi/archive/2006/06/maintaining_ses.html

      The web service is invoked just fine, however anything I save to HttpSession using setAttribute() does not survive beyond the request. So, on a subsequent request to a servlet using the JSESSIONID obtained from the WS call, the corresponding getAttribute call returns null.

      I tried to have a go at debugging this and thought that SessionContext.flush() might be a good place to start digging around (my web service also placed some values into SessionContext) but this was never called. I suppose that makes sense given that I commented out the handler responsible for managing contexts ;) However, could the lack of SOAP handler also cause the values I saved to a regular HttpSession to not be saved?

      Cheers,

      Chris

      Here is my WS code:

      @Name("developmentService")
      @Stateless
      @WebService(name = "DevelopmentService", serviceName = "DevelopmentService" )
      public class DevelopmentAuthenticator implements DevelopmentServiceRemote
      {
       @Logger Log log;
      
       @Resource
       private WebServiceContext wsContext;
      
       @WebMethod
       public boolean login(final String username,
       final String password) {
      
       final MessageContext mc = wsContext.getMessageContext();
      
       // This would be called during an AppletViewer session before any server calls. Therefore,
       // create a HttpSession so the HTTP response has a JSESSIONID cookie which can be used
       // by all other server requests.
       final HttpSession session =
       ((HttpServletRequest)mc.get(MessageContext.SERVLET_REQUEST)).getSession();
      
       if (session == null) {
       throw new WebServiceException("No session in WebServiceContext");
       }
      
       // do authentication
       Identity.instance().setUsername(username);
       Identity.instance().setPassword(password);
      
       Identity.instance().login();
      
       final boolean isLoggedIn = Identity.instance().isLoggedIn();
      
       if (isLoggedIn) {
       // Authenticator stores the userId on the SessionContext
       final Integer userId = (Integer) Contexts.getSessionContext().get("userId");
      
       // verify that userId is set
       if (userId == null) {
       log.warn("User ID not set after successful login in web service call.");
       }
      
       // transfer the user id to the HttpSession to allow access from all JEE entities,
       // not just Seam components.
       session.setAttribute("userId", userId);
      
       log.info("adding userId: {0} to session {1}", session.getAttribute("userId"), session.getId());
       }
      
       return isLoggedIn;
       }
      
      }


        • 1. Re: Is there a JBossWS client example for invoking a Seam ws
          shane.bryzak

          I've fixed the NPE in CVS, it was a bug. As for your other issue, does your web service client support cookies for propagating the session ID? We currently have a concern that a web service client without cookie support will have no session management, and are contemplating whether we should embed the session ID in the SOAP packets similar to what we do with conversation ID's. Anyway, it would be great if you could re-test again with latest CVS and let me know how that goes.

          • 2. Re: Is there a JBossWS client example for invoking a Seam ws
            lowecg2004

            Shane,

            Thanks for your reply, I'll give the new build a go.

            As for the session ID, I've been trying to add a cookie to a client generated by the JBossWS 2.0.0.GA wsconsume tool without any luck. As far as I understand session support in the client, it looks like you can instruct the client to participate in a session which it creates and manages itself. I was able to do this and get the resulting JSESSIONID cookie from the WS call. However I've not yet found a way to make a WS participate in an existing session (i.e. set my own JSESSIONID Cookie header).

            I believe there are some issues with session management in the 2.0.0 release. In particular, a session may be created but appears to get lost during subsequent requests. My prefered approach would have been to add the JSESSIONID myself rather than letting the client handle it, that way I can have servlets/web services/you name it all part of the same session. I'd also posted on the JBossWS regarding session management however I've yet to receive a reply:

            http://www.jboss.com/index.html?module=bb&op=viewtopic&t=112660

            I've had an equally tough time adding a SOAP header from a JAX-WS 2.0 client runtime (JDK 6) in order to specify the conversation ID. Under JAX-WS 2.1 it looks very straight forward, but I've not found a portable solution for JAX-WS 2.0. I'm probably missing something obvious, but variations in standards and versions and even behaviour between vendors has just left me completely confused and bewildered.

            What clients have you guys been using for your testing?

            Cheers,

            Chris.

            • 3. Re: Is there a JBossWS client example for invoking a Seam ws
              lowecg2004

              Shane,

              I can confirm that I no longer get the NPE. httpSession.getAttribute("userId") is still returning null though.

              Cheers,

              Chris.


              PS - my WS code is given in the original post. To complete the picture, here is my client call and how to get at the JSESSIONID:

              final DevelopmentService_Service service = new DevelopmentService_Service();
              final DevelopmentService proxy = service.getDevelopmentServicePort();
              
              ((BindingProvider)proxy).getRequestContext().put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true);
              
              // the following web service call will create a new HttpSession
              // and attempt a login using the supplied credentials
              final boolean result = proxy.login(username, password);
              
              // Extract the JSESSIONID cookie from the response.
              final Map responseMap = ((BindingProvider)proxy).getResponseContext();
              
              final Map headerValues = (Map)responseMap.get(MessageContext.HTTP_RESPONSE_HEADERS);
              
              final List<String> cookieHeaders = (List<String>) headerValues.get("Set-Cookie");
              
              // You can then use HttpCookie.parse() to parse and process the cookies and test for JSESSIONID etc.




              • 4. Re: Is there a JBossWS client example for invoking a Seam ws
                shane.bryzak

                I've been using soapUI (http://www.soapui.org/) for some testing, though in my limited experience I don't think it supports cookies. The web services test page in the seambay example actually sends a web service request from the browser, so it automatically gets cookie support (and therefore session propagation).

                However I've not yet found a way to make a WS participate in an existing session (i.e. set my own JSESSIONID Cookie header).


                What do you mean by "existing session"? Is this a session that is created within a web app? Keep in mind that the JBossWS servlet is different to your application (Seam) servlet, and that you are always going to have different session instances between the two.

                • 5. Re: Is there a JBossWS client example for invoking a Seam ws

                  Actually, SoapUI does support cookies. When you create a multi-step test case, you can right click on the test case, select Options and then "Maintain HTTP Session". It can also be configured to support the Seam conversationId in SOAP header. See:

                  http://www.michaelyuan.com/blog/2007/07/31/seam-and-soa/

                  cheers
                  Michael

                  • 6. Re: Is there a JBossWS client example for invoking a Seam ws
                    lowecg2004

                    Darn it - I'd confused myself with the fact that the web service code was part of the Seam app and didn't appreciate that the WS servlet was elsewhere. I guess that scuppers my plans until HttpSession sharing between WAR modules is implemented (which has just received my vote):

                    http://jira.jboss.com/jira/browse/JBAS-2861

                    To clarify what I meant by using an "existing session": I was using a Java applet embedded within a Seam application which I wanted to interact with same session by passing in the web page's JSESSIONID to the applet by parameter.

                    Cheers,

                    Chris.

                    • 7. Re: Is there a JBossWS client example for invoking a Seam ws
                      djohan0817

                      I want to use wsprovide tools to generate portable jax-ws artifacts. Could you give me some help? Should i use a command prompt to invoke wsprovide? If yes, HOW? Thanks in advance.

                      Johan

                      • 8. Re: Is there a JBossWS client example for invoking a Seam ws
                        lowecg2004

                        Unfortunately I have not used wsprovide:

                        http://jbws.dyndns.org/mediawiki/index.php?title=Wsprovide

                        Correct me if I'm wrong, but I don't think you need wsprovide if you're using Seam web services. Do you mean wsconsume for generating client artifacts?