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.transport.sftp;
8   
9   import org.mule.api.MuleMessage;
10  import org.mule.api.construct.FlowConstruct;
11  import org.mule.api.endpoint.InboundEndpoint;
12  import org.mule.api.lifecycle.CreateException;
13  import org.mule.transport.AbstractPollingMessageReceiver;
14  import org.mule.transport.sftp.notification.SftpNotifier;
15  
16  import java.io.InputStream;
17  import java.util.Arrays;
18  
19  /**
20   * <code>SftpMessageReceiver</code> polls and receives files from an sftp service
21   * using jsch. This receiver produces an InputStream payload, which can be
22   * materialized in a MessageDispatcher or Component.
23   */
24  public class SftpMessageReceiver extends AbstractPollingMessageReceiver
25  {
26  
27      private SftpReceiverRequesterUtil sftpRRUtil = null;
28  
29      public SftpMessageReceiver(SftpConnector connector,
30                                 FlowConstruct flow,
31                                 InboundEndpoint endpoint,
32                                 long frequency) throws CreateException
33      {
34          super(connector, flow, endpoint);
35  
36          this.setFrequency(frequency);
37  
38          sftpRRUtil = new SftpReceiverRequesterUtil(endpoint);
39      }
40  
41      public SftpMessageReceiver(SftpConnector connector, FlowConstruct flow, InboundEndpoint endpoint) throws CreateException
42      {
43          this(connector, flow, endpoint, DEFAULT_POLL_FREQUENCY);
44      }
45  
46      public void poll() throws Exception
47      {
48          if (logger.isDebugEnabled())
49          {
50              logger.debug("Pooling. Called at endpoint " + endpoint.getEndpointURI());
51          }
52          try
53          {
54              String[] files = sftpRRUtil.getAvailableFiles(false);
55  
56              if (files.length == 0)
57              {
58                  if (logger.isDebugEnabled())
59                  {
60                      logger.debug("Pooling. No matching files found at endpoint " + endpoint.getEndpointURI());
61                  }
62              }
63              else
64              {
65                  if (logger.isDebugEnabled())
66                  {
67                      logger.debug("Pooling. " + files.length + " files found at " + endpoint.getEndpointURI()
68                                   + ":" + Arrays.toString(files));
69                  }
70                  for (String file : files)
71                  {
72                      if (getLifecycleState().isStopping())
73                      {
74                          break;
75                      }
76                      routeFile(file);
77                  }
78                  if (logger.isDebugEnabled())
79                  {
80                      logger.debug("Pooling. Routed all " + files.length + " files found at "
81                                   + endpoint.getEndpointURI());
82                  }
83              }
84          }
85          catch (Exception e)
86          {
87              logger.error("Error in poll", e);
88              throw e;
89          }
90      }
91  
92      protected void routeFile(String path) throws Exception
93      {
94          // A bit tricky initialization of the notifier in this case since we don't
95          // have access to the message yet...
96          SftpNotifier notifier = new SftpNotifier((SftpConnector) connector, createNullMuleMessage(),
97              endpoint, flowConstruct.getName());
98  
99          InputStream inputStream = sftpRRUtil.retrieveFile(path, notifier);
100 
101         if (logger.isDebugEnabled())
102         {
103             logger.debug("Routing file: " + path);
104         }
105 
106         MuleMessage message = createMuleMessage(inputStream);
107 
108         message.setOutboundProperty(SftpConnector.PROPERTY_FILENAME, path);
109         message.setOutboundProperty(SftpConnector.PROPERTY_ORIGINAL_FILENAME, path);
110 
111         // Now we have access to the message, update the notifier with the message
112         notifier.setMessage(message);
113         routeMessage(message);
114 
115         if (logger.isDebugEnabled())
116         {
117             logger.debug("Routed file: " + path);
118         }
119     }
120 
121     /**
122      * SFTP-35
123      * @param message
124      * @return
125      */
126     @Override    
127     protected MuleMessage handleUnacceptedFilter(MuleMessage message) {
128         logger.debug("the filter said no, now trying to close the payload stream");
129         try {
130             final SftpInputStream payload = (SftpInputStream) message.getPayload();
131             payload.close();
132         }
133         catch (Exception e) {
134             logger.debug("unable to close payload stream", e);
135         }
136         return super.handleUnacceptedFilter(message);
137     }
138     
139     public void doConnect() throws Exception
140     {
141         // no op
142     }
143 
144     public void doDisconnect() throws Exception
145     {
146         // no op
147     }
148 
149     protected void doDispose()
150     {
151         // no op
152     }
153 }