]> WPIA git - gigi.git/blobdiff - src/org/cacert/gigi/ping/PingerDaemon.java
Merge "Suggestions to enhance the SQL call pattern."
[gigi.git] / src / org / cacert / gigi / ping / PingerDaemon.java
index 91ddfbb0b5a2188a8da3910c03971330b2abcf87..397ad58b508350c56028db1469db32af54cd0105 100644 (file)
 package org.cacert.gigi.ping;
 
 import java.security.KeyStore;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.SQLException;
 import java.util.HashMap;
-import org.cacert.gigi.Domain;
-import org.cacert.gigi.User;
+import java.util.LinkedList;
+import java.util.Queue;
+
 import org.cacert.gigi.database.DatabaseConnection;
+import org.cacert.gigi.database.DatabaseConnection.Link;
+import org.cacert.gigi.database.GigiPreparedStatement;
+import org.cacert.gigi.database.GigiResultSet;
+import org.cacert.gigi.dbObjects.Domain;
+import org.cacert.gigi.dbObjects.DomainPingConfiguration;
+import org.cacert.gigi.dbObjects.DomainPingType;
 import org.cacert.gigi.util.RandomToken;
 
 public class PingerDaemon extends Thread {
 
-    HashMap<String, DomainPinger> pingers = new HashMap<>();
-
-    private PreparedStatement searchNeededPings;
+    HashMap<DomainPingType, DomainPinger> pingers = new HashMap<>();
 
-    private PreparedStatement enterPingResult;
+    private GigiPreparedStatement searchNeededPings;
 
     private KeyStore truststore;
 
+    private Queue<DomainPingConfiguration> toExecute = new LinkedList<>();
+
     public PingerDaemon(KeyStore truststore) {
         this.truststore = truststore;
     }
 
     @Override
     public void run() {
-        try {
-            searchNeededPings = DatabaseConnection.getInstance().prepare("SELECT pingconfig.*, domains.domain, domains.memid FROM pingconfig LEFT JOIN domainPinglog ON domainPinglog.configId=pingconfig.id INNER JOIN domains ON domains.id=pingconfig.domainid WHERE domainPinglog.configId IS NULL ");
-            enterPingResult = DatabaseConnection.getInstance().prepare("INSERT INTO domainPinglog SET configId=?, state=?, result=?, challenge=?");
-            pingers.put("email", new EmailPinger());
-            pingers.put("ssl", new SSLPinger(truststore));
-            pingers.put("http", new HTTPFetch());
-            pingers.put("dns", new DNSPinger());
-        } catch (SQLException e) {
+        try (Link l = DatabaseConnection.newLink(false)) {
+            runWithConnection();
+        } catch (InterruptedException e) {
             e.printStackTrace();
         }
+    }
+
+    public void runWithConnection() {
+        searchNeededPings = new GigiPreparedStatement("SELECT `pingconfig`.`id` FROM `pingconfig` LEFT JOIN `domainPinglog` ON `domainPinglog`.`configId` = `pingconfig`.`id` INNER JOIN `domains` ON `domains`.`id` = `pingconfig`.`domainid` WHERE ( `domainPinglog`.`configId` IS NULL OR `domainPinglog`.`when` < CURRENT_TIMESTAMP - interval '6 mons') AND `domains`.`deleted` IS NULL AND `pingconfig`.`deleted` IS NULL GROUP BY `pingconfig`.`id`");
+        pingers.put(DomainPingType.EMAIL, new EmailPinger());
+        pingers.put(DomainPingType.SSL, new SSLPinger(truststore));
+        pingers.put(DomainPingType.HTTP, new HTTPFetch());
+        pingers.put(DomainPingType.DNS, new DNSPinger());
+
         while (true) {
             try {
-                execute();
-            } catch (SQLException e) {
-                e.printStackTrace();
+                boolean worked = false;
+                synchronized (this) {
+                    DomainPingConfiguration conf;
+                    while ((conf = toExecute.peek()) != null) {
+                        worked = true;
+                        handle(conf);
+                        toExecute.remove();
+                    }
+                    notifyAll();
+                }
+
+                GigiResultSet rs = searchNeededPings.executeQuery();
+                while (rs.next()) {
+                    worked = true;
+                    handle(DomainPingConfiguration.getById(rs.getInt("id")));
+                }
+                try {
+                    if ( !worked) {
+                        Thread.sleep(5000);
+                    }
+                } catch (InterruptedException e) {
+                }
+            } catch (Throwable t) {
+                t.printStackTrace();
             }
+        }
+    }
+
+    private void handle(DomainPingConfiguration conf) {
+        DomainPingType type = conf.getType();
+        String config = conf.getInfo();
+        DomainPinger dp = pingers.get(type);
+        if (dp != null) {
+            if (dp instanceof EmailPinger) {
+                String token = null;
+                token = RandomToken.generateToken(16);
+                config = config + ":" + token;
+            }
+            Domain target = conf.getTarget();
+            System.err.println("Executing " + dp + " on " + target + " (" + System.currentTimeMillis() + ")");
             try {
-                Thread.sleep(5000);
-            } catch (InterruptedException e) {
+                dp.ping(target, config, target.getOwner(), conf.getId());
+            } catch (Throwable t) {
+                t.printStackTrace();
+                DomainPinger.enterPingResult(conf.getId(), "error", "exception", null);
             }
+            System.err.println("done (" + System.currentTimeMillis() + ")");
         }
     }
 
-    private void execute() throws SQLException {
-
-        ResultSet rs = searchNeededPings.executeQuery();
-        while (rs.next()) {
-            String type = rs.getString("type");
-            String config = rs.getString("info");
-            DomainPinger dp = pingers.get(type);
-            if (dp != null) {
-                String token = null;
-                if (dp instanceof EmailPinger) {
-                    token = RandomToken.generateToken(16);
-                    config = config + ":" + token;
-                }
-                enterPingResult.setInt(1, rs.getInt("id"));
-                String resp = dp.ping(Domain.getById(rs.getInt("domainid")), config, User.getById(rs.getInt("memid")));
-                enterPingResult.setString(2, DomainPinger.PING_STILL_PENDING == resp ? "open" : DomainPinger.PING_SUCCEDED.equals(resp) ? "success" : "failed");
-                enterPingResult.setString(3, resp);
-                enterPingResult.setString(4, token);
-                enterPingResult.execute();
+    public synchronized void queue(DomainPingConfiguration toReping) {
+        interrupt();
+        toExecute.add(toReping);
+        while (toExecute.size() > 0) {
+            try {
+                wait();
+            } catch (InterruptedException e) {
+                e.printStackTrace();
             }
         }
     }