View Javadoc
1   /**
2    * This file is part of Waarp Project.
3    * 
4    * Copyright 2009, Frederic Bregier, and individual contributors by the @author tags. See the
5    * COPYRIGHT.txt in the distribution for a full listing of individual contributors.
6    * 
7    * All Waarp Project is free software: you can redistribute it and/or modify it under the terms of
8    * the GNU General Public License as published by the Free Software Foundation, either version 3 of
9    * the License, or (at your option) any later version.
10   * 
11   * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
12   * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13   * Public License for more details.
14   * 
15   * You should have received a copy of the GNU General Public License along with Waarp . If not, see
16   * <http://www.gnu.org/licenses/>.
17   */
18  package org.waarp.gateway.ftp.snmp;
19  
20  import io.netty.handler.traffic.TrafficCounter;
21  import org.waarp.common.command.ReplyCode;
22  import org.waarp.common.database.DbPreparedStatement;
23  import org.waarp.common.database.DbSession;
24  import org.waarp.common.database.data.AbstractDbData.UpdatedInfo;
25  import org.waarp.common.database.exception.WaarpDatabaseException;
26  import org.waarp.common.database.exception.WaarpDatabaseNoConnectionException;
27  import org.waarp.common.database.exception.WaarpDatabaseSqlException;
28  import org.waarp.common.logging.WaarpLogger;
29  import org.waarp.common.logging.WaarpLoggerFactory;
30  import org.waarp.gateway.ftp.config.FileBasedConfiguration;
31  import org.waarp.gateway.ftp.database.DbConstant;
32  import org.waarp.gateway.ftp.database.data.DbTransferLog;
33  import org.waarp.gateway.ftp.snmp.FtpPrivateMib.MibLevel;
34  import org.waarp.gateway.ftp.snmp.FtpPrivateMib.WaarpDetailedValuesIndex;
35  import org.waarp.gateway.ftp.snmp.FtpPrivateMib.WaarpErrorValuesIndex;
36  import org.waarp.gateway.ftp.snmp.FtpPrivateMib.WaarpGlobalValuesIndex;
37  import org.waarp.snmp.WaarpSnmpAgent;
38  import org.waarp.snmp.interf.WaarpInterfaceMonitor;
39  
40  /**
41   * SNMP Monitoring class for FTP Exec
42   * 
43   * @author Frederic Bregier
44   * 
45   */
46  public class FtpMonitoring implements WaarpInterfaceMonitor {
47      /**
48       * Internal Logger
49       */
50      private static WaarpLogger logger = WaarpLoggerFactory
51              .getLogger(FtpMonitoring.class);
52  
53      public WaarpSnmpAgent agent;
54  
55      // global informations
56      public long nbNetworkConnection = 0;
57      public long secondsRunning = 0;
58      public long nbThread = 0;
59      public long bandwidthIn = 0;
60      public long bandwidthOut = 0;
61  
62      // Internal data
63      private DbSession dbSession = null;
64      private TrafficCounter trafficCounter =
65              FileBasedConfiguration.fileBasedConfiguration.
66                      getFtpInternalConfiguration().getGlobalTrafficShapingHandler()
67                      .trafficCounter();
68  
69      public long nbCountInfoUnknown = 0;
70      public long nbCountInfoNotUpdated = 0;
71      public long nbCountInfoInterrupted = 0;
72      public long nbCountInfoToSubmit = 0;
73      public long nbCountInfoError = 0;
74      public long nbCountInfoRunning = 0;
75      public long nbCountInfoDone = 0;
76  
77      public long nbInActiveTransfer = 0;
78      public long nbOutActiveTransfer = 0;
79      public long lastInActiveTransfer = System.currentTimeMillis();
80      public long lastOutActiveTransfer = System.currentTimeMillis();
81      public long nbInTotalTransfer = 0;
82      public long nbOutTotalTransfer = 0;
83      public long nbInErrorTransfer = 0;
84      public long nbOutErrorTransfer = 0;
85  
86      public long nbCountAllTransfer = 0;
87  
88      // Info for other reasons than transfers
89      private long[] reply_info_notransfers = new long[WaarpDetailedValuesIndex.reply_350.ordinal() + 1];
90      // Error for other reasons than transfers
91      private long[] reply_error_notransfers = new long[WaarpErrorValuesIndex.reply_553.ordinal() + 1];
92      {
93          for (int i = 0; i <= WaarpDetailedValuesIndex.reply_350.ordinal(); i++) {
94              reply_info_notransfers[i] = 0;
95          }
96          for (int i = 0; i <= WaarpErrorValuesIndex.reply_553.ordinal(); i++) {
97              reply_error_notransfers[i] = 0;
98          }
99      }
100     // Overall status including past, future and current transfers
101     private DbPreparedStatement countInfo = null;
102 
103     // Current situation of all transfers, running or not
104     private DbPreparedStatement countInActiveTransfer = null;
105     private DbPreparedStatement countOutActiveTransfer = null;
106     private DbPreparedStatement countInTotalTransfer = null;
107     private DbPreparedStatement countOutTotalTransfer = null;
108     private DbPreparedStatement countInErrorTransfer = null;
109     private DbPreparedStatement countOutErrorTransfer = null;
110     private DbPreparedStatement countAllTransfer = null;
111     // Error Status on all transfers
112     private DbPreparedStatement countStatus = null;
113 
114     /**
115      * 
116      * @param session
117      */
118     public FtpMonitoring(DbSession session) {
119         if (session != null) {
120             dbSession = session;
121         } else {
122             dbSession = DbConstant.gatewayAdmin.getSession();
123         }
124         this.initialize();
125     }
126 
127     @Override
128     public void setAgent(WaarpSnmpAgent agent) {
129         this.agent = agent;
130         this.lastInActiveTransfer = this.agent.getUptimeSystemTime();
131         this.lastOutActiveTransfer = this.agent.getUptimeSystemTime();
132     }
133 
134     @Override
135     public void initialize() {
136         logger.debug("Initialize monitoring");
137         try {
138             // Overall status including past, future and current transfers
139             countInfo = DbTransferLog.getCountInfoPrepareStatement(dbSession);
140             // Count of Active/All In/Out transfers
141             countInActiveTransfer = DbTransferLog.getCountInOutRunningPrepareStatement(dbSession,
142                     true, true);
143             countOutActiveTransfer = DbTransferLog.getCountInOutRunningPrepareStatement(dbSession,
144                     false, true);
145             countInTotalTransfer = DbTransferLog.getCountInOutRunningPrepareStatement(dbSession,
146                     true, false);
147             countOutTotalTransfer = DbTransferLog.getCountInOutRunningPrepareStatement(dbSession,
148                     false, false);
149 
150             countInErrorTransfer = DbTransferLog
151                     .getCountInOutErrorPrepareStatement(dbSession, true);
152             countOutErrorTransfer = DbTransferLog.getCountInOutErrorPrepareStatement(dbSession,
153                     false);
154             // All
155             countAllTransfer = DbTransferLog.getCountAllPrepareStatement(dbSession);
156             // Error Status on all transfers
157             countStatus = DbTransferLog.getCountStatusPrepareStatement(dbSession);
158         } catch (WaarpDatabaseException e) {
159         }
160     }
161 
162     @Override
163     public void releaseResources() {
164         try {
165             logger.debug("Release monitoring");
166             // Overall status including past, future and current transfers
167             countInfo.realClose();
168 
169             countInActiveTransfer.realClose();
170             countOutActiveTransfer.realClose();
171             countInTotalTransfer.realClose();
172             countOutTotalTransfer.realClose();
173             countInErrorTransfer.realClose();
174             countOutErrorTransfer.realClose();
175 
176             countAllTransfer.realClose();
177             // Error Status on all transfers
178             countStatus.realClose();
179         } catch (NullPointerException e) {
180         }
181     }
182 
183     private static final int ref421 =
184             ReplyCode.REPLY_421_SERVICE_NOT_AVAILABLE_CLOSING_CONTROL_CONNECTION.ordinal();
185 
186     /**
187      * Update the reply code counter for other operations than a transfer
188      * 
189      * @param code
190      */
191     public void updateCodeNoTransfer(ReplyCode code) {
192         int i = code.ordinal();
193         if (i >= ref421) {
194             i -= ref421;
195             reply_error_notransfers[i]++;
196         } else {
197             reply_info_notransfers[i]++;
198         }
199     }
200 
201     /**
202      * Update the last InBound connection time
203      */
204     public void updateLastInBound() {
205         lastInActiveTransfer = System.currentTimeMillis();
206     }
207 
208     /**
209      * Update the last OutBound connection time
210      */
211     public void updateLastOutBand() {
212         lastOutActiveTransfer = System.currentTimeMillis();
213     }
214 
215     /**
216      * Update the value for one particular MIB entry
217      * 
218      * @param type
219      * @param entry
220      */
221     public void run(int type, int entry) {
222         long nbMs = FileBasedConfiguration.fileBasedConfiguration.agentSnmp.getUptime() + 100;
223         MibLevel level = MibLevel.values()[type];
224         switch (level) {
225             case globalInfo:// Global
226                 if (((FtpPrivateMib) this.agent.getMib()).rowGlobal != null)
227                     run(nbMs, WaarpGlobalValuesIndex.values()[entry]);
228                 return;
229             case detailedInfo:// Detailed
230                 if (((FtpPrivateMib) this.agent.getMib()).rowDetailed != null)
231                     run(nbMs, WaarpDetailedValuesIndex.values()[entry]);
232                 return;
233             case errorInfo:// Error
234                 if (((FtpPrivateMib) this.agent.getMib()).rowError != null)
235                     run(nbMs, WaarpErrorValuesIndex.values()[entry]);
236                 return;
237             case staticInfo:
238                 break;
239             case trapInfo:
240                 break;
241             default:
242                 break;
243         }
244     }
245 
246     /**
247      * Update a value in Global MIB part
248      * 
249      * @param rank
250      * @param value
251      */
252     protected void updateGlobalValue(int rank, long value) {
253         ((FtpPrivateMib) this.agent.getMib()).rowGlobal.setValue(rank, value);
254     }
255 
256     /**
257      * Update a value in Detailed MIB part
258      * 
259      * @param rank
260      * @param value
261      */
262     protected void updateDetailedValue(int rank, long value) {
263         ((FtpPrivateMib) this.agent.getMib()).rowDetailed.setValue(rank, value);
264     }
265 
266     /**
267      * Update a value in Error MIB part
268      * 
269      * @param rank
270      * @param value
271      */
272     protected void updateErrorValue(int rank, long value) {
273         ((FtpPrivateMib) this.agent.getMib()).rowError.setValue(rank, value);
274     }
275 
276     /**
277      * Update a value in Global MIB part
278      * 
279      * @param nbMs
280      * @param entry
281      */
282     protected void run(long nbMs, WaarpGlobalValuesIndex entry) {
283         synchronized (trafficCounter) {
284             long val = 0;
285             long limitDate = System.currentTimeMillis() - nbMs;
286             // Global
287             try {
288                 switch (entry) {
289                     case applUptime:
290                         return;
291                     case applOperStatus:
292                         return;
293                     case applLastChange:
294                         return;
295                     case applInboundAssociations:
296                         DbTransferLog.finishSelectOrCountPrepareStatement(countInActiveTransfer,
297                                 limitDate);
298                         nbInActiveTransfer = DbTransferLog
299                                 .getResultCountPrepareStatement(countInActiveTransfer);
300                         updateGlobalValue(entry.ordinal(), nbInActiveTransfer);
301                         return;
302                     case applOutboundAssociations:
303                         DbTransferLog.finishSelectOrCountPrepareStatement(countOutActiveTransfer,
304                                 limitDate);
305                         nbOutActiveTransfer = DbTransferLog
306                                 .getResultCountPrepareStatement(countOutActiveTransfer);
307                         updateGlobalValue(entry.ordinal(), nbOutActiveTransfer);
308                         return;
309                     case applAccumInboundAssociations:
310                         DbTransferLog.finishSelectOrCountPrepareStatement(countInTotalTransfer,
311                                 limitDate);
312                         nbInTotalTransfer = DbTransferLog
313                                 .getResultCountPrepareStatement(countInTotalTransfer);
314                         updateGlobalValue(entry.ordinal(), nbInTotalTransfer);
315                         return;
316                     case applAccumOutboundAssociations:
317                         DbTransferLog.finishSelectOrCountPrepareStatement(countOutTotalTransfer,
318                                 limitDate);
319                         nbOutTotalTransfer = DbTransferLog
320                                 .getResultCountPrepareStatement(countOutTotalTransfer);
321                         updateGlobalValue(entry.ordinal(), nbOutTotalTransfer);
322                         return;
323                     case applLastInboundActivity:
324                         val = (lastInActiveTransfer -
325                                 this.agent.getUptimeSystemTime()) / 10;
326                         if (val < 0)
327                             val = 0;
328                         updateGlobalValue(entry.ordinal(), val);
329                         return;
330                     case applLastOutboundActivity:
331                         val = (lastOutActiveTransfer -
332                                 this.agent.getUptimeSystemTime()) / 10;
333                         if (val < 0)
334                             val = 0;
335                         updateGlobalValue(entry.ordinal(), val);
336                         return;
337                     case applRejectedInboundAssociations:
338                         DbTransferLog.finishSelectOrCountPrepareStatement(countInErrorTransfer,
339                                 limitDate);
340                         nbInErrorTransfer = DbTransferLog
341                                 .getResultCountPrepareStatement(countInErrorTransfer);
342                         updateGlobalValue(entry.ordinal(), nbInErrorTransfer);
343                         return;
344                     case applFailedOutboundAssociations:
345                         DbTransferLog.finishSelectOrCountPrepareStatement(countOutErrorTransfer,
346                                 limitDate);
347                         nbOutErrorTransfer = DbTransferLog
348                                 .getResultCountPrepareStatement(countOutErrorTransfer);
349                         updateGlobalValue(entry.ordinal(), nbOutErrorTransfer);
350                         return;
351                     case applInboundBandwidthKBS:
352                         val = trafficCounter.lastReadThroughput() >> 10;// B/s -> KB/s
353                         updateGlobalValue(entry.ordinal(), val);
354                         return;
355                     case applOutboundBandwidthKBS:
356                         val = trafficCounter.lastWriteThroughput() >> 10;
357                         updateGlobalValue(entry.ordinal(), val);
358                         return;
359                     case nbInfoUnknown:
360                         nbCountInfoUnknown = DbTransferLog.getResultCountPrepareStatement(
361                                 countInfo,
362                                 UpdatedInfo.UNKNOWN, limitDate);
363                         updateGlobalValue(entry.ordinal(), nbCountInfoUnknown);
364                         return;
365                     case nbInfoNotUpdated:
366                         nbCountInfoNotUpdated = DbTransferLog.getResultCountPrepareStatement(
367                                 countInfo,
368                                 UpdatedInfo.NOTUPDATED, limitDate);
369                         updateGlobalValue(entry.ordinal(), nbCountInfoNotUpdated);
370                         return;
371                     case nbInfoInterrupted:
372                         nbCountInfoInterrupted = DbTransferLog.getResultCountPrepareStatement(
373                                 countInfo,
374                                 UpdatedInfo.INTERRUPTED, limitDate);
375                         updateGlobalValue(entry.ordinal(), nbCountInfoInterrupted);
376                         return;
377                     case nbInfoToSubmit:
378                         nbCountInfoToSubmit = DbTransferLog.getResultCountPrepareStatement(
379                                 countInfo,
380                                 UpdatedInfo.TOSUBMIT, limitDate);
381                         updateGlobalValue(entry.ordinal(), nbCountInfoToSubmit);
382                         return;
383                     case nbInfoError:
384                         nbCountInfoError = DbTransferLog.getResultCountPrepareStatement(countInfo,
385                                 UpdatedInfo.INERROR, limitDate);
386                         updateGlobalValue(entry.ordinal(), nbCountInfoError);
387                         return;
388                     case nbInfoRunning:
389                         nbCountInfoRunning = DbTransferLog.getResultCountPrepareStatement(
390                                 countInfo,
391                                 UpdatedInfo.RUNNING, limitDate);
392                         updateGlobalValue(entry.ordinal(), nbCountInfoRunning);
393                         return;
394                     case nbInfoDone:
395                         nbCountInfoDone = DbTransferLog.getResultCountPrepareStatement(countInfo,
396                                 UpdatedInfo.DONE, limitDate);
397                         updateGlobalValue(entry.ordinal(), nbCountInfoDone);
398                         return;
399                     case nbAllTransfer:
400                         DbTransferLog.finishSelectOrCountPrepareStatement(countAllTransfer,
401                                 limitDate);
402                         nbCountAllTransfer = DbTransferLog
403                                 .getResultCountPrepareStatement(countAllTransfer);
404                         updateGlobalValue(entry.ordinal(), nbCountAllTransfer);
405                         return;
406                     case memoryTotal:
407                         return;
408                     case memoryFree:
409                         return;
410                     case memoryUsed:
411                         return;
412                     case nbThreads:
413                         nbThread = Thread.activeCount();
414                         updateGlobalValue(entry.ordinal(), nbThread);
415                         return;
416                     case nbNetworkConnection:
417                         nbNetworkConnection = FileBasedConfiguration.fileBasedConfiguration
418                                 .getFtpInternalConfiguration().getNumberSessions();
419                         updateGlobalValue(entry.ordinal(), nbNetworkConnection);
420                         return;
421                 }
422             } catch (WaarpDatabaseNoConnectionException e) {
423             } catch (WaarpDatabaseSqlException e) {
424             }
425         }
426     }
427 
428     /**
429      * Update a value in Detailed MIB part
430      * 
431      * @param nbMs
432      * @param entry
433      */
434     protected void run(long nbMs, WaarpDetailedValuesIndex entry) {
435         synchronized (trafficCounter) {
436             long limitDate = System.currentTimeMillis() - nbMs;
437             // Detailed
438             long value = DbTransferLog.getResultCountPrepareStatement(
439                     countStatus, entry.code, limitDate);
440             updateDetailedValue(entry.ordinal(), value + reply_info_notransfers[entry.ordinal()]);
441         }
442     }
443 
444     /**
445      * Update a value in Error MIB part
446      * 
447      * @param nbMs
448      * @param entry
449      */
450     protected void run(long nbMs, WaarpErrorValuesIndex entry) {
451         synchronized (trafficCounter) {
452             long limitDate = System.currentTimeMillis() - nbMs;
453             // Error
454             long value = DbTransferLog.getResultCountPrepareStatement(
455                     countStatus, entry.code, limitDate);
456             updateErrorValue(entry.ordinal(), value + reply_error_notransfers[entry.ordinal()]);
457         }
458     }
459 
460 }