KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ejbca > core > ejb > upgrade > UpgradeSessionBean


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
14 package org.ejbca.core.ejb.upgrade;
15
16 import java.io.ByteArrayOutputStream JavaDoc;
17 import java.io.IOException JavaDoc;
18 import java.io.InputStream JavaDoc;
19 import java.io.InputStreamReader JavaDoc;
20 import java.io.UnsupportedEncodingException JavaDoc;
21 import java.sql.Connection JavaDoc;
22 import java.sql.PreparedStatement JavaDoc;
23 import java.sql.ResultSet JavaDoc;
24 import java.sql.SQLException JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.Collection JavaDoc;
27 import java.util.Iterator JavaDoc;
28
29 import javax.ejb.CreateException JavaDoc;
30 import javax.ejb.EJBException JavaDoc;
31
32 import org.apache.commons.lang.StringUtils;
33 import org.ejbca.core.ejb.BaseSessionBean;
34 import org.ejbca.core.ejb.JNDINames;
35 import org.ejbca.core.ejb.ServiceLocator;
36 import org.ejbca.core.ejb.ca.caadmin.ICAAdminSessionLocal;
37 import org.ejbca.core.ejb.ca.caadmin.ICAAdminSessionLocalHome;
38 import org.ejbca.core.ejb.log.LogConfigurationDataLocal;
39 import org.ejbca.core.ejb.log.LogConfigurationDataLocalHome;
40 import org.ejbca.core.model.log.Admin;
41 import org.ejbca.util.JDBCUtil;
42 import org.ejbca.util.SqlExecutor;
43
44 import se.anatom.ejbca.log.OldLogConfigurationDataLocal;
45 import se.anatom.ejbca.log.OldLogConfigurationDataLocalHome;
46
47 /** The upgrade session bean is used to upgrade the database between ejbca releases.
48  *
49  * @version $Id: UpgradeSessionBean.java,v 1.12 2007/01/12 09:43:27 anatom Exp $
50  * @ejb.bean
51  * display-name="UpgradeSB"
52  * name="UpgradeSession"
53  * jndi-name="UpgradeSession"
54  * view-type="both"
55  * type="Stateless"
56  * transaction-type="Container"
57  * generate="true"
58  *
59  * @ejb.transaction type="RequiresNew"
60  *
61  * @weblogic.enable-call-by-reference True
62  *
63  * @ejb.home
64  * extends="javax.ejb.EJBHome"
65  * local-extends="javax.ejb.EJBLocalHome"
66  * local-class="org.ejbca.core.ejb.upgrade.IUpgradeSessionLocalHome"
67  * remote-class="org.ejbca.core.ejb.upgrade.IUpgradeSessionHome"
68  *
69  * @ejb.env-entry
70  * name="DataSource"
71  * type="java.lang.String"
72  * value="${datasource.jndi-name-prefix}${datasource.jndi-name}"
73  *
74  * @ejb.interface
75  * extends="javax.ejb.EJBObject"
76  * local-extends="javax.ejb.EJBLocalObject"
77  * local-class="org.ejbca.core.ejb.upgrade.IUpgradeSessionLocal"
78  * remote-class="org.ejbca.core.ejb.upgrade.IUpgradeSessionRemote"
79  *
80  * @ejb.ejb-external-ref
81  * description="The Log Configuration Data Entity bean"
82  * view-type="local"
83  * ref-name="ejb/LogConfigurationDataLocal"
84  * type="Entity"
85  * home="org.ejbca.core.ejb.log.LogConfigurationDataLocalHome"
86  * business="org.ejbca.core.ejb.log.LogConfigurationDataLocal"
87  * link="LogConfigurationData"
88  *
89  * @ejb.ejb-external-ref
90  * description="The Old Log Configuration Data Entity bean"
91  * view-type="local"
92  * ref-name="ejb/OldLogConfigurationDataLocal"
93  * type="Entity"
94  * home="se.anatom.ejbca.log.OldLogConfigurationDataLocalHome"
95  * business="se.anatom.ejbca.log.OldLogConfigurationDataLocal"
96  * link="OldLogConfigurationData"
97  *
98  * @ejb.ejb-external-ref
99  * description="The CA Admin Session"
100  * view-type="local"
101  * ref-name="ejb/CAAdminSessionLocal"
102  * type="Session"
103  * home="org.ejbca.core.ejb.ca.caadmin.ICAAdminSessionLocalHome"
104  * business="org.ejbca.core.ejb.ca.caadmin.ICAAdminSessionLocal"
105  * link="CAAdminSession"
106  */

107 public class UpgradeSessionBean extends BaseSessionBean {
108
109     /** Var holding JNDI name of datasource */
110     private String JavaDoc dataSource = "";
111
112     private OldLogConfigurationDataLocalHome oldLogHome = null;
113     private LogConfigurationDataLocalHome logHome = null;
114     /** The local interface of the ca admin session bean */
115     private ICAAdminSessionLocal caadminsession = null;
116     private Admin administrator = null;
117     
118     /**
119      * Default create for SessionBean without any creation Arguments.
120      *
121      * @throws CreateException if bean instance can't be created
122      */

123     public void ejbCreate() throws CreateException JavaDoc {
124         dataSource = getLocator().getString(JNDINames.DATASOURCE);
125         logHome = (LogConfigurationDataLocalHome)ServiceLocator.getInstance().getLocalHome(LogConfigurationDataLocalHome.COMP_NAME);
126         oldLogHome = (OldLogConfigurationDataLocalHome)ServiceLocator.getInstance().getLocalHome(OldLogConfigurationDataLocalHome.COMP_NAME);
127         
128     }
129
130     /**
131      * Gets connection to ca admin session bean
132      */

133     private ICAAdminSessionLocal getCaAdminSession() {
134         if(caadminsession == null){
135           try{
136               ICAAdminSessionLocalHome caadminsessionhome = (ICAAdminSessionLocalHome)getLocator().getLocalHome(ICAAdminSessionLocalHome.COMP_NAME);
137               caadminsession = caadminsessionhome.create();
138           }catch(Exception JavaDoc e){
139              throw new EJBException JavaDoc(e);
140           }
141         }
142         return caadminsession;
143     } //getCaAdminSession
144

145     /** Runs a preCheck to see if an upgrade is possible
146      *
147      * @return true if ok to upgrade or false if not
148      */

149     private boolean preCheck() {
150         debug(">preCheck");
151         boolean ret = false;
152         Connection JavaDoc con = null;
153         PreparedStatement JavaDoc ps = null;
154         try {
155             error("Getting connection for: "+dataSource);
156             con = JDBCUtil.getDBConnection(JNDINames.DATASOURCE);
157             ps = con.prepareStatement("select userDataVO from CertReqHistoryData");
158             ResultSet JavaDoc rs = ps.executeQuery();
159             if (rs.next()) {
160                 try {
161                     String JavaDoc ud = rs.getString(1);
162                     java.beans.XMLDecoder JavaDoc decoder = null;
163                     try {
164                       decoder = new java.beans.XMLDecoder JavaDoc(
165                                 new java.io.ByteArrayInputStream JavaDoc(ud.getBytes("UTF8")));
166                     } catch (UnsupportedEncodingException JavaDoc e) {
167                         error("Can not decode old UserDataVO: ", e);
168                     }
169                     se.anatom.ejbca.common.UserDataVO oldud = (se.anatom.ejbca.common.UserDataVO)decoder.readObject();
170                     decoder.close();
171                     // If we came this far, we have an old UserDataVO.
172
ret = true;
173                     error("(this is not an error) during pre-check successfully decoded old UserDataVO with username="+oldud.getUsername());
174                 } catch (Exception JavaDoc e) {
175                     error("Can not decode old UserDataVO: ", e);
176                 }
177             }
178         } catch (Exception JavaDoc e) {
179             error("Database error during preCheck: ", e);
180         } finally {
181             JDBCUtil.close(ps);
182             JDBCUtil.close(con);
183         }
184         debug("<preCheck("+ret+")");
185         return ret;
186     }
187
188     /** Upgrades the database
189      * @ejb.interface-method
190      * @jboss.method-attributes transaction-timeout="3600"
191      *
192      * @param admin
193      * @return true or false if upgrade was done or not
194      */

195     public boolean upgrade(Admin admin, String JavaDoc[] args) {
196         debug(">upgrade("+admin.toString()+")");
197         this.administrator = admin;
198         
199         String JavaDoc dbtype = null;
200         if (args.length > 0) {
201             dbtype = args[0];
202             debug("Database type="+dbtype);
203         }
204
205         boolean upgradefrom31 = false;
206         if (args.length > 1) {
207             String JavaDoc u = args[1];
208             if (StringUtils.equalsIgnoreCase(u, "yes")) {
209                 upgradefrom31 = true;
210             }
211         }
212
213         // Upgrade small database change between ejbca 3.3.x and 3.4.x
214
if (!migradeDatabase33(dbtype)) {
215             // Ignore errors and continue, perhaps we have already done this manually
216
// return false;
217
}
218
219         // If we are not upgrading from EJBCA 3.1.x we can stop here
220
if (!upgradefrom31) {
221             return true;
222         }
223         
224         if (!preCheck()) {
225             info("preCheck failed, no upgrade performed.");
226             return false;
227         }
228
229         if (!migradeDatabase31(dbtype)) {
230             return false;
231         }
232
233         if (!upgradeHardTokenClassPath()) {
234             return false;
235         }
236         if (!upgradeUserDataVO()) {
237             return false;
238         }
239         ArrayList JavaDoc datas = logConfStep1();
240         // If we got some datas, we have something to upgrade, otherwise we don't
241
if (datas != null) {
242             if (!logConfStep2(datas)) {
243                 return false;
244             }
245             if (!logConfStep3(datas)) {
246                 return false;
247             }
248         }
249         debug("<upgrade()");
250         return true;
251     }
252
253
254     /** Called from other migrate methods, don't call this directly, call from an interface-method
255      */

256     public boolean migradeDatabase(String JavaDoc resource) {
257         // Fetch the resource file with SQL to modify the database tables
258
InputStream JavaDoc in = this.getClass().getResourceAsStream(resource);
259         if (in == null) {
260             error("Can not read resource for database '"+resource+"', this database probably does not need table definition changes.");
261             // no error
262
return true;
263         }
264
265         // Migrate database tables to new columns etc
266
Connection JavaDoc con = null;
267         info("Start migration of database.");
268         try {
269             InputStreamReader JavaDoc inreader = new InputStreamReader JavaDoc(in);
270             con = JDBCUtil.getDBConnection(JNDINames.DATASOURCE);
271             SqlExecutor sqlex = new SqlExecutor(con, false);
272             sqlex.runCommands(inreader);
273         } catch (SQLException JavaDoc e) {
274             error("SQL error during database migration: ", e);
275             return false;
276         } catch (IOException JavaDoc e) {
277             error("IO error during database migration: ", e);
278             return false;
279         } finally {
280             JDBCUtil.close(con);
281         }
282         error("(this is not an error) Finished migrating database.");
283         return true;
284     }
285
286     /**
287      * @ejb.interface-method
288      * @jboss.method-attributes transaction-timeout="3600"
289      *
290      */

291     public boolean migradeDatabase31(String JavaDoc dbtype) {
292         error("(this is not an error) Starting upgrade from ejbca 3.1.x to ejbca 3.2.x");
293         boolean ret = migradeDatabase("/31_32/31_32-upgrade-"+dbtype+".sql");
294         error("(this is not an error) Finished migrating database.");
295         return ret;
296     }
297     /**
298      * @ejb.interface-method
299      * @jboss.method-attributes transaction-timeout="3600"
300      *
301      */

302     public boolean migradeDatabase33(String JavaDoc dbtype) {
303         error("(this is not an error) Starting upgrade from ejbca 3.3.x to ejbca 3.4.x");
304         boolean ret = migradeDatabase("/33_34/33_34-upgrade-"+dbtype+".sql");
305         error("(this is not an error) Finished migrating database.");
306         return ret;
307     }
308
309     /**
310      * @ejb.interface-method
311      * @jboss.method-attributes transaction-timeout="3600"
312      *
313      */

314     public boolean upgradeHardTokenClassPath() {
315         try {
316             ICAAdminSessionLocal casession = getCaAdminSession();
317             Collection JavaDoc caids = casession.getAvailableCAs(administrator);
318             Iterator JavaDoc iter = caids.iterator();
319             while (iter.hasNext()) {
320                 int caid = ((Integer JavaDoc) iter.next()).intValue();
321                 casession.upgradeFromOldCAHSMKeyStore(administrator, caid);
322             }
323         } catch (Exception JavaDoc e) {
324             error("Error upgrading hard token class path: ", e);
325             return false;
326         }
327         return true;
328     }
329
330     /**
331      * @ejb.interface-method
332      * @jboss.method-attributes transaction-timeout="3600"
333      *
334      */

335     public ArrayList JavaDoc logConfStep1() {
336         ArrayList JavaDoc datas = new ArrayList JavaDoc();
337         try {
338             Collection JavaDoc oldColl = oldLogHome.findAll();
339             Iterator JavaDoc it = oldColl.iterator();
340             while (it.hasNext()) {
341                 OldLogConfigurationDataLocal odata = (OldLogConfigurationDataLocal)it.next();
342                 LogConfData d = new LogConfData();
343                 d.id = odata.getId();
344                 d.data = odata.getLogConfiguration();
345                 d.row = odata.getLogEntryRowNumber();
346                 datas.add(d);
347             }
348             error("(this is not an error) read "+datas.size()+" old LogConfigurationData.");
349         } catch (Exception JavaDoc e) {
350             error("Error reading old LogConfigurationData: ", e);
351             return null;
352         }
353         return datas;
354     }
355
356     /**
357      * @ejb.interface-method
358      * @jboss.method-attributes transaction-timeout="3600"
359      *
360      */

361     public boolean logConfStep2(ArrayList JavaDoc datas) {
362         try {
363             Iterator JavaDoc it2 = datas.iterator();
364             while (it2.hasNext()) {
365                 LogConfData d = (LogConfData) it2.next();
366                 OldLogConfigurationDataLocal l = oldLogHome.findByPrimaryKey(d.id);
367                 oldLogHome.remove(l.getPrimaryKey());
368             }
369             error("(this is not an error) deleted old LogConfigurationData.");
370         } catch (Exception JavaDoc e) {
371             error("Failed to delete old LogConfigurationData");
372             return false;
373         }
374         return true;
375     }
376     /**
377      * @ejb.interface-method
378      * @jboss.method-attributes transaction-timeout="3600"
379      *
380      */

381     public boolean logConfStep3(ArrayList JavaDoc datas) {
382         try {
383             // Start creating the new ones
384
Iterator JavaDoc it2 = datas.iterator();
385             error("(this is not an error) Upgrading "+datas.size()+" LogConfigurationData.");
386             while (it2.hasNext()) {
387                 LogConfData d = (LogConfData)it2.next();
388                 se.anatom.ejbca.log.LogConfiguration logConf = d.data;
389                 org.ejbca.core.model.log.LogConfiguration newLog = new org.ejbca.core.model.log.LogConfiguration(
390                 logConf.useLogDB(), logConf.useExternalLogDevices(), logConf.getConfigurationData());
391                 logHome.create(d.id, newLog);
392                 LogConfigurationDataLocal dl = logHome.findByPrimaryKey(d.id);
393                 dl.setLogEntryRowNumber(d.row);
394             }
395             error("(this is not an error) Upgraded LogConfigurationData successfully.");
396         } catch (Exception JavaDoc e) {
397             error("Error upgrading LogConfigurationData: ", e);
398             return false;
399         }
400         return true;
401     }
402     
403     private boolean upgradeUserDataVO() {
404         PreparedStatement JavaDoc ps1 = null;
405         PreparedStatement JavaDoc ps2 = null;
406         Connection JavaDoc con = null;
407         int count = 0;
408         try {
409             con = JDBCUtil.getDBConnection(JNDINames.DATASOURCE);
410             ps1 = con.prepareStatement("select fingerprint,userDataVO from CertReqHistoryData");
411             ps2 = con.prepareStatement("update CertReqHistoryData set userDataVO=? where fingerprint=?");
412             ResultSet JavaDoc rs = ps1.executeQuery();
413             se.anatom.ejbca.common.UserDataVO oldud = null;
414             while (rs.next()) {
415                 boolean goon = true;
416                 String JavaDoc fp = rs.getString(1);
417                 String JavaDoc ud = rs.getString(2);
418                 try {
419                     java.beans.XMLDecoder JavaDoc decoder = null;
420                     try {
421                       decoder = new java.beans.XMLDecoder JavaDoc(
422                                 new java.io.ByteArrayInputStream JavaDoc(ud.getBytes("UTF8")));
423                     } catch (UnsupportedEncodingException JavaDoc e) {
424                         goon = false;
425                     }
426                     if (goon) {
427                         oldud = (se.anatom.ejbca.common.UserDataVO)decoder.readObject();
428                     }
429                     decoder.close();
430                 } catch (Exception JavaDoc e) {
431                     error("Can not decode old UserDataVO for fingerprint "+fp+": ", e);
432                     goon = false;
433                 }
434                 if (goon) {
435                     org.ejbca.core.model.ra.UserDataVO newud = createNewUserDataVO(oldud);
436                     ByteArrayOutputStream JavaDoc baos = null;
437                     try {
438                         baos = new java.io.ByteArrayOutputStream JavaDoc();
439                         java.beans.XMLEncoder JavaDoc encoder = new java.beans.XMLEncoder JavaDoc(baos);
440                         encoder.writeObject(newud);
441                         encoder.close();
442                         String JavaDoc newudstr = baos.toString("UTF8");
443                         ps2.setString(1, newudstr);
444                         ps2.setString(2, fp);
445                         ps2.executeUpdate();
446                         count ++;
447                     } catch (Exception JavaDoc e) {
448                         error("Can not create new UserDataVO for fingerprint "+fp+": ", e);
449                     } finally {
450                         try {
451                             if (baos != null) baos.close();
452                         } catch (Exception JavaDoc e) {}
453                     }
454                 }
455                 if ( (count % 1000) == 0) {
456                     error("(this is not an error) migrated "+count+" UserDataVO");
457                 }
458             }
459             //con.commit();
460
} catch (SQLException JavaDoc sqle) {
461             error("Error updating CertReqHistoryData: ", sqle);
462             return false;
463         } finally {
464             JDBCUtil.close(ps1);
465             JDBCUtil.close(ps2);
466             JDBCUtil.close(con);
467         }
468         error("(this is not an error) migrated "+count+" UserDataVO");
469         return true;
470     }
471     
472     private org.ejbca.core.model.ra.UserDataVO createNewUserDataVO(se.anatom.ejbca.common.UserDataVO old) {
473         org.ejbca.core.model.ra.UserDataVO ret = new org.ejbca.core.model.ra.UserDataVO(
474                 old.getUsername(), old.getDN(), old.getCAId(),
475                 old.getSubjectAltName(),old.getEmail(),old.getStatus(),
476                 old.getType(),old.getEndEntityProfileId(),old.getCertificateProfileId(),
477                 old.getTimeCreated(),old.getTimeModified(),old.getTokenType(),
478                 old.getHardTokenIssuerId(),old.getExtendedinformation()
479                 );
480         return ret;
481     }
482     /**
483      * Enum type to hold old logconfigurationdatalocal
484      *
485      */

486     private class LogConfData {
487         public Integer JavaDoc id;
488         public se.anatom.ejbca.log.LogConfiguration data;
489         public int row;
490     }
491 } // UpgradeSessionBean
492
Popular Tags