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.RequestContext;
10  import org.mule.api.MuleEvent;
11  import org.mule.api.MuleException;
12  import org.mule.api.processor.MessageProcessor;
13  import org.mule.api.routing.filter.Filter;
14  import org.mule.processor.AbstractFilteringMessageProcessor;
15  import org.mule.processor.AbstractMessageProcessorOwner;
16  import org.mule.util.ObjectUtils;
17  
18  import java.util.Collections;
19  import java.util.List;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  
24  /**
25   * The <code>WireTap</code> MessageProcessor allows inspection of messages in a flow.
26   * <p>
27   * The incoming message is is sent to both the primary and wiretap outputs. The flow
28   * of the primary output will be unmodified and a copy of the message used for the
29   * wiretap output.
30   * <p>
31   * An optional filter can be used to filter which message are sent to the wiretap
32   * output, this filter does not affect the flow to the primary output. If there is an
33   * error sending to the wiretap output no exception will be thrown but rather an
34   * error logged.
35   * <p>
36   * <b>EIP Reference:</b> <a href="http://www.eaipatterns.com/WireTap.html">http://www.eaipatterns.com/WireTap.html<a/>
37   */
38  public class WireTap extends AbstractMessageProcessorOwner implements MessageProcessor
39  {
40      protected final transient Log logger = LogFactory.getLog(getClass());
41      protected volatile MessageProcessor tap;
42      protected volatile Filter filter;
43  
44      protected MessageProcessor filteredTap = new WireTapFilter();
45  
46      public MuleEvent process(MuleEvent event) throws MuleException
47      {
48          if (tap == null)
49          {
50              return event;
51          }
52  
53          try
54          {
55              // Do we need this?
56              RequestContext.setEvent(null);
57              filteredTap.process(RequestContext.setEvent(event));
58          }
59          catch (MuleException e)
60          {
61              logger.error("Exception sending to wiretap output " + tap, e);
62          }
63  
64          return event;
65      }
66  
67      public MessageProcessor getTap()
68      {
69          return tap;
70      }
71  
72      public void setTap(MessageProcessor tap)
73      {
74          this.tap = tap;
75      }
76  
77      @Deprecated
78      public void setMessageProcessor(MessageProcessor tap)
79      {
80          setTap(tap);
81      }
82      
83      public Filter getFilter()
84      {
85          return filter;
86      }
87  
88      public void setFilter(Filter filter)
89      {
90          this.filter = filter;
91      }
92  
93      private class WireTapFilter extends AbstractFilteringMessageProcessor
94      {
95          @Override
96          protected boolean accept(MuleEvent event)
97          {
98              if (filter == null)
99              {
100                 return true;
101             }
102             else
103             {
104                 return filter.accept(event.getMessage());
105             }
106         }
107 
108         @Override
109         protected MuleEvent processNext(MuleEvent event) throws MuleException
110         {
111             if (tap != null)
112             {
113                 tap.process(event);
114             }
115             return null;
116         }
117 
118         @Override
119         public String toString()
120         {
121             return ObjectUtils.toString(this);
122         }
123     }
124 
125     @Override
126     public String toString()
127     {
128         return ObjectUtils.toString(this);
129     }
130 
131         @Override
132     protected List<MessageProcessor> getOwnedMessageProcessors()
133     {
134         return Collections.singletonList(tap);
135     }
136 
137 }