View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.routing.outbound;
8   
9   import org.mule.DefaultMuleEvent;
10  import org.mule.DefaultMuleMessage;
11  import org.mule.api.MuleEvent;
12  import org.mule.api.MuleMessage;
13  import org.mule.api.MuleSession;
14  import org.mule.api.routing.RoutingException;
15  import org.mule.config.i18n.CoreMessages;
16  
17  /**
18   * A router that breaks up the current message onto smaller parts and sends them to the
19   * same destination. The Destination service needs to have a MessageChunkingAggregator
20   * inbound router in order to rebuild the message at the other end.
21   */
22  public class MessageChunkingRouter extends FilteringOutboundRouter
23  {
24      private int messageSize = 0;
25      private int numberOfMessages = 1;
26  
27      public int getMessageSize()
28      {
29          return messageSize;
30      }
31  
32      public void setMessageSize(int messageSize)
33      {
34          this.messageSize = messageSize;
35      }
36  
37      public int getNumberOfMessages()
38      {
39          return numberOfMessages;
40      }
41  
42      public void setNumberOfMessages(int numberOfMessages)
43      {
44          this.numberOfMessages = numberOfMessages;
45      }
46  
47      @Override
48      public MuleEvent route(MuleEvent event) throws RoutingException
49      {
50          MuleMessage message = event.getMessage();
51          MuleSession session = event.getSession();
52          if (messageSize == 0 && numberOfMessages < 2)
53          {
54              return super.route(event);
55          }
56          else if (messageSize > 0)
57          {
58              byte[] data;
59              try
60              {
61                  data = message.getPayloadAsBytes();
62              }
63              catch (Exception e)
64              {
65                  throw new RoutingException(CoreMessages.failedToReadPayload(), event, getRoute(0, event), e);
66              }
67  
68              int parts = data.length / messageSize;
69              if ((parts * messageSize) < data.length)
70              {
71                  parts++;
72              }
73              int len = messageSize;
74              MuleMessage part;
75              int count = 0;
76              int pos = 0;
77              byte[] buffer;
78              try
79              {
80                  for (; count < parts; count++)
81                  {
82                      if ((pos + len) > data.length)
83                      {
84                          len = data.length - pos;
85                      }
86                      buffer = new byte[len];
87                      System.arraycopy(data, pos, buffer, 0, buffer.length);
88                      pos += len;
89                      part = new DefaultMuleMessage(buffer, message, muleContext);
90                      part.setCorrelationId(message.getUniqueId());
91                      part.setCorrelationGroupSize(parts);
92                      part.setCorrelationSequence(count);
93  
94                      if (logger.isInfoEnabled())
95                      {
96                          logger.info(String.format("sending part %d of %d (seq # %d)", count + 1, parts, count));
97                      }
98                      super.route(new DefaultMuleEvent(part, event.getEndpoint(), session));
99                      if (logger.isInfoEnabled())
100                     {
101                         logger.info("sent");
102                     }
103                 }
104             }
105             catch (RoutingException e)
106             {
107                 // we'll want to send the whole message to the Exception handler
108                 e = new RoutingException(e.getI18nMessage(), e.getEvent(), e.getRoute(), e.getCause());
109                 // e.addInfo("chunking", "true");
110                 // buffer = new byte[data.length - len];
111                 // System.arraycopy(data, len, buffer, 0, buffer.length);
112                 // e.addInfo("remaining data", buffer);
113                 throw e;
114             }
115         }
116         return event;
117     }
118 }