001: /*
002:
003: Derby - Class org.apache.derbyTesting.functionTests.store.OnlineBackup
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to You under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derbyTesting.functionTests.tests.store;
023:
024: import java.sql.Connection;
025: import java.sql.CallableStatement;
026: import java.sql.SQLException;
027: import org.apache.derbyTesting.functionTests.util.TestUtil;
028:
029: /**
030: * This class provides functionalty for tests to perform
031: * online backup in a separate thread. And functions to
032: * create/restore/rollforard recovery from the backup.
033: *
034: * @author <a href="mailto:suresh.thalamati@gmail.com">Suresh Thalamati</a>
035: * @version 1.0
036: */
037:
038: public class OnlineBackup implements Runnable {
039:
040: private String dbName; // name of the database to backup
041: private boolean beginBackup = false;
042: private boolean endBackup = false;
043: private boolean backupFailed = false;
044: private Throwable backupError = null;
045: private String backupPath;
046:
047: OnlineBackup(String dbName, String backupPath) {
048: this .dbName = dbName;
049: this .backupPath = backupPath;
050: }
051:
052: /**
053: * implementation of run() method in the Runnable interface, which
054: * is invoked when a thread is started using this class object.
055: *
056: * Performs online backup.
057: *
058: */
059: public void run() {
060: backupFailed = false;
061: try {
062: performBackup();
063: } catch (Throwable error) {
064: synchronized (this ) {
065: // inform threads that may be waiting for backup to
066: // start/end that it failed.
067: backupFailed = true;
068: backupError = error;
069: notifyAll();
070: }
071: org.apache.derby.tools.JDBCDisplayUtil.ShowException(
072: System.out, error);
073: error.printStackTrace(System.out);
074: }
075: }
076:
077: /**
078: * Backup the database
079: */
080: void performBackup() throws SQLException {
081: Connection conn = TestUtil.getConnection(dbName, "");
082: CallableStatement backupStmt = conn
083: .prepareCall("CALL SYSCS_UTIL.SYSCS_BACKUP_DATABASE(?)");
084: backupStmt.setString(1, backupPath);
085:
086: synchronized (this ) {
087: beginBackup = true;
088: endBackup = false;
089: notifyAll();
090: }
091:
092: backupStmt.execute();
093: backupStmt.close();
094: conn.close();
095:
096: synchronized (this ) {
097: beginBackup = false;
098: endBackup = true;
099: notifyAll();
100: }
101: }
102:
103: /**
104: * Wait for the backup to start.
105: */
106:
107: public void waitForBackupToBegin() throws Exception {
108: synchronized (this ) {
109: //wait for backup to begin
110: while (!beginBackup) {
111: // if the backup failed for some reason throw error, don't go
112: // into wait state.
113: if (backupFailed)
114: throw new Exception("BACKUP FAILED:"
115: + backupError.getMessage());
116: else
117: wait();
118: }
119: }
120: }
121:
122: /*
123: * Wait for the backup to finish.
124: */
125: public void waitForBackupToEnd() throws Exception {
126: synchronized (this ) {
127: if (!endBackup) {
128: // check if a backup has actually started by the test
129: if (!beginBackup) {
130: System.out
131: .println("BACKUP IS NOT STARTED BY THE TEST YET");
132: } else {
133:
134: //wait for backup to finish
135: while (!endBackup) {
136: // if the backup failed for some reason throw error, don't go
137: // into wait state.
138: if (backupFailed)
139: throw new Exception("BACKUP FAILED:"
140: + backupError.getMessage());
141: else
142: wait();
143: }
144: }
145: }
146:
147: }
148: }
149:
150: /**
151: * Check if backup is running ?
152: * @return <tt>true</tt> if backup is running.
153: * <tt>false</tt> otherwise.
154: */
155: public synchronized boolean isRunning() {
156: return beginBackup;
157: }
158:
159: /**
160: * Create a new database from the backup copy taken earlier.
161: * @param newDbName name of the database to be created.
162: */
163: public void createFromBackup(String newDbName) throws SQLException {
164:
165: Connection conn = TestUtil.getConnection(newDbName,
166: "createFrom=" + backupPath + "/" + dbName);
167: conn.close();
168:
169: }
170:
171: /**
172: * Restore the database from the backup copy taken earlier.
173: */
174: public void restoreFromBackup() throws SQLException {
175:
176: Connection conn = TestUtil.getConnection(dbName, "restoreFrom="
177: + backupPath + "/" + dbName);
178:
179: conn.close();
180: }
181: }
|