0 Replies Latest reply on Dec 3, 2007 6:30 AM by Pavel Kadlec

    How to implement asynchronous web service in jboss esb?

    Pavel Kadlec Novice

      Hello,

      I am thinking about asynchronous web service gateway. Somebody would call web service through jboss remoting gateway (http protocol, would listnen on port, eg. 8888).

      The gateway would call esb listener asynchronously (it's now possible, there is jbr-listener boolean tag 'synchronous'). Then the action processing pipeline would be called, of course.....

      There would be SoapProcessor.......

      The webservice would have a method returning void. I would use ws-addresing tags to tell where to send method response. Last action in the action processing pipeline would read the addressing tags and send the response....

      So I have this scenario in mind but I have one problem, the implementation.....
      When I set the jbr-listner tag "synchronous" to false, the JBossRemotingGatewayListener class calls the esb listener asynchronously (that's nice) and returns string ack...

      But when I tried to use it, the client throws the exception below


      Exception in thread "main" javax.xml.ws.WebServiceException: java.io.IOException: Could not transmit message
      at org.jboss.ws.core.jaxws.client.ClientImpl.handleOneWayException(ClientImpl.java:292)
      at org.jboss.ws.core.jaxws.client.ClientImpl.invoke(ClientImpl.java:251)
      at org.jboss.ws.core.jaxws.client.ClientProxy.invoke(ClientProxy.java:164)
      at org.jboss.ws.core.jaxws.client.ClientProxy.invoke(ClientProxy.java:150)
      at $Proxy16.sayGoodbyeWithoutResponse(Unknown Source)
      at org.jboss.soa.esb.samples.quickstart.webserviceproducer.webservice.client.WSClient.main(WSClient.java:26)
      Caused by: java.io.IOException: Could not transmit message
      at org.jboss.ws.core.client.RemotingConnectionImpl.invoke(RemotingConnectionImpl.java:201)
      at org.jboss.ws.core.client.SOAPRemotingConnection.invoke(SOAPRemotingConnection.java:77)
      at org.jboss.ws.core.CommonClient.invoke(CommonClient.java:337)
      at org.jboss.ws.core.jaxws.client.ClientImpl.invoke(ClientImpl.java:243)
      ... 4 more
      Caused by: org.jboss.remoting.CannotConnectException: Can not connect http client invoker.
      at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:334)
      at org.jboss.remoting.transport.http.HTTPClientInvoker.transport(HTTPClientInvoker.java:136)
      at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:122)
      at org.jboss.remoting.Client.invoke(Client.java:1634)
      at org.jboss.remoting.Client.invoke(Client.java:548)
      at org.jboss.remoting.Client.invokeOneway(Client.java:598)
      at org.jboss.ws.core.client.RemotingConnectionImpl.invoke(RemotingConnectionImpl.java:176)
      ... 7 more
      Caused by: java.io.IOException: javax.xml.soap.SOAPException: Unsupported content type: text/html
      at org.jboss.ws.core.soap.SOAPMessageUnMarshaller.read(SOAPMessageUnMarshaller.java:92)
      at org.jboss.remoting.transport.http.HTTPClientInvoker.readResponse(HTTPClientInvoker.java:502)
      at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:306)
      ... 13 more
      Caused by: javax.xml.soap.SOAPException: Unsupported content type: text/html
      at org.jboss.ws.core.soap.MessageFactoryImpl.createMessage(MessageFactoryImpl.java:242)
      at org.jboss.ws.core.soap.SOAPMessageUnMarshaller.read(SOAPMessageUnMarshaller.java:84)
      ... 15 more


      There is method JBossRemotingGatewayListener.invoke(InvocationRequest). Its changed code would look like this. There is one small change....

      public Object invoke(InvocationRequest invocationRequest) throws Throwable {
      try {
      if (synchronous) {
      Object response = messageDeliveryAdapter.deliverSync(invocationRequest, 20000); // TODO Fix magic number
      if(logger.isDebugEnabled()) {
      logger.debug("Returning response [" + response + "].");
      }

      /*
      if(response instanceof String) {
      response = ((String)response).getBytes("UTF-8");
      }
      */

      return response;
      } else {
      messageDeliveryAdapter.deliverAsync(invocationRequest);
      }
      } catch (Throwable t) {
      logger.error("JBoss Remoting Gateway failed to " + (synchronous ? "synchronously" : "asynchronously") + " deliver message to target service [" +
      messageDeliveryAdapter.getDeliveryAdapter().getServiceCategory() + ":" +
      messageDeliveryAdapter.getDeliveryAdapter().getServiceName() + "].", t);

      throw t;
      }

      /**
      * THERE IS THE CHANGE
      * I need to change content-type and return empty string
      */
      invocationRequest.getReturnPayload().put("Content-Type", "text/xml");
      return "";
      }


      My question is, whether there is some other standard way to implement the scenario above without the change in the code. If not, do you think that I should create JIRA feature request? What do you think about the scenario?

      Regards
      Pavel