6 Replies Latest reply on Jul 21, 2013 10:56 AM by moraleslos

    Composer to convert returned POJO to String

    moraleslos

      Hi,

       

      I have a component and corresponding bean which has a method that returns a POJO.  However I have a composite service that has a REST binding which has a method that returns a String containing JSON data.  This REST method invokes the aforementioned bean that returns a POJO.  I want to have the bean implementation use POJOs internally while the composite services return only Strings (JSON data) for each method.  Now because of the mismatch return type, I was thinking that in the Composer's decompose(), I would essentially convert the POJO into JSON for each respective method, something like this:

       

       public RESTEasyBindingData decompose(Exchange exchange, RESTEasyBindingData target) throws Exception {
              Object content = exchange.getMessage().getContent();
              String opName = exchange.getContract().getProviderOperation().getName();
              target = super.decompose(exchange, target);
              if (target.getOperationName().equals("method1") && (content != null) && (content instanceof Pojo1) {
                     exchange.getMessage().setContent(((Pojo1)content).convertToJsonString());
             }          
      }
      

       

       

      Apparently the above doesn't work and get a class cast exception:  .Pojo1 cannot be cast to java.lang.String

       

       

      Any ideas on how to do this?  TIA.

        • 1. Re: Composer to convert returned POJO to String
          mageshbk

          The conversion from POJO to JSON should happen if the REST interface is annotated appropriately using the @Consumes and @Produces. Can you post your switchyard.xml or better still attach a simple project?

          • 2. Re: Composer to convert returned POJO to String
            moraleslos

            For the composite reference, it does return JSON and I have it annotated that way since the external service is REST-based. See below:

             

            @Path("/")

            public interface InvokeExternalReference {

             

             

                @POST

                @Path("/Authentication/Authenticate")

                @Produces({"application/xml","application/json"})

                      String authenticate(String jsonString);

            }

             

            Now in my component service implementation (the bean) that called the above reference, I successfully get the JSON string, parse it, unmarshal it into a POJO, and returns that POJO to be used by the bean elsewhere:

             

            @Inject

            @Reference

            private InvokeExternalService _ref;

             

             

            @Override

                      public POJO2 authenticate(POJO1 pojo) {

                      String json = pojo.convertIntoJsonString();

                      String result = _ref.authenticate(json);

             

                      POJO2 pojo2 = new POJO2();

                      unmarshal(pojo2, result);  // populates pojo2 with json data

                      return pojo2;

               }

             

            Now my composite service's REST binding interface that called the above authenticate(POJO1) method looks like this:

             

                @GET

                @Path("/authenticate/{username}/{password}")

                @Produces({"application/json"})

                      String authenticate(@PathParam("username") String username, @PathParam("password") String password);

             

             

            I have a CustomComposer that maps the username/password Strings into POJO1.  Now when I run the above, I get that class cast exception.  The POJO1 works fine in the bean when I need to use it, but the returned JSON string fails due to the exception.

            • 3. Re: Composer to convert returned POJO to String
              mageshbk

              Hi,

               

              You really need to attach the simplified project that has the switchyard.xml. I can understand something, but I am not able to see the complete picture to help you.

               

              thanks,

              Magesh

              • 4. Re: Composer to convert returned POJO to String
                moraleslos

                Sorry forgot the xml (see below).  If you still need an example project, I'll need to create a new one but will do:

                 

                <?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:camel="urn:switchyard-component-camel:config:1.0" xmlns:http="urn:switchyard-component-http:config:1.0" xmlns:resteasy="urn:switchyard-component-resteasy:config:1.0" xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:soap="urn:switchyard-component-soap:config:1.0" name="switchyard-example" targetNamespace="urn:com.example.switchyard:switchyard-example:1.0">

                  <sca:composite name="switchyard-example" targetNamespace="urn:com.example.switchyard:switchyard-example:1.0">

                    <sca:component name="InvokeExternalServiceBean">

                      <bean:implementation.bean class="com.example.switchyard.switchyard_example.InvokeExternalServiceBean"/>

                      <sca:service name="InvokeExternalService">

                        <sca:interface.java interface="com.example.switchyard.switchyard_example.InvokeExternalService"/>

                      </sca:service>

                      <sca:reference name="ExternalService">

                        <sca:interface.java interface="com.example.switchyard.switchyard_example.ExternalService"/>

                      </sca:reference>

                    </sca:component>

                    <sca:reference name="ExternalService" multiplicity="0..1" promote="InvokeExternalServiceBean/ExternalService">

                      <sca:interface.java interface="com.example.switchyard.switchyard_example.ExternalService"/>

                      <resteasy:binding.rest>

                        <resteasy:contextMapper/>

                        <resteasy:messageComposer/>

                        <resteasy:interfaces>com.example.switchyard.switchyard_example.InvokeExternalReference</resteasy:interfaces>

                        <resteasy:address>http://10.62.18.2/item_admin/services/CMS</resteasy:address>

                      </resteasy:binding.rest>

                    </sca:reference>

                    <sca:service name="InvokeExternalService" promote="InvokeExternalServiceBean/InvokeExternalService">

                      <sca:interface.java interface="com.example.switchyard.switchyard_example.InvokeExternalService"/>

                      <resteasy:binding.rest>

                        <resteasy:contextMapper/>

                        <resteasy:messageComposer class="com.example.switchyard.switchyard_example.CustomComposer"/>

                        <resteasy:interfaces>com.example.switchyard.switchyard_example.ClientRestReference</resteasy:interfaces>

                        <resteasy:contextPath>switchyard-example</resteasy:contextPath>

                      </resteasy:binding.rest>

                    </sca:service>

                  </sca:composite>

                </switchyard>

                • 5. Re: Composer to convert returned POJO to String
                  mageshbk

                  Your custom composer uses the name as "method1". Are you sure your method name is that and not "aunthenticate"? It is best if you attach a simple project so that we can help you further. There could be errors in copy-pasting code around.

                  • 6. Re: Composer to convert returned POJO to String
                    moraleslos

                    Yes, it is the authenticate method (and not method1). Let me see if I can you a project...