001: /**
002: * Sequoia: Database clustering technology.
003: * Copyright (C) 2005 AmicoSoft, Inc. dba Emic Networks
004: * Copyright (C) 2005-2006 Continuent, Inc.
005: * Contact: sequoia@continuent.org
006: *
007: * Licensed under the Apache License, Version 2.0 (the "License");
008: * you may not use this file except in compliance with the License.
009: * You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: *
019: * Initial developer(s): Olivier Fambon.
020: * Contributor(s): Emmanuel Cecchet.
021: */package org.continuent.sequoia.controller.virtualdatabase.protocol;
022:
023: import java.io.Serializable;
024: import java.sql.SQLException;
025:
026: import org.continuent.hedera.common.Member;
027: import org.continuent.sequoia.common.exceptions.ControllerException;
028: import org.continuent.sequoia.common.exceptions.VirtualDatabaseException;
029: import org.continuent.sequoia.controller.virtualdatabase.DistributedVirtualDatabase;
030:
031: /**
032: * This message is used both to prepare the sending of a set of log entries to a
033: * remote controller's vdb recovery log (intialization) and to terminate it
034: * (termination). Initialization is the second step of the process to rebuild
035: * the remote recovery log from a live one, termination is the final step of the
036: * process. The process is as such so that eventually the remote vdb backends
037: * can be restored from dumps. Upon reception of this message for the
038: * initialisation phase (identified by a null dumpCheckpointName), the remote
039: * recovery log is cleared from the beginning upto the 'now' checkpoint.
040: * Subsequently, CopyLogEntry messages are sent and log entries are inserted 'as
041: * are' into the remote recovery log. Then, upon reception of this message for
042: * the termination phase (non-null dumpCheckpointName), the remote recovery log
043: * makes the dumpCheckpointName available for restore operations.
044: *
045: * @see CopyLogEntry
046: * @author <a href="mailto:Olivier.Fambon@emicnetworks.com>Olivier Fambon </a>
047: * @author <a href="mailto:emmanuel.cecchet@continuent.com">Emmanuel Cecchet</a>
048: * @version 1.0
049: */
050: public class ReplicateLogEntries extends
051: DistributedVirtualDatabaseMessage {
052: private static final long serialVersionUID = -2813776509468770586L;
053:
054: private String checkpointName;
055: private String dumpCheckpointName;
056: private long checkpointId;
057: private String dumpName;
058:
059: /**
060: * Creates a new <code>ReplicateLogEntries</code> message
061: *
062: * @param checkpointName The checkpoint (aka now checkpoint) before wich
063: * entries are to be replaced.
064: * @param dumpCheckpointName The dump checkoint from which entries are to be
065: * replaced. If this one is null, the recovery log is reset.
066: * @param dumpName the name of the dump associated to dumpCheckpointName.
067: * @param checkpointId The id associated to checkpoint THIS ID SHOULD BE
068: * HIDDEN
069: */
070: public ReplicateLogEntries(String checkpointName,
071: String dumpCheckpointName, String dumpName,
072: long checkpointId) {
073: this .dumpCheckpointName = dumpCheckpointName;
074: this .checkpointName = checkpointName;
075: this .checkpointId = checkpointId;
076: this .dumpName = dumpName;
077: }
078:
079: /**
080: * Returns the checkpointName value.
081: *
082: * @return Returns the 'now' checkpointName.
083: */
084: public String getCheckpointName() {
085: return checkpointName;
086: }
087:
088: /**
089: * Returns the dump checkpoint name .
090: *
091: * @return Returns the dump CheckpointName.
092: */
093: public String getDumpCheckpointName() {
094: return dumpCheckpointName;
095: }
096:
097: /**
098: * Returns the Checkpoint id.
099: *
100: * @return the Checkpoint id
101: */
102: public long getCheckpointId() {
103: return checkpointId;
104: }
105:
106: void performSanityChecks(DistributedVirtualDatabase dvdb)
107: throws VirtualDatabaseException, SQLException {
108: if (!dvdb.hasRecoveryLog()) {
109: String errorMessage = "Tentative handleReplicateLogEntries on vdb with no recovery log";
110: throw new VirtualDatabaseException(errorMessage);
111: }
112:
113: if (dvdb.getRecoveryLog().getDumpInfo(dumpName) == null)
114: throw new VirtualDatabaseException("Invalid dump name: "
115: + dumpName);
116: }
117:
118: void performInitializationPhase(DistributedVirtualDatabase dvdb)
119: throws SQLException {
120: dvdb.getRequestManager().getRecoveryLog()
121: .resetLogTableIdAndDeleteRecoveryLog(checkpointName,
122: checkpointId);
123: }
124:
125: void performTerminationPhase(DistributedVirtualDatabase dvdb)
126: throws SQLException, VirtualDatabaseException {
127: // 1: store dump checkpoint name in the checkpoints table
128: dvdb.getRequestManager().getRecoveryLog()
129: .storeDumpCheckpointName(dumpCheckpointName,
130: checkpointId);
131: // (should this one be synchronous ?)
132:
133: // 2: update the dump table with it, and make the dump valid for restore
134: dvdb.getRecoveryLog().updateDumpCheckpoint(dumpName,
135: dumpCheckpointName);
136:
137: // 3: update global counters based on new log
138: dvdb.initGlobalCounters(dvdb.getControllerId());
139: }
140:
141: /**
142: * @see org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedVirtualDatabaseMessage#handleMessageSingleThreaded(org.continuent.sequoia.controller.virtualdatabase.DistributedVirtualDatabase,
143: * org.continuent.hedera.common.Member)
144: */
145: public Object handleMessageSingleThreaded(
146: DistributedVirtualDatabase dvdb, Member sender) {
147: try {
148: // Note: with this test placed here, the check is performed both at
149: // initialization and at completion.
150: performSanityChecks(dvdb);
151:
152: if (dumpCheckpointName == null)
153: performInitializationPhase(dvdb);
154: else
155: performTerminationPhase(dvdb);
156:
157: } catch (Exception e) {
158: dvdb.getLogger().warn(e);
159: return new ControllerException(e);
160: }
161:
162: return null;
163: }
164:
165: /**
166: * @see org.continuent.sequoia.controller.virtualdatabase.protocol.DistributedVirtualDatabaseMessage#handleMessageMultiThreaded(org.continuent.sequoia.controller.virtualdatabase.DistributedVirtualDatabase,
167: * org.continuent.hedera.common.Member, java.lang.Object)
168: */
169: public Serializable handleMessageMultiThreaded(
170: DistributedVirtualDatabase dvdb, Member sender,
171: Object handleMessageSingleThreadedResult) {
172: return (Serializable) handleMessageSingleThreadedResult;
173: }
174: }
|