14 Replies Latest reply on Jun 6, 2013 9:17 AM by fenoloco

    Service with SOAP binding (Default transformation)

    fenoloco

      Hi,

      I have just started to play with SY and I have a question. 

      First I defined a service from a java interface then I added a Bean that implement the interface and finally I defined a SAOP binding.

       

       

      My files are.

      Interface TestService2.java

       

      public interface TestService2 {
                String echo(String value);
                String reverse(String value);
      }
      

       

       

      Bean TestService2Imp.java

       

      @Service(TestService2.class)
      public class TestService2Imp implements TestService2 {
      
                @Override
                public String echo(String value) {
                          return value;
                }
      
                @Override
                public String reverse(String value) {
                          return new StringBuilder(value).reverse().toString();
                } 
      }
      

       

      switchYard.xml

       

      <?xml version="1.0" encoding="UTF-8"?>
      <switchyard xmlns="urn:switchyard-config:switchyard:1.0" xmlns:bean="urn:switchyard-component-bean:config:1.0" xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:soap="urn:switchyard-component-soap:config:1.0" name="SW-SOAP" targetNamespace="urn:com.example.switchyard:SW-SOAP:1.0">
        <sca:composite name="SW-SOAP" targetNamespace="urn:com.example.switchyard:SW-SOAP:1.0">
          <sca:service name="TestService2" promote="TestService2Impl/TestService2">
            <sca:interface.java interface="com.example.switchyard.SW_SOAP.TestService2"/>
            <soap:binding.soap>
              <soap:contextMapper/>
              <soap:wsdl>META-INF/TestService2.wsdl</soap:wsdl>
              <soap:wsdlPort>TestService2Port</soap:wsdlPort>
              <soap:socketAddr>:8080</soap:socketAddr>
              <soap:contextPath>SW-SOAP</soap:contextPath>
              <soap:endpointAddress>http://localhost:8080/SW-SOAP/TestService2</soap:endpointAddress>
            </soap:binding.soap>
          </sca:service>
          <sca:component name="TestService2Impl">
            <bean:implementation.bean class="com.example.switchyard.SW_SOAP.TestService2Impl"/>
            <sca:service name="TestService2">
              <sca:interface.java interface="com.example.switchyard.SW_SOAP.TestService2"/>
            </sca:service>
          </sca:component>
        </sca:composite>
      </switchyard>
      


       

      When I invoke the method,  the value param have all the xml of the request, I think I have to define a transformation to get the parameters. 

      The question is: I will have to define a transformation ( by hand ) for all my WS?

       

      Thanks in advance,

        • 1. Re: Service with SOAP binding (Default transformation)
          fenoloco

          Hi, again

           

          I viewed the SY video series (episode6) and I learned the way to autogenerate JAXB transformation. ( The videos are here)

          I choose JAXB Transformer, all is ok for a POJO class annotated with @XmlRootElement, but if I have a String as a parameter, I always get this error when Invoke the service.

           

          <faultstring>org.switchyard.exception.SwitchYardException: Failed to unmarshall for 'java:java.lang.String'.</faultstring>
          

           

          Any idea?

          Thanks again.

          • 2. Re: Service with SOAP binding (Default transformation)
            kcbabo

            If you are using String as a payload type, a JAXB transformer won't work.  The default payload type for SOAP bindings will be a DOMSource and there should be a transformer which automatically transforms that to String.  Try removing the JAXB transformer definition from your application for the XML type to String and see what happens.

            • 3. Re: Service with SOAP binding (Default transformation)
              fenoloco

              Hi Keith,

              Thanks for the quick response.

               

              The autogenerated transaccion was

               <transforms>
                  <transform:transform.jaxb from="java:com.example.switchyard.ExampleStringTrx.PojoParam" to="{urn:com.example.switchyard:ExampleStringTrx:1.0}reversePojoResponse"/>
                  <transform:transform.jaxb from="java:java.lang.String" to="{urn:com.example.switchyard:ExampleStringTrx:1.0}reverseSimpleResponse"/>
                  <transform:transform.jaxb from="{urn:com.example.switchyard:ExampleStringTrx:1.0}reversePojo" to="java:com.example.switchyard.ExampleStringTrx.PojoParam"/>
                  <transform:transform.jaxb from="{urn:com.example.switchyard:ExampleStringTrx:1.0}reverseSimple" to="java:java.lang.String"/>
                </transforms>
              

               

              I deleted these lines

               

                  <transform:transform.jaxb from="java:java.lang.String" to="{urn:com.example.switchyard:ExampleStringTrx:1.0}reverseSimpleResponse"/>
                  <transform:transform.jaxb from="{urn:com.example.switchyard:ExampleStringTrx:1.0}reverseSimple" to="java:java.lang.String"/>
              

               

              The method is now receiving the soap request message and not the parameters, so this error is throw

               

              Transformations not applied.  Required payload type of 'java:java.lang.String'.  Actual payload type is '{urn:com.example.switchyard:ExampleStringTrx:1.0}reverseSimple'.  You must define and register a Transformer to transform between these types.
              

               

               

              I attacked the example if you would check it.

               

              Thanks again.

              Mauricio

              • 4. Re: Service with SOAP binding (Default transformation)
                kcbabo

                Ah, sorry forgot one step.  You can use the OperationTypes annotation in your Java interface to indicate that you want to pass the XML value directly through:

                 

                https://docs.jboss.org/author/display/SWITCHYARD/Bean+Services+-+Extra

                 

                So the updated method on your TestService interface would look like:

                 

                 

                @OperationTypes(
                        in = "{urn:com.example.switchyard:ExampleStringTrx:1.0}reverseSimple",
                        out = "{urn:com.example.switchyard:ExampleStringTrx:1.0}reverseSimpleResponse")
                public String reverseSimple(String value);
                

                 

                hth,

                keith

                • 5. Re: Service with SOAP binding (Default transformation)
                  fenoloco

                  Keith

                   

                  I tried adding the @OperationTypes but I still getting an error.

                   

                  In the log said.

                   

                  10:33:47,561 ERROR [stderr] (http-localhost-127.0.0.1-8080-1) [Fatal Error] :1:1: Content is not allowed in prolog.
                  

                   

                  I add a print in the method and the value is the payload of the SOAP request.So when I reverse It the message can´t be parsed to a SOAP message and I get this error on the SOAPUI client. -> Unable to parse SOAP Message

                  • 6. Re: Service with SOAP binding (Default transformation)
                    kcbabo

                    That's likely from the reply path, where you are returning a simple string and not well-formed XML.  This leaves you two options:

                     

                    1) Return XML from your service implementation in the form of a string.

                    2) Introduce a transformer (not JAXB) that transforms between String and "{urn:com.example.switchyard:ExampleStringTrx:1.0}reverseSimpleResponse".  A Java transformer would work well.

                     

                    An interesting enhancement here would be to have a fallback in our transformer handler which detects if the destination type is java.lang.String and automatically calls a conversion to String on the source type.  That would remove the need to specify any transformers or annotations when dealing with Strings.

                    • 7. Re: Service with SOAP binding (Default transformation)
                      fenoloco

                      Yes I think it can be a good enhancement. You can also remove the generation of the default transformations for the String params.

                      I will try both options thanks

                      • 8. Re: Service with SOAP binding (Default transformation)
                        nmoghadam

                        When are you guys planning to fix this issue?

                        • 9. Re: Service with SOAP binding (Default transformation)
                          kcbabo

                          It's not a bug, so there's nothing to fix.  Feel free to file an enhancement request if you would like to see the feature described in this thread.

                           

                          https://issues.jboss.org/browse/SWITCHYARD

                          • 10. Re: Service with SOAP binding (Default transformation)
                            fenoloco

                            Keith,

                            The automatic generated JAXB transformations from and to String are not valid, I think this look like a bug and not a enhancement.

                            • 11. Re: Service with SOAP binding (Default transformation)
                              kcbabo

                              Can you elaborate on the "automatic" generation of the JAXB transforms?  At what point were these automatically added to the application?  Did you select a JAXB transformer to transform to String in the "Create Required Transforms" wizard?  If so, then JAXB is not a valid transformer option for that type.

                              • 12. Re: Service with SOAP binding (Default transformation)
                                fenoloco

                                Yes, Im talking about the "Create Required Transforms" on the wizard. I know I selected the transformation for a String but the wizard shows it to me in spite of the type. If it show a warning or is not listed, nobody going to get confused as me.

                                 

                                 

                                Thanks.

                                • 13. Re: Service with SOAP binding (Default transformation)
                                  kcbabo

                                  The issue there is that we can't screen every single Java type to determine if it can be used in a JAXB transformer.  I think the best bet is to simply document that types used in JAXB transforms require a JAXB annotation or an ObjectFactory which maps the type using JAXBElement when an annotation is not present.  Tooling for the latter case is a bit chancy.  It's possible if a contextPath is provided and there's an ObjectFactory and we introspect the ObjectFactory to determine if there's a JAXBElement definition which corresponds to a type.  That's a lot of ands though. :-)

                                   

                                   

                                  FWIW, I agree that String is very common case and providing the enhancement we discussed earlier in this thread would be a good thing.  In the meantime, I think documenting the above constraint is the correct approach.  If you have additional ideas, please let us know.

                                  • 14. Re: Service with SOAP binding (Default transformation)
                                    fenoloco

                                    Ok I understand your point now . Im agree with the idea of improve the documentation about JAX-B Transform.

                                    A quickstarts example to managing this kind of types using all available options,  Java Transformation,ObjectFactory, etc can help a lot

                                     

                                     

                                    I really appreciate your time to respond my questions

                                    Have a good day