KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > jdbc > support > DatabaseStartupValidator


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.jdbc.support;
18
19 import java.sql.Connection JavaDoc;
20 import java.sql.SQLException JavaDoc;
21 import java.sql.Statement JavaDoc;
22
23 import javax.sql.DataSource JavaDoc;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 import org.springframework.beans.factory.InitializingBean;
29 import org.springframework.jdbc.CannotGetJdbcConnectionException;
30
31 /**
32  * Bean that checks if a database has already started up. To be referenced
33  * via "depends-on" from beans that depend on database startup, like a Hibernate
34  * SessionFactory or custom data access objects that access a DataSource directly.
35  *
36  * <p>Useful to defer application initialization until a database has started up.
37  * Particularly appropriate for waiting on a slowly starting Oracle database.
38  *
39  * @author Juergen Hoeller
40  * @since 18.12.2003
41  */

42 public class DatabaseStartupValidator implements InitializingBean {
43
44     public static final int DEFAULT_INTERVAL = 1;
45
46     public static final int DEFAULT_TIMEOUT = 60;
47
48
49     protected final Log logger = LogFactory.getLog(getClass());
50
51     private DataSource JavaDoc dataSource;
52
53     private String JavaDoc validationQuery;
54
55     private int interval = DEFAULT_INTERVAL;
56
57     private int timeout = DEFAULT_TIMEOUT;
58
59
60     /**
61      * Set the DataSource to validate.
62      */

63     public void setDataSource(DataSource JavaDoc dataSource) {
64         this.dataSource = dataSource;
65     }
66
67     /**
68      * Set the SQL query string to use for validation.
69      */

70     public void setValidationQuery(String JavaDoc validationQuery) {
71         this.validationQuery = validationQuery;
72     }
73
74     /**
75      * Set the interval between validation runs (in seconds).
76      * Default is 1.
77      */

78     public void setInterval(int interval) {
79         this.interval = interval;
80     }
81
82     /**
83      * Set the timeout (in seconds) after which a fatal exception
84      * will be thrown. Default is 60.
85      */

86     public void setTimeout(int timeout) {
87         this.timeout = timeout;
88     }
89
90
91     /**
92      * Check whether the validation query can be executed on a Connection
93      * from the specified DataSource, with the specified interval between
94      * checks, until the specified timeout.
95      */

96     public void afterPropertiesSet() {
97         if (this.dataSource == null) {
98             throw new IllegalArgumentException JavaDoc("dataSource is required");
99         }
100         if (this.validationQuery == null) {
101             throw new IllegalArgumentException JavaDoc("validationQuery is required");
102         }
103
104         boolean validated = false;
105         long beginTime = System.currentTimeMillis();
106         long deadLine = beginTime + this.timeout * 1000;
107         SQLException JavaDoc latestEx = null;
108
109         while (!validated && System.currentTimeMillis() < deadLine) {
110             Connection JavaDoc con = null;
111             Statement JavaDoc stmt = null;
112             try {
113                 con = this.dataSource.getConnection();
114                 stmt = con.createStatement();
115                 stmt.execute(this.validationQuery);
116                 validated = true;
117             }
118             catch (SQLException JavaDoc ex) {
119                 latestEx = ex;
120                 logger.debug("Validation query [" + this.validationQuery + "] threw exception", ex);
121                 float rest = ((float) (deadLine - System.currentTimeMillis())) / 1000;
122                 if (rest > this.interval) {
123                     logger.warn("Database has not started up yet - retrying in " + this.interval +
124                                             " seconds (timeout in " + rest + " seconds)");
125                 }
126             }
127             finally {
128                 JdbcUtils.closeStatement(stmt);
129                 JdbcUtils.closeConnection(con);
130             }
131
132             try {
133                 Thread.sleep(this.interval * 1000);
134             }
135             catch (InterruptedException JavaDoc ex) {
136                 // Re-interrupt current thread, to allow other threads to react.
137
Thread.currentThread().interrupt();
138             }
139         }
140
141         if (validated) {
142             float duration = (System.currentTimeMillis() - beginTime) / 1000;
143             if (logger.isInfoEnabled()) {
144                 logger.info("Database startup detected after " + duration + " seconds");
145             }
146         }
147         else {
148             throw new CannotGetJdbcConnectionException(
149                     "Database has not started up within " + this.timeout + " seconds", latestEx);
150         }
151     }
152
153 }
154
Popular Tags