Details

    • Type: Improvement Improvement
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 1.6.1
    • Fix Version/s: None
    • Component/s: json
    • Labels:
      None

      Description

      RawXMLInOutMessageReceiver can be only used in JSON services now [1].
      However, JSON/badgerfish builder can be improved by handling RPCMessageReceiver correctly. I can't attach the patch because i have copy pasted and created my own formatters and builders(please find the source attached):

      1) It is possible to solve the namespace problem described at [1] by explicitly converting JSON/badgerfish to SOAP in JSONbadgerfish builder :
      public OMElement processDocument(InputStream inputStream, String contentType,
      MessageContext messageContext) throws AxisFault

      { .... AbstractXMLInputFactory inputFactory = new BadgerFishXMLInputFactory(); XMLStreamReader xmlReader = inputFactory.createXMLStreamReader( new JSONTokener(IOUtils.toString(reader))); OMNodeEx document = (OMNodeEx) new StAXOMBuilder(xmlReader).getDocumentElement(); //removing parent document.setParent(null); //wrapping document with envelope SOAPFactory soapFactory = OMAbstractFactory.getSOAP11Factory(); SOAPEnvelope soapEnvelope = soapFactory.getDefaultEnvelope(); SOAPBody body = soapEnvelope.getBody(); body.addChild(document); soapEnvelope.build(); //converting xml structure to soap xml structure, //this operation will construct SoapEnvelope,SoapBody,SoapFault instead of //regular OmElement StAXSOAPModelBuilder stAXSOAPModelBuilder = new StAXSOAPModelBuilder(soapEnvelope.getXMLStreamReader(), null); return stAXSOAPModelBuilder.getSOAPEnvelope(); ... }

      2) jettison 1.2 has cool feature called setIgnoreNamespaces which allows to use json formatter with any xml.

      We use the these builders and formatters successfully with JSON/badgerfish request and JSON response.

      [1] http://isurues.wordpress.com/2009/10/06/how-to-use-axis2-json/

      1. JSONMessageFormatter.java
        4 kB
        Paul Khodchenkov
      2. JSONMappedBuilder.java
        0.6 kB
        Paul Khodchenkov
      3. JSONBadgerfishMessageFormatter.java
        4 kB
        Paul Khodchenkov
      4. JSONBadgerfishBuilder.java
        0.5 kB
        Paul Khodchenkov
      5. ExtendedMappedXMLStreamWriter.java
        2 kB
        Paul Khodchenkov
      6. AbstractJSONMessageFormatter.java
        3 kB
        Paul Khodchenkov
      7. AbstractJSONBuilder.java
        5 kB
        Paul Khodchenkov

        Issue Links

          Activity

          Hide
          Hudson added a comment -

          Integrated in Axis2 #1700 (See https://builds.apache.org/job/Axis2/1700/)
          AXIS2-5158: Use Parameter#getValue() instead of Parameter#getParameterElement() to get the XML for the xmlToJsonNamespaceMap parameter. This should ensure that the feature can be used in a Synapse proxy. (Revision 1371442)

          Result = SUCCESS
          veithen :
          Files :

          • /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/JSONUtil.java
          • /axis/axis2/java/core/trunk/modules/json/test-repository/services/POJOService.aar/META-INF/services.xml
          • /axis/axis2/java/core/trunk/src/site/xdoc/docs/json_support.xml
          Show
          Hudson added a comment - Integrated in Axis2 #1700 (See https://builds.apache.org/job/Axis2/1700/ ) AXIS2-5158 : Use Parameter#getValue() instead of Parameter#getParameterElement() to get the XML for the xmlToJsonNamespaceMap parameter. This should ensure that the feature can be used in a Synapse proxy. (Revision 1371442) Result = SUCCESS veithen : Files : /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/JSONUtil.java /axis/axis2/java/core/trunk/modules/json/test-repository/services/POJOService.aar/META-INF/services.xml /axis/axis2/java/core/trunk/src/site/xdoc/docs/json_support.xml
          Hide
          Hudson added a comment -

          Integrated in Axis2 #1610 (See https://builds.apache.org/job/Axis2/1610/)
          AXIS2-5158: SOAPEnvelope#hasFault should normally not throw any exception. (Revision 1355946)

          Result = SUCCESS
          veithen :
          Files :

          • /axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/context/MessageContext.java
          Show
          Hudson added a comment - Integrated in Axis2 #1610 (See https://builds.apache.org/job/Axis2/1610/ ) AXIS2-5158 : SOAPEnvelope#hasFault should normally not throw any exception. (Revision 1355946) Result = SUCCESS veithen : Files : /axis/axis2/java/core/trunk/modules/kernel/src/org/apache/axis2/context/MessageContext.java
          Hide
          Hudson added a comment -

          Integrated in Axis2 #1513 (See https://builds.apache.org/job/Axis2/1513/)
          AXIS2-5158: Adding a sample to the documentation that shows how to enable JSON on an existing service (the ADB stock quote sample in this case). (Revision 1343034)

          Result = SUCCESS
          veithen :
          Files :

          • /axis/axis2/java/core/trunk/src/site/xdoc/docs/json_support.xml
          Show
          Hudson added a comment - Integrated in Axis2 #1513 (See https://builds.apache.org/job/Axis2/1513/ ) AXIS2-5158 : Adding a sample to the documentation that shows how to enable JSON on an existing service (the ADB stock quote sample in this case). (Revision 1343034) Result = SUCCESS veithen : Files : /axis/axis2/java/core/trunk/src/site/xdoc/docs/json_support.xml
          Hide
          Hudson added a comment -

          Integrated in Axis2 #1511 (See https://builds.apache.org/job/Axis2/1511/)
          AXIS2-5158: Updated the documentation with a description of the current architecture. The documentation previously referred to a WSO2 article that is outdated. (Revision 1343015)

          Result = SUCCESS
          veithen :
          Files :

          • /axis/axis2/java/core/trunk/src/site/xdoc/docs/json_support.xml
          Show
          Hudson added a comment - Integrated in Axis2 #1511 (See https://builds.apache.org/job/Axis2/1511/ ) AXIS2-5158 : Updated the documentation with a description of the current architecture. The documentation previously referred to a WSO2 article that is outdated. (Revision 1343015) Result = SUCCESS veithen : Files : /axis/axis2/java/core/trunk/src/site/xdoc/docs/json_support.xml
          Hide
          Hudson added a comment -

          Integrated in Axis2 #1505 (See https://builds.apache.org/job/Axis2/1505/)
          AXIS2-5158: Updated the documentation to explain how to configure an Axis2 service for use with Mapped JSON. (Revision 1342071)

          Result = SUCCESS
          veithen :
          Files :

          • /axis/axis2/java/core/trunk/src/site/xdoc/docs/json_support.xml
          Show
          Hudson added a comment - Integrated in Axis2 #1505 (See https://builds.apache.org/job/Axis2/1505/ ) AXIS2-5158 : Updated the documentation to explain how to configure an Axis2 service for use with Mapped JSON. (Revision 1342071) Result = SUCCESS veithen : Files : /axis/axis2/java/core/trunk/src/site/xdoc/docs/json_support.xml
          Hide
          Andreas Veithen added a comment -

          Checked that with the latest Axiom code, no exception is thrown anymore inside MessageContext#isFault.

          Show
          Andreas Veithen added a comment - Checked that with the latest Axiom code, no exception is thrown anymore inside MessageContext#isFault.
          Hide
          Paul Khodchenkov added a comment -

          P.S in http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/AbstractJSONMessageFormatter.java?view=markup on line 176 there is a statement:
          "Mapped format cannot handle element with namespaces.. So cannot handle Faults".
          Actually, it may serialize the fault : just need to call setIgnoreNamespaces in mapped jettison message formatter, so client will receive a proper json response for fault instead of plain text string.

          Show
          Paul Khodchenkov added a comment - P.S in http://svn.apache.org/viewvc/axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/AbstractJSONMessageFormatter.java?view=markup on line 176 there is a statement: "Mapped format cannot handle element with namespaces.. So cannot handle Faults". Actually, it may serialize the fault : just need to call setIgnoreNamespaces in mapped jettison message formatter, so client will receive a proper json response for fault instead of plain text string.
          Hide
          Paul Khodchenkov added a comment -

          One of the possible minor issues here is that RPCMessageReceiver (at least in axis 2 1.6) is sensitive to the top level arguments order. This produces a problem , if client (especially flex client, which generates json key-value ordered by key's hash ) sends json top level arguments in different order than expected by the method signature. RPCMessageReceiver will try to invoke the service method with shuffled arguments.

          Show
          Paul Khodchenkov added a comment - One of the possible minor issues here is that RPCMessageReceiver (at least in axis 2 1.6) is sensitive to the top level arguments order. This produces a problem , if client (especially flex client, which generates json key-value ordered by key's hash ) sends json top level arguments in different order than expected by the method signature. RPCMessageReceiver will try to invoke the service method with shuffled arguments.
          Hide
          Andreas Veithen added a comment -

          The code in Axis2 trunk now fully supports both Badgerfish and mapped JSON. This works out of the box with data bindings, including POJO services.

          To use mapped JSON, add a xmlToJsonNamespaceMap parameter to the service configuration to define the mappings between XML and JSON namespaces, as shown in the following sample:

          <service name="POJOService" scope="application" targetNamespace="http://example.org">
          <description>POJO Service</description>
          <schema schemaNamespace="http://example.org"/>
          <messageReceivers>
          <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
          <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
          </messageReceivers>
          <parameter name="ServiceClass">org.apache.axis2.json.POJOService</parameter>
          <parameter name="xmlToJsonNamespaceMap">
          <mapping xmlNamespace="http://example.org" jsonNamespace=""/>
          </parameter>
          </service>

          There are a couple more things to be done before the issue can be closed:

          • Add/update documentation.
          • The new JSON code relies on the feature introduced by AXIOM-399, but that feature doesn't interact in an optimal way with the optimizations described in AXIOM-282.
          • Check that the feature can be used with Synapse (and maybe add a new sample).
          Show
          Andreas Veithen added a comment - The code in Axis2 trunk now fully supports both Badgerfish and mapped JSON. This works out of the box with data bindings, including POJO services. To use mapped JSON, add a xmlToJsonNamespaceMap parameter to the service configuration to define the mappings between XML and JSON namespaces, as shown in the following sample: <service name="POJOService" scope="application" targetNamespace="http://example.org"> <description>POJO Service</description> <schema schemaNamespace="http://example.org"/> <messageReceivers> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/> <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/> </messageReceivers> <parameter name="ServiceClass">org.apache.axis2.json.POJOService</parameter> <parameter name="xmlToJsonNamespaceMap"> <mapping xmlNamespace="http://example.org" jsonNamespace=""/> </parameter> </service> There are a couple more things to be done before the issue can be closed: Add/update documentation. The new JSON code relies on the feature introduced by AXIOM-399 , but that feature doesn't interact in an optimal way with the optimizations described in AXIOM-282 . Check that the feature can be used with Synapse (and maybe add a new sample).
          Hide
          Hudson added a comment -

          Integrated in Axis2 #1412 (See https://builds.apache.org/job/Axis2/1412/)
          Improving the JSON code - Step 2 - Instead of using some hacks to extract the name of the element, just let Axiom determine it lazily using the feature introduced by AXIOM-399.

          This should make databindings work with Badgerfish (although we have no integration test for this yet) and solve AXIS2-5158, AXIS2-5295 and AXIS2-5300. (Revision 1332402)

          Result = SUCCESS
          veithen :
          Files :

          • /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/AbstractJSONDataSource.java
          • /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/AbstractJSONOMBuilder.java
          • /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/JSONBadgerfishDataSource.java
          • /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/JSONBadgerfishMessageFormatter.java
          • /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/JSONBadgerfishOMBuilder.java
          • /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/JSONDataSource.java
          • /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/JSONMessageFormatter.java
          • /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/JSONOMBuilder.java
          • /axis/axis2/java/core/trunk/modules/json/test/org/apache/axis2/json/JSONDataSourceTest.java
          • /axis/axis2/java/core/trunk/modules/json/test/org/apache/axis2/json/JSONOMBuilderTest.java
          Show
          Hudson added a comment - Integrated in Axis2 #1412 (See https://builds.apache.org/job/Axis2/1412/ ) Improving the JSON code - Step 2 - Instead of using some hacks to extract the name of the element, just let Axiom determine it lazily using the feature introduced by AXIOM-399 . This should make databindings work with Badgerfish (although we have no integration test for this yet) and solve AXIS2-5158 , AXIS2-5295 and AXIS2-5300 . (Revision 1332402) Result = SUCCESS veithen : Files : /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/AbstractJSONDataSource.java /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/AbstractJSONOMBuilder.java /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/JSONBadgerfishDataSource.java /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/JSONBadgerfishMessageFormatter.java /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/JSONBadgerfishOMBuilder.java /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/JSONDataSource.java /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/JSONMessageFormatter.java /axis/axis2/java/core/trunk/modules/json/src/org/apache/axis2/json/JSONOMBuilder.java /axis/axis2/java/core/trunk/modules/json/test/org/apache/axis2/json/JSONDataSourceTest.java /axis/axis2/java/core/trunk/modules/json/test/org/apache/axis2/json/JSONOMBuilderTest.java
          Hide
          PNS added a comment - - edited

          Axis2 is too mainstream a technology to not support plain vanilla JSON ("Mapped JSON", if you prefer) and to require workarounds.

          It is really surprising that we have reached version 1.6.1 without a permanent, transparent and working solution. From the brief minutes of the Vancouver meeting, there seems to be no intention to resolve in forthcoming releases, either.

          The sooner this issue is dealt with, the better.

          Show
          PNS added a comment - - edited Axis2 is too mainstream a technology to not support plain vanilla JSON ("Mapped JSON", if you prefer) and to require workarounds. It is really surprising that we have reached version 1.6.1 without a permanent, transparent and working solution. From the brief minutes of the Vancouver meeting, there seems to be no intention to resolve in forthcoming releases, either. The sooner this issue is dealt with, the better.
          Hide
          Paul Khodchenkov added a comment -

          Increasing popularity of JSON requires to have more intelligent support for JSON in Axis2 .
          We use WSO2 ESB( axis2 is used as core engine) in our environment. One of the requirements was to expose the existing SOAP services over JSON in order to support flex/mobile devices.
          The current JSON implementation forces the service to handle payload in a raw way. So the POJO Axis2 services can't expose JSON interfaces(mapped convention) automatically without altering the service. However, after looking to the sources of JSONBadgerfishBuilder i realized that it is possible to handle application/json/badgerfish and application/json request-response scenario if we convert badgerfish to soap in explicit way .
          This allows to:
          1) expose existing axis2 services as application/json/badgerfish for requests and application/json for response
          2) apply the same mediation rules in WSO2 ESB for both application/json/badgerfish and SOAP requests ( application/json/badgerfish is explicitly converted to SOAP so there is no difference between them)
          3) expose json/badgerfish interfaces for non axis2 SOAP services behind the WSO2 ESB

          The only problem here is that client should understand badgerfish notation. To provide json interfaces without badgerfish we use xslt transformations inside ESB proxy to enrich json request with the required SOAP namespaces and attributes. so the backend SOAP service will correctly accept such payload. However, this should be done manually for each service operation.
          In the ideal situation Axis2 JSON builder should be able(along with ability to use json with POJO service) to fetch the required information from service wsdl and construct SOAP request based on the incoming json request(non badgerfish), so it will provide a cool way to automatically expose JSON services on ESB for any SOAP service.
          Thanks

          Show
          Paul Khodchenkov added a comment - Increasing popularity of JSON requires to have more intelligent support for JSON in Axis2 . We use WSO2 ESB( axis2 is used as core engine) in our environment. One of the requirements was to expose the existing SOAP services over JSON in order to support flex/mobile devices. The current JSON implementation forces the service to handle payload in a raw way. So the POJO Axis2 services can't expose JSON interfaces(mapped convention) automatically without altering the service. However, after looking to the sources of JSONBadgerfishBuilder i realized that it is possible to handle application/json/badgerfish and application/json request-response scenario if we convert badgerfish to soap in explicit way . This allows to: 1) expose existing axis2 services as application/json/badgerfish for requests and application/json for response 2) apply the same mediation rules in WSO2 ESB for both application/json/badgerfish and SOAP requests ( application/json/badgerfish is explicitly converted to SOAP so there is no difference between them) 3) expose json/badgerfish interfaces for non axis2 SOAP services behind the WSO2 ESB The only problem here is that client should understand badgerfish notation. To provide json interfaces without badgerfish we use xslt transformations inside ESB proxy to enrich json request with the required SOAP namespaces and attributes. so the backend SOAP service will correctly accept such payload. However, this should be done manually for each service operation. In the ideal situation Axis2 JSON builder should be able(along with ability to use json with POJO service) to fetch the required information from service wsdl and construct SOAP request based on the incoming json request(non badgerfish), so it will provide a cool way to automatically expose JSON services on ESB for any SOAP service. Thanks
          Hide
          Andreas Veithen added a comment -

          As explained in Isuru's blog, the current implementation constructs an OMSourcedElement so that the original JSON payload can be accessed in scenarios where it is not necessary to convert it to XML. I guess that this is relevant for ESB scenarios where a JSON request is forwarded to an endpoint that accepts JSON. The problem is that Axiom currently requires that the local name and namespace URI is known when constructing the OMSourcedElement. The current JSON implementation is unable to determine this information and that's why the request is not dispatched correctly, which is why it doesn't work with RPCMessageReceiver.

          Interestingly nothing would prevent Axiom from supporting OMSourcedElements with unknown local name and namespace URI. The only constraint is that such an OMSourcedElement needs to be automatically expanded when getLocalName(), getNamespace() or getQName() is called (which in the scenario described here would occur during dispatching). Axiom actually already supports this for the namespace prefix which can be determined lazily (see AXIOM-334). It would be natural to extend this concept to the local name and namespace URI.

          Show
          Andreas Veithen added a comment - As explained in Isuru's blog, the current implementation constructs an OMSourcedElement so that the original JSON payload can be accessed in scenarios where it is not necessary to convert it to XML. I guess that this is relevant for ESB scenarios where a JSON request is forwarded to an endpoint that accepts JSON. The problem is that Axiom currently requires that the local name and namespace URI is known when constructing the OMSourcedElement. The current JSON implementation is unable to determine this information and that's why the request is not dispatched correctly, which is why it doesn't work with RPCMessageReceiver. Interestingly nothing would prevent Axiom from supporting OMSourcedElements with unknown local name and namespace URI. The only constraint is that such an OMSourcedElement needs to be automatically expanded when getLocalName(), getNamespace() or getQName() is called (which in the scenario described here would occur during dispatching). Axiom actually already supports this for the namespace prefix which can be determined lazily (see AXIOM-334 ). It would be natural to extend this concept to the local name and namespace URI.
          Hide
          Sagara Gunathunga added a comment - - edited

          Other than above MessageReceiver limitation current JSON support perform number of extra XML/JSON conventions in both client and server sides in order to match with existing Axis2 architecture. The proper solution would be serialize/deserialize JSON to Java objects and back again directly but this required some refactoring , google-gson [1] can be a good framework for this propose with it's performance and streaming support.

          BTW as a short term solution we can include your modification to work with RPCMessageReceivers. BTW it's bit of difficult task to review raw source files instead can you please provide your modification as a svn patch for Axis2 trunk. It Would be great if you can provide a unit test for this too .

          [1] - http://code.google.com/p/google-gson/

          Show
          Sagara Gunathunga added a comment - - edited Other than above MessageReceiver limitation current JSON support perform number of extra XML/JSON conventions in both client and server sides in order to match with existing Axis2 architecture. The proper solution would be serialize/deserialize JSON to Java objects and back again directly but this required some refactoring , google-gson [1] can be a good framework for this propose with it's performance and streaming support. BTW as a short term solution we can include your modification to work with RPCMessageReceivers. BTW it's bit of difficult task to review raw source files instead can you please provide your modification as a svn patch for Axis2 trunk. It Would be great if you can provide a unit test for this too . [1] - http://code.google.com/p/google-gson/

            People

            • Assignee:
              Andreas Veithen
              Reporter:
              Paul Khodchenkov
            • Votes:
              2 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

              • Created:
                Updated:

                Development