13 Replies Latest reply on Apr 24, 2015 11:24 PM by jorgemoralespou_2

    Service operations on a Java interface must have exactly one parameter.

    moraleslos

      Hi,

       

      I'm currently getting this error when deploying my SY app onto EAP 6.1:  java.lang.RuntimeException: Service operations on a Java interface must have exactly one parameter.

       

      My program compiled just fine.  I have a composite reference that tries to invoke an external REST service passing in two parameters:  looks something like this:

       

      @Path("/")

      public interface InvokeExternalRestReference {

       

          @GET

          @Path("/Authenticate?credentials={\"LoginName\":\"{username}\",\"Password\":\"{password}\"}")

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

      }

       

       

      This is really the only place where I see this error would occur.  Is something wrong with the above code, or does SY can not invoke REST services with more than one parameter?  I'm using SY 1.0.0 (alpha1).

       

      TIA

        • 1. Re: Service operations on a Java interface must have exactly one parameter.
          mageshbk

          At SwitchYard level all service interface can have only one parameter. However when binding with REST you will have to map the multiple parameter into the SwitchYard message using a custom composer as shown here:

           

          https://github.com/jboss-switchyard/quickstarts/blob/master/rest-binding/src/main/java/org/switchyard/quickstarts/rest/binding/CustomComposer.java

           

          Please have a look at the rest-binding quickstart.

          1 of 1 people found this helpful
          • 2. Re: Service operations on a Java interface must have exactly one parameter.
            moraleslos

            I see.  Just curious as to why the interfaces are restricted to only one parameter.  Is it by design or due to some restrictions?  I couldn't find an explanation in the user guide.  TIA.

            • 3. Re: Service operations on a Java interface must have exactly one parameter.
              moraleslos

              Ok I created a custom composer as you mentioned but I'm still getting the same error.

               

               

               

              Below is my service interface (Credentials is just a POJO):

               

              public interface InvokeExternalRestService{

                        String authenticate(Credentials credentials);

              }

               

               

               

              Below is my external REST service reference:

              @Path("/")

              public interface InvokeExternalRestReference {

               

                  @PUT

                  @Path("/Authenticate?credentials={\"LoginName\":\"{username}\",\"Password\":\"{password}\"}")

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

              }

               

               

              Below is my custom composer:

               

              public class CustomComposer extends RESTEasyMessageComposer {

                  /**

                   * {@inheritDoc}

                   */

                  @Override

                  public Message compose(RESTEasyBindingData source, Exchange exchange) throws Exception {

                      final Message message = super.compose(source, exchange);

                     

                      if (source.getOperationName().equals("authenticate") && (source.getParameters().length == 2)) {

                          // Wrap the parameters

                          Credentials cred = new Credentials((String)source.getParameters()[0], (String)source.getParameters()[1]);

                          message.setContent(cred);

                      }

                      return message;

                  }

               

               

                  /**

                   * {@inheritDoc}

                   */

                  @Override

                  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("authenticate")

                          && (content != null) && (content instanceof Credentials)) {

                          // Unwrap the parameters

                          target.setParameters(new Object[]{((Credentials)content).getUsername(), ((Credentials)content).getPassword()});

                      }

               

               

                      return target;

                  }

               

               

              }

               

               

               

              And finally below is my SY config:

               

              <switchyard....

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

                  <sca:component name="InvokeExternalRestServiceBean">

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

                    <sca:service name="InvokeExternalRestService">

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

                    </sca:service>

                    <sca:reference name="InvokeExternalRestReference">

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

                    </sca:reference>

                  </sca:component>

                  <sca:reference name="InvokeExternalRestReference" multiplicity="0..1" promote="InvokeExternalRestServiceBean/InvokeExternalRestReference">

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

                    <resteasy:binding.rest>

                      <resteasy:contextMapper/>

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

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

                      <resteasy:address>http://10.21.23.9/er_em/services/REST/</resteasy:address>

                    </resteasy:binding.rest>

                  </sca:reference>

                </sca:composite>

              </switchyard>

              • 4. Re: Service operations on a Java interface must have exactly one parameter.
                moraleslos

                never mind. for some reason my reference on the bean had an incorrect configuration-- was pointing to my reference interface rather than my service interface.  Took forever to see this!  Anyway got it to run.  thanks for the help.

                • 5. Re: Service operations on a Java interface must have exactly one parameter.
                  rohan0287

                  Hi Los,

                   

                  Can u paste the exact switchyard.xml config after correction. I ran in to the same problem.

                  • 6. Re: Service operations on a Java interface must have exactly one parameter.
                    rohan0287

                    1.png

                    is this part correct? as mentioned by Los. because as per rule SY will not allow more than one parameter.

                    • 7. Re: Service operations on a Java interface must have exactly one parameter.
                      rcernich

                      You need a custom message composer that converts the parameters into a single message that gets passed into the system.  This could be a simple type with a field corresponding to each parameter.  Likewise, some of the parameters could be passed as header properties.

                      • 8. Re: Service operations on a Java interface must have exactly one parameter.
                        rohan0287

                        @Rob Cernich

                        I just used the Los's Example and created the same as steps mentioned by him. I too created a custom message composer.

                        But still i am unable to get those parameters in to the RestEasyBindingData object, though i got the operation name but not the parameters.

                        Please let me is there any thing wrong with Los's example. TIA

                        • 9. Re: Service operations on a Java interface must have exactly one parameter.
                          rcernich

                          It looks correct and he's stated it is working.

                           

                          Keep in mind, compose() is going to be invoked when receiving a message from the gateway/endpoint and decompose() is going to be invoked when sending a message to the gateway/endpoint.

                           

                          You should be able to place a breakpoint in your custom composer to make sure the data is being set correctly.

                           

                          Sorry I couldn't be of more help.

                           

                          Rob

                          • 10. Re: Service operations on a Java interface must have exactly one parameter.
                            rory8000

                            Hi

                             

                            Anybody can help me with this:

                             

                            I want to develop a rest proxy in switchyard with an url on this form :http://localhost:8080/switchyardpath/process/{id}/test

                             

                            where I want a POST to get work, sending a json.

                             

                            This is my interface for a component service

                             

                            @POST
                            @Path("/{id}/test")

                            @Consumes("application/json")

                            @Produces("application/json" + ";charset=utf-8")

                            @PermitAll
                            public String createTest(@PathParam("id") String processId, Object anything);

                             

                            and the real working rest service:

                             

                            @POST
                            @Path("/{id}/people")

                            @Consumes("application/json")

                            @Produces("application/json" + ";charset=utf-8")

                            @PermitAll
                            public boolean createPeople(@PathParam("id") UUID processId, List<PersonDTO> people) {

                             

                            Since switchyard doesn't work with more than 1 parameter, i dont know how to get this thing working.

                             

                            Thanks for your help

                            • 11. Re: Service operations on a Java interface must have exactly one parameter.
                              jorgemoralespou_2

                              Hi Rory,

                              You should open a new question instead of using already answered ones. I've seen you've done it in 2 of the threads. Don't be lazy. If you want to reference these 2 threads you can do it, otherwise, people may skip your real problem.

                              If you do it, we'll try to help.

                              • 12. Re: Service operations on a Java interface must have exactly one parameter.
                                rory8000

                                Thanks for the advice.  I appreciate it

                                 

                                But unfortunately it seems that you're more worried about the use of the forum instead of helping me with a such simple question.

                                • 13. Re: Service operations on a Java interface must have exactly one parameter.
                                  jorgemoralespou_2

                                  Unfortunately, if you have time to answer complaining to me, but not to work in a community as expected, then the community might not help you back :-(