Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Then we can replace "direct:start" with our cxf endpoint instead, so it's:

Code Block
java
java
        from(cxfEndpoint)...

The next issue you might now have guessed is that before (in part 4) we did a traditional codeing style to start a task and return a response to the caller in the method:

Code Block
java
java

  public OutputReportIncident reportIncident(InputReportIncident parameters) {
        // create the producer template to use for sending messages
        ProducerTemplate producer = context.createProducerTemplate();
        // send the body and the filename defined with the special header key
        Object mailBody = producer.sendBody("direct:start", parameters);
        System.out.println("Body:" + mailBody);

        // return an OK reply
        OutputReportIncident out = new OutputReportIncident();
        out.setCode("OK");
        return out;
    }

As you can see the method reportIncident is invoked with the webservice input parameters and we return the response to to the webservice from the method. But our situation now is that we don't have this method anymore. So how do we return a response to the webservice?

Houston we have a problem! Well of course not but the mindset have to be changed slightly to understand the routing concept, and how it works. So let's step back a bit. What we have here is a webservice that we expose. And our webservice is synchronous request/response based so the caller waits for a response. This is a InOut Message Exchange Pattern. Camel will default use InOut for webservices so we don't need to specify this explicitly. When we have a InOut pattern then Camel will return the response to the original caller when the routes ends. Looking at our route we have:

Code Block
java
java

        from(cxfEndpoint)
            .to("velocity:MailBody.vm")
            // then set the file name using the FilenameGenerator bean
            .setHeader(FileComponent.HEADER_FILE_NAME, BeanLanguage.bean(FilenameGenerator.class, "generateFilename"))
            // and store the file    
            .to("file://target/subfolder")

When the route ends after the file endpoint has been processed Camel will return the OUT message to the original caller (the caller of the webservice). However our route currently as it stands have not set any OUT message, so this is what we need to do, transforming (Message Translator EIP) the message into the response. We will therefore use a processor where we have 100% control in the Java code to set the response.

Code Block
java
java

        public void process(Exchange exchange) throws Exception {
            // the response we want to send
            OutputReportIncident OK = new OutputReportIncident();
            OK.setCode("0");

            // set the response on the OUT message as we use InOut
            exchange.getOut().setBody(OK);
       }

And with the route:

Code Block
java
java

        // first part from the webservice -> file backup
        from(cxfEndpoint)
            .to("velocity:MailBody.vm")
            // then set the file name using the FilenameGenerator bean
            .setHeader(FileComponent.HEADER_FILE_NAME, BeanLanguage.bean(FilenameGenerator.class, "generateFilename"))
            // and store the file    
            .to("file://target/subfolder")
            // return OK as response
            .process(new Processor() {
                public void process(Exchange exchange) throws Exception {
                    // the response we want to send
                    OutputReportIncident OK = new OutputReportIncident();
                    OK.setCode("0");

                    // set the response on the OUT message as we use InOut
                    exchange.getOut().setBody(OK);
                }
            });