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;
8   
9   import org.mule.DefaultMuleEvent;
10  import org.mule.DefaultMuleMessage;
11  import org.mule.api.MuleContext;
12  import org.mule.api.MuleEvent;
13  import org.mule.api.MuleMessage;
14  import org.mule.routing.correlation.CollectionCorrelatorCallback;
15  import org.mule.routing.correlation.CorrelationSequenceComparator;
16  import org.mule.routing.correlation.EventCorrelatorCallback;
17  import org.mule.util.SerializationUtils;
18  
19  import java.util.Arrays;
20  import java.util.Comparator;
21  
22  import org.apache.commons.io.IOUtils;
23  import org.apache.commons.io.output.ByteArrayOutputStream;
24  import org.apache.commons.lang.SerializationException;
25  
26  public class MessageChunkAggregator extends AbstractAggregator
27  {
28      public static final int DEFAULT_BUFFER_SIZE = 4096;
29  
30      protected Comparator eventComparator;
31  
32      public MessageChunkAggregator()
33      {
34          super();
35          eventComparator = new CorrelationSequenceComparator();
36      }
37  
38      @Override
39      protected EventCorrelatorCallback getCorrelatorCallback(MuleContext muleContext)
40      {
41          return new CollectionCorrelatorCallback(muleContext)
42          {
43              /**
44               * This method is invoked if the shouldAggregate method is called and returns
45               * true. Once this method returns an aggregated message the event group is
46               * removed from the router
47               *
48               * @param events the event group for this request
49               * @return an aggregated message
50               * @throws org.mule.routing.AggregationException if the aggregation fails. in
51               *             this scenario the whole event group is removed and passed to the
52               *             exception handler for this componenet
53               */
54              @Override
55              public MuleEvent aggregateEvents(EventGroup events) throws AggregationException
56              {
57                  MuleEvent[] collectedEvents = events.toArray();
58                  MuleEvent firstEvent = collectedEvents[0];
59                  Arrays.sort(collectedEvents, eventComparator);
60                  ByteArrayOutputStream baos = new ByteArrayOutputStream(DEFAULT_BUFFER_SIZE);
61  
62                  try
63                  {
64                      for (MuleEvent event : collectedEvents)
65                      {
66                          baos.write(event.getMessageAsBytes());
67                      }
68  
69                      MuleMessage message;
70  
71                      // try to deserialize message, since ChunkingRouter might have serialized
72                      // the object...
73                      try
74                      {
75                          // must deserialize in correct classloader
76                          final Object deserialized = SerializationUtils.deserialize(baos.toByteArray(), muleContext);
77                          message = new DefaultMuleMessage(deserialized, firstEvent.getMessage(), muleContext);
78  
79                      }
80                      catch (SerializationException e)
81                      {
82                          message = new DefaultMuleMessage(baos.toByteArray(), firstEvent.getMessage(), muleContext);
83                      }
84  
85                      message.setCorrelationGroupSize(-1);
86                      message.setCorrelationSequence(-1);
87  
88                      return new DefaultMuleEvent(message, firstEvent);
89                  }
90                  catch (Exception e)
91                  {
92                      throw new AggregationException(events,MessageChunkAggregator.this, e);
93                  }
94                  finally
95                  {
96                      IOUtils.closeQuietly(baos);
97                  }
98              }
99          };
100     }
101 
102 }