View Javadoc
1   /**
2    * This Source Code Form is subject to the terms of the Mozilla Public
3    * License, v. 2.0. If a copy of the MPL was not distributed with this
4    * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5    *
6    * If it is not possible or desirable to put the notice in a particular
7    * file, then You may include the notice in a location (such as a LICENSE
8    * file in a relevant directory) where a recipient would be likely to look
9    * for such a notice.
10   *
11   * 
12   */
13  /*  ---------------------------------------------------------------------------
14   *  U.S. Government, Department of the Army
15   *  Army Materiel Command
16   *  Research Development Engineering Command
17   *  Communications Electronics Research Development and Engineering Center
18   *  ---------------------------------------------------------------------------
19   */
20  package org.miloss.fgsms.datapruner;
21  
22  import java.io.File;
23  import java.io.RandomAccessFile;
24  import java.nio.channels.FileChannel;
25  import java.nio.channels.FileLock;
26  import java.sql.Connection;
27  import java.sql.PreparedStatement;
28  import java.sql.ResultSet;
29  import java.util.GregorianCalendar;
30  import org.miloss.fgsms.common.Utility;
31  
32  import org.miloss.fgsms.sla.AuxHelper;
33  import org.miloss.fgsms.sla.SLACommon;
34  import org.apache.log4j.Level;
35  import org.miloss.fgsms.common.Logger;;
36  import org.apache.log4j.PropertyConfigurator;
37  import org.miloss.fgsms.services.interfaces.common.PolicyType;
38  
39  /**
40   * Removes old records per the service policy's data retention setting
41   *
42   * @author AO
43   */
44  public class DataPruner {
45  
46      static Logger log = Logger.getLogger("fgsms.DataPruner");
47      private boolean running = true;
48      private File file;
49      private FileChannel channel;
50      private FileLock lock;
51      private boolean done = false;
52      public static boolean noloop = false;
53  
54      /**
55       * Data Pruner, this utility process for fgsms will remove stale data from
56       * the performance database based on service policy
57       *
58       * @param args the command line arguments
59       */
60      public static void main(String[] args) throws InterruptedException {
61          new DataPruner().Main(args);
62  
63      }
64  
65      private void closeLock() {
66          try {
67              lock.release();
68          } catch (Exception e) {
69          }
70          try {
71              channel.close();
72          } catch (Exception e) {
73          }
74      }
75  
76      private void deleteFile() {
77          try {
78              file.delete();
79          } catch (Exception e) {
80          }
81      }
82  
83      public class RunWhenShuttingDown extends Thread {
84  
85          public void run() {
86              System.out.println("Control-C caught. Shutting down...");
87              running = false;
88              while (!done) {
89                  try {
90                      Thread.sleep(1000);
91                  } catch (InterruptedException ex) {
92                  }
93              }
94              closeLock();
95              deleteFile();
96              if (!noloop) {
97                  AuxHelper.TryUpdateStatus(false, "urn:fgsms:DataPruner:" + Utility.getHostName(), "Stopped", false, PolicyType.STATUS, AuxHelper.UNSPECIFIED, SLACommon.GetHostName());
98              }
99          }
100     }
101 
102     private void Main(String[] args) throws InterruptedException {
103         boolean pooled = false;
104         try {
105             file = new File("dp.lck");
106             channel = new RandomAccessFile(file, "rw").getChannel();
107             lock = channel.tryLock();
108         } catch (Exception e) {
109             // already locked
110             closeLock();
111             System.out.println("Could not obtain the lock, this means that either this program is already running or something went wrong and the file dp.lck needs to be deleted.");
112             return;
113         }
114         if (lock == null) {
115             closeLock();
116             System.out.println("Could not obtain the lock, this means that either this program is already running or something went wrong and the file dp.lck needs to be deleted.");
117             return;
118         }
119 
120         if (args.length == 1 && args[0].equalsIgnoreCase("noloop")) {
121             noloop = true;
122         }
123 
124         Runtime.getRuntime().addShutdownHook(new RunWhenShuttingDown());
125         PropertyConfigurator.configure("log4j.properties");
126         long lastRanAt = 0;
127         long interval = 24 * 60 * 60 * 1000;        //24 hours
128         long lastUpdateAt = 0;
129         long updatestatusinterval = 5 * 60 * 1000;  //5 minues
130 
131         log.log(Level.INFO, "fgsms Data Pruner startup");
132         while (running) {
133 
134             {
135                 if (System.currentTimeMillis() - lastUpdateAt > updatestatusinterval) {
136                     AuxHelper.TryUpdateStatus(true, "urn:fgsms:DataPruner:" + Utility.getHostName(), "OK", pooled, PolicyType.STATUS, AuxHelper.UNSPECIFIED, SLACommon.GetHostName());
137                     lastUpdateAt = System.currentTimeMillis();
138 
139                 }
140                 //check last time purged
141                 if (System.currentTimeMillis() - lastRanAt > interval) {
142                     AuxHelper.TryUpdateStatus(true, "urn:fgsms:DataPruner:" + Utility.getHostName(), "OK", pooled, PolicyType.STATUS, AuxHelper.UNSPECIFIED, SLACommon.GetHostName());
143                     log.log(Level.INFO, "fgsms Data Pruner is purging old records...");
144                     Purge(false);
145                     log.log(Level.INFO, "fgsms Data Pruner sleeping for " + interval + "ms");
146                     lastRanAt = System.currentTimeMillis();
147                 }
148             }
149             if (noloop) {
150                 running = false;
151             }
152             if (running) {
153                 Thread.sleep(5000);
154             }
155 
156         }
157         done = true;
158     }
159 
160     /**
161      * this is called from the quartz job or from void main
162      *
163      * @param pooled
164      */
165     public void Purge(boolean pooled) {
166         try {
167             GregorianCalendar cal = (GregorianCalendar) GregorianCalendar.getInstance();
168             long now = cal.getTimeInMillis();
169             Connection ConfigCon = null;
170             Connection PerfCon = null;
171             if (pooled) {
172                 ConfigCon = Utility.getConfigurationDBConnection();
173                 PerfCon = Utility.getPerformanceDBConnection();
174             } else {
175                 ConfigCon = Utility.getConfigurationDB_NONPOOLED_Connection();
176                 PerfCon = Utility.getPerformanceDB_NONPOOLED_Connection();
177             }
178             PreparedStatement com = ConfigCon.prepareStatement("select uri, datattl, hostname from servicepolicies;");
179             ResultSet rs = com.executeQuery();
180             while (rs.next() && running) {
181                 long ttl = now - rs.getLong("datattl");
182                 PreparedStatement del = PerfCon.prepareStatement(
183                         "delete from rawdata where"
184                         + "(utcdatetime < ?) and (uri = ?);"
185                         + "delete from brokerhistory where"
186                         + "(utcdatetime < ?) and (host = ?);"
187                         + "delete from availability where"
188                         + "(utcdatetime < ?) and (uri = ?);"
189                         + "delete from slaviolations where"
190                         + "(utcdatetime < ?) and (uri = ?);"
191                         + "delete from rawdatadrives where"
192                         + "(utcdatetime < ?) and (hostname = ?);"
193                         + "delete from rawdatamachineprocess where"
194                         + "(utcdatetime < ?) and (uri = ?);"
195                         + "delete from rawdatanic where"
196                         + "(utcdatetime < ?) and (uri = ?);"
197                         + "delete from rawdatamachinesensor where"
198                         + "(utcdatetime < ?) and (uri = ?);");
199                 del.setLong(1, ttl);
200                 del.setString(2, rs.getString("uri"));
201                 del.setLong(3, ttl);
202                 del.setString(4, rs.getString("uri"));
203                 del.setLong(5, ttl);
204                 del.setString(6, rs.getString("uri"));
205                 del.setLong(7, ttl);
206                 del.setString(8, rs.getString("uri"));
207 
208                 del.setLong(9, ttl);
209                 //unspecified hostnames shouldn't be an issue
210                 del.setString(10, rs.getString("hostname"));
211                 del.setLong(11, ttl);
212                 del.setString(12, rs.getString("uri"));
213 
214                 del.setLong(13, ttl);
215                 del.setString(14, rs.getString("uri"));
216                 del.setLong(15, ttl);
217                 del.setString(16, rs.getString("uri"));
218 
219                 int i = del.executeUpdate();
220                 if (i == 0) {
221                     log.log(Level.DEBUG, i + " records removed for service " + rs.getString("uri"));
222                 } else {
223                     log.log(Level.INFO, i + " records removed for service " + rs.getString("uri"));
224                 }
225                 del.close();
226             }
227             rs.close();
228             com.close();
229             PerfCon.close();
230 
231             ConfigCon.close();
232             //run once a day
233 
234         } catch (Exception ex) {
235             System.console().writer().println("caught error!" + ex.getLocalizedMessage());
236             log.log(Level.ERROR, null, ex);
237 
238             AuxHelper.TryUpdateStatus(false, "urn:fgsms:DataPruner:" + Utility.getHostName(), "ERROR", pooled, PolicyType.STATUS, AuxHelper.UNSPECIFIED, SLACommon.GetHostName());
239         }
240     }
241 }