]> WPIA git - gigi.git/blob - src/club/wpia/gigi/dbObjects/DomainPingConfiguration.java
chg: revoke certificates if repeated ping failed
[gigi.git] / src / club / wpia / gigi / dbObjects / DomainPingConfiguration.java
1 package club.wpia.gigi.dbObjects;
2
3 import java.sql.Timestamp;
4 import java.util.Date;
5
6 import club.wpia.gigi.Gigi;
7 import club.wpia.gigi.GigiApiException;
8 import club.wpia.gigi.database.GigiPreparedStatement;
9 import club.wpia.gigi.database.GigiResultSet;
10 import club.wpia.gigi.output.template.SprintfCommand;
11
12 public class DomainPingConfiguration implements IdCachable {
13
14     private static final int REPING_MINIMUM_DELAY = 5 * 60 * 1000;
15
16     private int id;
17
18     private Domain target;
19
20     private DomainPingType type;
21
22     private String info;
23
24     private DomainPingConfiguration(int id) {
25         try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT `id`, `domainid`, `type`, `info` FROM `pingconfig` WHERE `id`=?")) {
26             ps.setInt(1, id);
27
28             GigiResultSet rs = ps.executeQuery();
29             if ( !rs.next()) {
30                 throw new IllegalArgumentException("Invalid pingconfig id " + id);
31             }
32             this.id = rs.getInt("id");
33             target = Domain.getById(rs.getInt("domainid"));
34             type = DomainPingType.valueOf(rs.getString("type").toUpperCase());
35             info = rs.getString("info");
36         }
37     }
38
39     @Override
40     public int getId() {
41         return id;
42     }
43
44     public Domain getTarget() {
45         return target;
46     }
47
48     public DomainPingType getType() {
49         return type;
50     }
51
52     public String getInfo() {
53         return info;
54     }
55
56     private static ObjectCache<DomainPingConfiguration> cache = new ObjectCache<>();
57
58     public static synchronized DomainPingConfiguration getById(int id) {
59         DomainPingConfiguration res = cache.get(id);
60         if (res == null) {
61             cache.put(res = new DomainPingConfiguration(id));
62         }
63         return res;
64     }
65
66     public Date getLastExecution() {
67         try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT `when` AS stamp from `domainPinglog` WHERE `configId`=? ORDER BY `when` DESC LIMIT 1")) {
68             ps.setInt(1, id);
69             GigiResultSet rs = ps.executeQuery();
70             if (rs.next()) {
71                 return new Date(rs.getTimestamp("stamp").getTime());
72             }
73             return new Date(0);
74         }
75     }
76
77     public Date getLastSuccess() {
78         try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT `when` AS stamp from `domainPinglog` WHERE `configId`=? AND state='success' ORDER BY `when` DESC LIMIT 1")) {
79             ps.setInt(1, id);
80             GigiResultSet rs = ps.executeQuery();
81             if (rs.next()) {
82                 return new Date(rs.getTimestamp("stamp").getTime());
83             }
84             return new Date(0);
85         }
86     }
87
88     public synchronized void requestReping() throws GigiApiException {
89         Date lastExecution = getLastExecution();
90         if (lastExecution.getTime() + REPING_MINIMUM_DELAY < System.currentTimeMillis()) {
91             Gigi.notifyPinger(this);
92             return;
93         }
94         throw new GigiApiException(SprintfCommand.createSimple("Reping is only allowed after {0} minutes, yours end at {1}.", REPING_MINIMUM_DELAY / 60 / 1000, new Date(lastExecution.getTime() + REPING_MINIMUM_DELAY)));
95     }
96
97     /**
98      * Return true when there was a last execution and it succeeded.
99      * 
100      * @return if this ping is currently valid.
101      */
102     public boolean isValid() {
103         try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT state='success' AS bool from `domainPinglog` WHERE `configId`=? ORDER BY `when` DESC LIMIT 1")) {
104             ps.setInt(1, id);
105             GigiResultSet rs = ps.executeQuery();
106             if ( !rs.next()) {
107                 return false;
108             }
109             return rs.getBoolean(1);
110         }
111     }
112
113     /**
114      * Return true when this ping has not been successful within the last 2
115      * weeks.
116      * 
117      * @param time
118      *            the point in time for which the determination is carried out.
119      * @return the value for this ping.
120      */
121     public boolean isStrictlyInvalid(Date time) {
122         Date lastSuccess = getLastSuccess();
123         if (lastSuccess.getTime() == 0) {
124             // never a successful ping
125             return true;
126         }
127         try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT `when` AS stamp from `domainPinglog` WHERE `configId`=? AND state='failed' AND `when` > ? ORDER BY `when` ASC LIMIT 1")) {
128             ps.setInt(1, id);
129             ps.setTimestamp(2, new Timestamp(lastSuccess.getTime()));
130             GigiResultSet rs = ps.executeQuery();
131             if (rs.next()) {
132                 Date turnedInvalid = new Date(rs.getTimestamp("stamp").getTime());
133                 // turned invalid older than 2 weeks ago
134                 return turnedInvalid.getTime() < time.getTime() - 2L * 7 * 24 * 60 * 60 * 1000;
135             }
136             return false;
137         }
138     }
139 }