Versions Compared

Key

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

Writing the bean class

Wiki Markup
{scrollbar}

We now have to

Excerpt

write the bean class

to handle incoming message exchanges.

...

Next thing to do is creation the bean class. For this select the src/main/java folder in your project. Now delete everything inside this folder.

Now select File > New > Class. In the dialog enter the following:

*

Code Block

Package:    org.apache.servicemix.jbi

...


Name:

...

       HandlerBean
Interfaces: org.apache.servicemix.MessageExchangeListener

*

Then hit Finish to create the class. Eclipse will also implements implement the interface's only method for you:
*

Code Block
java
java
   public void onMessageExchange(MessageExchange arg0) throws MessagingException
   {...}

*
This method is responsible for handling incoming messages.

...

We extract the first attachment of the message by name. The name is equal to the filename. After this we have the original filename in the
fileName variable and the file content in the content variable (as DataHandler object).
For the sake of simplicity we just write the contents into a temporary file and use this file for sending it back to the http-consumer-su.

Code Block
java
java
   fileName = it.next().toString();
  content = in.getAttachment(fileName);
  
  // create a temporary file
  File f = File.createTempFile("tmp_", fileName);
  // open an output stream to this file
  FileOutputStream fos = new FileOutputStream(f);
  content.// use the DataHandler to write the contents into the stream
  content.writeTo(fos);
  // flush and close the stream (flush should be done automatically on closing the stream and so it's maybe not needed here)
  fos.flush();
  fos.close();
                            
  // for the sake of simplicity only return the file received as attachment
  NormalizedMessage out = exchange.createMessage();
        
  // set the content to dummy xml tag
  out.setContent(new StringSource("<payload/>"));
                            
  FileDataSource fds = new FileDataSource(f);
  InputStream is = fds.getInputStream();
                            
  // create a handler for the attachment (the attachment data from the file is obtained by using a StreamDataSource which takes 
  // 2 parameters - the input stream (of the filedatasource) and the content type (for example application/octet-stream)
  DataHandler dh = new DataHandler(new StreamDataSource(is, fds.getContentType())); // mime type is obtained automatically here
                            
  // and add the itdatahandler to the message's attachments (binary data can't be send in the content - so use attachments)
  out.addAttachment(fileName, dh);

  // prepare and send the exchange
  exchange.setMessage(out, "out");
  channel.send(exchange);
  // finally clean up the temporary file
  f.deleteOnExit();

This is of course a stupid example, so just imagine you now convert this file into another format and send the result back.
You can do such a logic if you want. For this you can refer for example to OpenOffice running in headless mode in combination with the JODConverter of "Arts of Solving". This will enable you to convert for example a .odt document into a .pdf document. But this is really out of scope now.

The finished class

Code Block
java
java
titleHandlerBean.java
borderStylesolid
package org.apache.servicemix.jbi;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.Set;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.annotation.Resource;
import javax.jbi.messaging.DeliveryChannel;
import javax.jbi.messaging.ExchangeStatus;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.MessagingException;
import javax.jbi.messaging.NormalizedMessage;
import javax.jbi.messaging.MessageExchange.Role;
import org.apache.log4j.Logger;
import org.apache.servicemix.MessageExchangeListener;
import org.apache.servicemix.jbi.jaxp.StringSource;
import org.apache.servicemix.jbi.util.StreamDataSource;

public class HandlerBean implements MessageExchangeListener
{
    private static final Logger logger = Logger.getLogger(HandlerBean.class);

    @Resource
    private DeliveryChannel channel;

    /*
     * (non-Javadoc)
     * @see org.apache.servicemix.MessageExchangeListener#onMessageExchange(javax.jbi.messaging.MessageExchange)
     */
    public void onMessageExchange(MessageExchange exchange) throws MessagingException
        {
        if (exchange == null)
            {
            return;
            }
        
        // The component acts as a consumer, this means this exchange is received because
        // we sent it to another component. As it is active, this is either an out or a fault
        // If this component does not create / send exchanges, you may just throw an
        // UnsupportedOperationException
        if (exchange.getRole() == Role.CONSUMER)
            {
            onConsumerExchange(exchange);
            }
        
        // The component acts as a provider, this means that another component has requested our
        // service
        // As this exchange is active, this is either an in or a fault (out are send by this
        // component)
        else if (exchange.getRole() == MessageExchange.Role.PROVIDER)
            {
            onProviderExchange(exchange);
            }
        
        // Unknown role
        else
            {
            throw new MessagingException("HandlerBean.onMessageExchange(): Unknown role: " + exchange.getRole());
            }
        }

    /**
     * handles the incoming consumer messages
     * 
     * @param exchange
     * @throws MessagingException
     */
    private void onConsumerExchange(MessageExchange exchange) throws MessagingException 
        {
        // Out message
        if (exchange.getMessage("out") != null)
            {
            exchange.setStatus(ExchangeStatus.DONE);
            channel.send(exchange);
            }
    
        // Fault message
        else if (exchange.getFault() != null)
            {
            exchange.setStatus(ExchangeStatus.DONE);
            channel.send(exchange);
            }
    
        // This is not compliant with the default MEPs
        else
            {
            throw new MessagingException("HandlerBean.onConsumerExchange(): Consumer exchange is ACTIVE, but no out or fault is provided");
            }
        }
    
    /**
     * handles the incoming provider messages
     * 
     * @param exchange
     * @throws MessagingException
     */
    private void onProviderExchange(MessageExchange exchange) throws MessagingException 
        {
        // Exchange is finished
        if (exchange.getStatus() == ExchangeStatus.DONE) 
            {
            return;
            }
        // Exchange has been aborted with an exception
        else if (exchange.getStatus() == ExchangeStatus.ERROR) 
            {
            return;
            }
        // Fault message
        else if (exchange.getFault() != null) 
            {
            exchange.setStatus(ExchangeStatus.DONE);
            channel.send(exchange);
            } 
        else 
            {
            NormalizedMessage in = exchange.getMessage("in");
            
            if (in == null)
                {
                // no in message - strange
                throw new MessagingException("HandlerBean.onProviderExchange(): Exchange has no IN message");
                }
            else
                {
                String fileName = null;
                DataHandler content = null;
                Set attNames = in.getAttachmentNames();
                Iterator it = attNames.iterator();
                
                if (attNames.size()==1)
                    {
                    if (it.hasNext())
                        {
                        try
                            {
                            fileName = it.next().toString();
                            content = in.getAttachment(fileName);
   
                            File f = File.createTempFile("tmp_", fileName);
                            FileOutputStream fos = new FileOutputStream(f);
                            content.writeTo(fos);
                            fos.flush();
                            fos.close();
                            
                            // for the sake of simplicity only return the file received as attachment
                            NormalizedMessage out = exchange.createMessage();
        
                            // set the content to dummy xml tag
                            out.setContent(new StringSource("<payload/>"));
                            
                            FileDataSource fds = new FileDataSource(f);
                            InputStream is = fds.getInputStream();
                            
                            // create a handler for the attachment
                            DataHandler dh = new DataHandler(new StreamDataSource(is, fds.getContentType()));
                            
                            // and add it to the message
                            out.addAttachment(fileName, dh);
                            
                            // prepare and send the exchange
                            exchange.setMessage(out, "out");
                            channel.send(exchange);
                            
                            f.deleteOnExit();
                            }
                        catch (IOException ex)
                            {
                            throw new MessagingException("HandlerBean.onProviderExchange(): " + ex.getLocalizedMessage());
                            }
                        }
                    }
                else
                    {
                    // more or less than one attachment
                    throw new MessagingException("HandlerBean.onProviderExchange(): Wrong message format (invalid attachment count)");
                    }
                }
            }
        }
}

...