KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejbca > core > model > services > workers > CertificateExpirationNotifierWorker


1 /*************************************************************************
2  * *
3  * EJBCA: The OpenSource Certificate Authority *
4  * *
5  * This software is free software; you can redistribute it and/or *
6  * modify it under the terms of the GNU Lesser General Public *
7  * License as published by the Free Software Foundation; either *
8  * version 2.1 of the License, or any later version. *
9  * *
10  * See terms of license at gnu.org. *
11  * *
12  *************************************************************************/

13 package org.ejbca.core.model.services.workers;
14
15 import java.security.cert.X509Certificate JavaDoc;
16 import java.sql.Connection JavaDoc;
17 import java.sql.PreparedStatement JavaDoc;
18 import java.sql.ResultSet JavaDoc;
19 import java.util.ArrayList JavaDoc;
20 import java.util.Collection JavaDoc;
21 import java.util.Date JavaDoc;
22 import java.util.Iterator JavaDoc;
23
24 import org.apache.log4j.Logger;
25 import org.ejbca.core.ejb.JNDINames;
26 import org.ejbca.core.ejb.ca.store.CertificateDataBean;
27 import org.ejbca.core.model.InternalResources;
28 import org.ejbca.core.model.ra.UserDataVO;
29 import org.ejbca.core.model.services.BaseWorker;
30 import org.ejbca.core.model.services.ServiceExecutionFailedException;
31 import org.ejbca.core.model.services.actions.MailActionInfo;
32 import org.ejbca.util.Base64;
33 import org.ejbca.util.CertTools;
34 import org.ejbca.util.JDBCUtil;
35 import org.ejbca.util.NotificationParamGen;
36
37 /**
38  * Email Notifier Worker
39  *
40  * Makes queries about which emails that is about to expire in a given number of days
41  * and creates an notification sent to either the end user or the administrator.
42  *
43  * @author Philip Vendil
44  *
45  * $id$
46  */

47 public class CertificateExpirationNotifierWorker extends BaseWorker {
48
49     private static final Logger log = Logger.getLogger(CertificateExpirationNotifierWorker.class);
50     /** Internal localization of logs and errors */
51     private static final InternalResources intres = InternalResources.getInstance();
52
53     /** Should be a ';' separated string of CANames. */
54     public static final String JavaDoc PROP_CAIDSTOCHECK = "worker.emailexpiration.caidstocheck";
55     
56     /** The time in 'timeunit' remaining of a certificate before sending a notification */
57     public static final String JavaDoc PROP_TIMEBEFOREEXPIRING = "worker.emailexpiration.timebeforeexpiring";
58     
59     /** Unit in days, hours or seconds */
60     public static final String JavaDoc PROP_TIMEUNIT = "worker.emailexpiration.timeunit";
61     
62     /** Boolean indicating if a notification should be sent to the end user of the certificate */
63     public static final String JavaDoc PROP_SENDTOENDUSERS = "worker.emailexpiration.sendtoendusers";
64     
65     /** Boolean indicating if a nofification should be sent to the administartors */
66     public static final String JavaDoc PROP_SENDTOADMINS = "worker.emailexpiration.sendtoadmins";
67     
68     /** The subject to use in the end user notification */
69     public static final String JavaDoc PROP_USERSUBJECT = "worker.emailexpiration.usersubject";
70     
71     /** The message to use in the end user notification. Subsutution varibles are possible in
72      * the same way as for regular notifications.*/

73     public static final String JavaDoc PROP_USERMESSAGE = "worker.emailexpiration.usermessage";
74     
75     /** The subject to use in the admin notification */
76     public static final String JavaDoc PROP_ADMINSUBJECT = "worker.emailexpiration.adminsubject";
77     
78     /** The message to use in the adminr notification. Subsutution varibles are possible in
79      * the same way as for regular notifications.*/

80     public static final String JavaDoc PROP_ADMINMESSAGE = "worker.emailexpiration.adminmessage";
81     
82     
83     public static final String JavaDoc UNIT_SECONDS = "SECONDS";
84     public static final String JavaDoc UNIT_MINUTES = "MINUTES";
85     public static final String JavaDoc UNIT_HOURS = "HOURS";
86     public static final String JavaDoc UNIT_DAYS = "DAYS";
87     
88     public static final int UNITVAL_SECONDS = 1;
89     public static final int UNITVAL_MINUTES = 60;
90     public static final int UNITVAL_HOURS = 3600;
91     public static final int UNITVAL_DAYS = 86400;
92
93     public static final String JavaDoc[] AVAILABLE_UNITS = {UNIT_SECONDS, UNIT_MINUTES, UNIT_HOURS, UNIT_DAYS};
94     public static final int[] AVAILABLE_UNITSVALUES = {UNITVAL_SECONDS, UNITVAL_MINUTES, UNITVAL_HOURS, UNITVAL_DAYS};
95     
96     private transient Collection JavaDoc cAIdsToCheck = null;
97     private transient long timeBeforeExpire = -1;
98     private transient String JavaDoc endUserSubject = null;
99     private transient String JavaDoc adminSubject = null;
100     private transient String JavaDoc endUserMessage = null;
101     private transient String JavaDoc adminMessage = null;
102     
103     private class EmailCertData{
104         
105         private String JavaDoc fingerPrint = null;
106         private MailActionInfo actionInfo = null;
107         
108         public EmailCertData(String JavaDoc fingerPrint, MailActionInfo actionInfo) {
109             super();
110             this.fingerPrint = fingerPrint;
111             this.actionInfo = actionInfo;
112         }
113
114         public String JavaDoc getFingerPrint() {
115             return fingerPrint;
116         }
117
118         public MailActionInfo getActionInfo() {
119             return actionInfo;
120         }
121         
122     }
123     
124     /**
125      * Worker that makes a query to the Certificate Store about
126      * expiring certificates.
127      *
128      * @see org.ejbca.core.model.services.IWorker#work()
129      */

130     public void work() throws ServiceExecutionFailedException {
131         log.debug(">CertificateExpirationNotifierWorker.work started");
132         
133         ArrayList JavaDoc userEmailQueue = new ArrayList JavaDoc();
134         ArrayList JavaDoc adminEmailQueue = new ArrayList JavaDoc();
135         
136         // Build Query
137
String JavaDoc cASelectString = "";
138         if(getCAIdsToCheck().size() >0){
139             Iterator JavaDoc iter = getCAIdsToCheck().iterator();
140             while(iter.hasNext()){
141                 String JavaDoc caid = (String JavaDoc) iter.next();
142                 String JavaDoc cadn = getCAAdminSession().getCAInfo(getAdmin(), Integer.parseInt(caid)).getSubjectDN();
143                 if(cASelectString.equals("")){
144                     cASelectString = "issuerDN='" + cadn +"' ";
145                 }else{
146                     cASelectString += " OR issuerDN='" + cadn +"' ";
147                 }
148             }
149
150             String JavaDoc checkDate = "expireDate <= " + ((new Date JavaDoc()).getTime() + getTimeBeforeExpire());
151             String JavaDoc statuses = "status=" +CertificateDataBean.CERT_ACTIVE;
152
153             // Execute Query
154
Connection JavaDoc con = null;
155             PreparedStatement JavaDoc ps = null;
156             PreparedStatement JavaDoc updateStatus = null;
157             ResultSet JavaDoc result = null;
158
159             try{
160                 con = JDBCUtil.getDBConnection(JNDINames.DATASOURCE);
161                 ps = con.prepareStatement("SELECT DISTINCT fingerprint, base64Cert, username"
162                         + " FROM CertificateData WHERE ("
163                         + cASelectString + ") AND ("
164                         + checkDate + ") AND ("
165                         + statuses + ")");
166                 
167                 result = ps.executeQuery();
168
169                 while(result.next()){
170                     // For each certificate update status.
171
String JavaDoc fingerprint = result.getString(1);
172                     String JavaDoc certBase64 = result.getString(2);
173                     String JavaDoc username = result.getString(3);
174                     X509Certificate JavaDoc cert = CertTools.getCertfromByteArray(Base64.decode(certBase64.getBytes()));
175                     
176                     UserDataVO userData = getUserAdminSession().findUser(getAdmin(), username);
177                     if(userData != null){
178                         String JavaDoc userDN = userData.getDN();
179
180                         if(isSendToEndUsers()){
181                             NotificationParamGen paramGen = new NotificationParamGen(userDN,cert);
182                             if(userData.getEmail() == null || userData.getEmail().trim().equals("")){
183                                 String JavaDoc msg = intres.getLocalizedMessage("services.certexpireworker.errornoemail", username);
184                                 log.info(msg);
185                             }else{
186                                 // Populate end user message
187
String JavaDoc message = NotificationParamGen.interpolate(paramGen.getParams(), getEndUserMessage());
188                                 MailActionInfo mailActionInfo = new MailActionInfo(userData.getEmail(),getEndUserSubject(), message);
189                                 userEmailQueue.add(new EmailCertData(fingerprint,mailActionInfo));
190                             }
191                         }
192                     }
193                     if(isSendToAdmins()){
194                         // Populate admin message
195
NotificationParamGen paramGen = new NotificationParamGen(cert.getSubjectDN().toString(),cert);
196                         String JavaDoc message = NotificationParamGen.interpolate(paramGen.getParams(), getAdminMessage());
197                         MailActionInfo mailActionInfo = new MailActionInfo(null,getAdminSubject(), message);
198                         adminEmailQueue.add(new EmailCertData(fingerprint,mailActionInfo));
199                     }
200                     
201
202                 }
203
204
205
206             } catch (Exception JavaDoc fe) {
207                 fe.printStackTrace();
208                 throw new ServiceExecutionFailedException(fe);
209             } finally {
210                 if(updateStatus != null){
211                     JDBCUtil.close(updateStatus);
212                 }
213                 JDBCUtil.close(con, ps, result);
214             }
215             
216             
217             if(isSendToEndUsers()){
218                 sendEmails(userEmailQueue);
219             }
220             if(isSendToAdmins()){
221                 sendEmails(adminEmailQueue);
222             }
223
224         }
225         log.debug("<CertificateExpirationNotifierWorker.work ended");
226     }
227     
228     private void sendEmails(ArrayList JavaDoc queue) throws ServiceExecutionFailedException{
229         Iterator JavaDoc iter = queue.iterator();
230         while(iter.hasNext()){
231             Connection JavaDoc con = null;
232             PreparedStatement JavaDoc updateStatus = null;
233             try{
234                 con = JDBCUtil.getDBConnection(JNDINames.DATASOURCE);
235                 EmailCertData next = (EmailCertData) iter.next();
236                 getAction().performAction(next.getActionInfo());
237                 updateStatus = con.prepareStatement("UPDATE CertificateData SET status=" + CertificateDataBean.CERT_NOTIFIEDABOUTEXPIRATION +" WHERE fingerprint='" + next.getFingerPrint() + "'");
238                 updateStatus.execute();
239             } catch (Exception JavaDoc fe) {
240                 fe.printStackTrace();
241                 throw new ServiceExecutionFailedException(fe);
242             } finally {
243                 if(updateStatus != null){
244                     JDBCUtil.close(updateStatus);
245                 }
246                 if(con != null){
247                   JDBCUtil.close(con);
248                 }
249             }
250         }
251     }
252     
253     private Collection JavaDoc getCAIdsToCheck(){
254         if(cAIdsToCheck == null){
255             cAIdsToCheck = new ArrayList JavaDoc();
256             String JavaDoc[] canames = properties.getProperty(PROP_CAIDSTOCHECK).split(";");
257             for(int i=0;i<canames.length;i++ ){
258                 cAIdsToCheck.add(canames[i]);
259             }
260         }
261         return cAIdsToCheck;
262     }
263     
264     private long getTimeBeforeExpire() throws ServiceExecutionFailedException{
265         if(timeBeforeExpire == -1){
266             String JavaDoc unit = properties.getProperty(PROP_TIMEUNIT);
267             if(unit == null){
268                 String JavaDoc msg = intres.getLocalizedMessage("services.certexpireworker.errorconfig", serviceName, "UNIT");
269                 throw new ServiceExecutionFailedException(msg);
270             }
271             int unitval = 0;
272             for(int i=0;i<AVAILABLE_UNITS.length;i++){
273                 if(AVAILABLE_UNITS[i].equalsIgnoreCase(unit)){
274                     unitval = AVAILABLE_UNITSVALUES[i];
275                     break;
276                 }
277             }
278             if(unitval == 0){
279                 String JavaDoc msg = intres.getLocalizedMessage("services.certexpireworker.errorconfig", serviceName, "UNIT");
280                 throw new ServiceExecutionFailedException(msg);
281             }
282                         
283             String JavaDoc value = properties.getProperty(PROP_TIMEBEFOREEXPIRING);
284             int intvalue = 0;
285             try{
286               intvalue = Integer.parseInt(value);
287             }catch(NumberFormatException JavaDoc e){
288                 String JavaDoc msg = intres.getLocalizedMessage("services.certexpireworker.errorconfig", serviceName, "VALUE");
289                 throw new ServiceExecutionFailedException(msg);
290             }
291             
292             if(intvalue == 0){
293                 String JavaDoc msg = intres.getLocalizedMessage("services.certexpireworker.errorconfig", serviceName, "VALUE");
294                 throw new ServiceExecutionFailedException(msg);
295             }
296             timeBeforeExpire = intvalue * unitval;
297         }
298
299         return timeBeforeExpire * 1000;
300     }
301
302     private String JavaDoc getAdminMessage() {
303         if(adminMessage == null){
304             adminMessage = properties.getProperty(PROP_ADMINMESSAGE,"No Message Configured");
305         }
306         return adminMessage;
307     }
308
309     private String JavaDoc getAdminSubject() {
310         if(adminSubject == null){
311             adminSubject = properties.getProperty(PROP_ADMINSUBJECT,"No Subject Configured");
312         }
313         
314         return adminSubject;
315     }
316
317     private String JavaDoc getEndUserMessage() {
318         if(endUserMessage == null){
319             endUserMessage = properties.getProperty(PROP_USERMESSAGE,"No Message Configured");
320         }
321         
322         return endUserMessage;
323     }
324
325     private String JavaDoc getEndUserSubject() {
326         if(endUserSubject == null){
327             endUserSubject = properties.getProperty(PROP_USERSUBJECT,"No Subject Configured");
328         }
329         
330         return endUserSubject;
331     }
332
333     private boolean isSendToAdmins() {
334         return properties.getProperty(PROP_SENDTOADMINS,"FALSE").equalsIgnoreCase("TRUE");
335     }
336
337     private boolean isSendToEndUsers() {
338         return properties.getProperty(PROP_SENDTOENDUSERS,"FALSE").equalsIgnoreCase("TRUE");
339     }
340     
341
342
343 }
344
Popular Tags