001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2013-2016 ForgeRock AS. 015 */ 016package org.opends.server.replication.server.changelog.api; 017 018import java.util.Set; 019 020import org.opends.server.replication.common.CSN; 021import org.opends.server.replication.common.MultiDomainServerState; 022import org.opends.server.replication.common.ServerState; 023import org.opends.server.replication.protocol.UpdateMsg; 024import org.opends.server.replication.server.changelog.api.DBCursor.CursorOptions; 025import org.opends.server.replication.server.changelog.file.MultiDomainDBCursor; 026import org.forgerock.opendj.ldap.DN; 027 028/** 029 * This interface allows to query or control the replication domain database(s) 030 * (composed of one or more ReplicaDBs) and query/update each ReplicaDB. 031 * <p> 032 * In particular, the {@code getCursorFom()} methods allow to obtain a cursor at any level: 033 * <ul> 034 * <li>Across all the domains, provided a {@link MultiDomainServerState}</li> 035 * <li>Across all replicaDBs of a domain, provided a {@link ServerState}</li> 036 * <li>On one replica DB for a domain and serverId, provided a CSN</li> 037 * </ul> 038 * The cursor starting point is specified by providing a key, a {@link KeyMatchingStrategy} and 039 * a {@link PositionStrategy}. 040 */ 041public interface ReplicationDomainDB 042{ 043 044 /** 045 * Returns the oldest {@link CSN}s from the replicaDBs for each serverId in 046 * the specified replication domain. 047 * 048 * @param baseDN 049 * the replication domain baseDN 050 * @return a new ServerState object holding the {serverId => oldest CSN} 051 * mapping. If a replica DB is empty or closed, the oldest CSN will be 052 * null for that replica. The caller owns the generated ServerState. 053 */ 054 ServerState getDomainOldestCSNs(DN baseDN); 055 056 /** 057 * Returns the newest {@link CSN}s from the replicaDBs for each serverId in 058 * the specified replication domain. 059 * 060 * @param baseDN 061 * the replication domain baseDN 062 * @return a new ServerState object holding the {serverId => newest CSN} Map. 063 * If a replica DB is empty or closed, the newest CSN will be null for 064 * that replica. The caller owns the generated ServerState. 065 */ 066 ServerState getDomainNewestCSNs(DN baseDN); 067 068 /** 069 * Removes all the data relating to the specified replication domain and 070 * shutdown all its replica databases. In particular, it will: 071 * <ol> 072 * <li>remove all the changes from the replica databases</li> 073 * <li>remove all knowledge of the serverIds in this domain</li> 074 * <li>remove any knowledge of the current generationId for this domain</li> 075 * </ol> 076 * 077 * @param baseDN 078 * the replication domain baseDN 079 * @throws ChangelogException 080 * If a database problem happened 081 */ 082 void removeDomain(DN baseDN) throws ChangelogException; 083 084 /** 085 * Generates a {@link DBCursor} across all the domains starting before, at or 086 * after the provided {@link MultiDomainServerState} for each domain, 087 * depending on the provided matching and positioning strategies. 088 * <p> 089 * When the cursor is not used anymore, client code MUST call the 090 * {@link DBCursor#close()} method to free the resources and locks used by the 091 * cursor. 092 * 093 * @param startState 094 * Starting point for each domain cursor. If any {@link ServerState} 095 * for a domain is null, then start from the oldest CSN for each 096 * replicaDBs 097 * @param options The cursor options 098 * @return a non null {@link DBCursor} 099 * @throws ChangelogException 100 * If a database problem happened 101 * @see #getCursorFrom(DN, ServerState, CursorOptions) 102 */ 103 MultiDomainDBCursor getCursorFrom(MultiDomainServerState startState, CursorOptions options) throws ChangelogException; 104 105 /** 106 * Generates a {@link DBCursor} across all the domains starting before, at or 107 * after the provided {@link MultiDomainServerState} for each domain, 108 * excluding a provided set of domain DNs. 109 * <p> 110 * When the cursor is not used anymore, client code MUST call the 111 * {@link DBCursor#close()} method to free the resources and locks used by the 112 * cursor. 113 * 114 * @param startState 115 * Starting point for each domain cursor. If any {@link ServerState} 116 * for a domain is null, then start from the oldest CSN for each 117 * replicaDBs 118 * @param options The cursor options 119 * @param excludedDomainDns 120 * Every domain appearing in this set is excluded from the cursor 121 * @return a non null {@link DBCursor} 122 * @throws ChangelogException 123 * If a database problem happened 124 * @see #getCursorFrom(DN, ServerState, CursorOptions) 125 */ 126 MultiDomainDBCursor getCursorFrom(MultiDomainServerState startState, CursorOptions options, Set<DN> excludedDomainDns) 127 throws ChangelogException; 128 129 /** 130 * Generates a {@link DBCursor} across all the replicaDBs for the specified 131 * replication domain starting before, at or after the provided 132 * {@link ServerState} for each replicaDB, depending on the provided matching 133 * and positioning strategies. 134 * <p> 135 * When the cursor is not used anymore, client code MUST call the 136 * {@link DBCursor#close()} method to free the resources and locks used by the 137 * cursor. 138 * 139 * @param baseDN 140 * the replication domain baseDN 141 * @param startState 142 * Starting point for each ReplicaDB cursor. If any CSN for a 143 * replicaDB is null, then start from the oldest CSN for this 144 * replicaDB 145 * @param options The cursor options 146 * @return a non null {@link DBCursor} 147 * @throws ChangelogException 148 * If a database problem happened 149 * @see #getCursorFrom(DN, int, CSN, CursorOptions) 150 */ 151 DBCursor<UpdateMsg> getCursorFrom(DN baseDN, ServerState startState, CursorOptions options) throws ChangelogException; 152 153 /** 154 * Generates a {@link DBCursor} for one replicaDB for the specified 155 * replication domain and serverId starting before, at or after the provided 156 * {@link CSN}, depending on the provided matching and positioning strategies. 157 * <p> 158 * When the cursor is not used anymore, client code MUST call the 159 * {@link DBCursor#close()} method to free the resources and locks used by the 160 * cursor. 161 * 162 * @param baseDN 163 * the replication domain baseDN of the replicaDB 164 * @param serverId 165 * the serverId of the replicaDB 166 * @param startCSN 167 * Starting point for the ReplicaDB cursor. If the CSN is null, then 168 * start from the oldest CSN for this replicaDB 169 * @param options The cursor options 170 * @return a non null {@link DBCursor} 171 * @throws ChangelogException 172 * If a database problem happened 173 */ 174 DBCursor<UpdateMsg> getCursorFrom(DN baseDN, int serverId, CSN startCSN, CursorOptions options) 175 throws ChangelogException; 176 177 /** 178 * Unregisters the provided cursor from this replication domain. 179 * 180 * @param cursor 181 * the cursor to unregister. 182 */ 183 void unregisterCursor(DBCursor<?> cursor); 184 185 /** 186 * Publishes the provided change to the changelog DB for the specified 187 * serverId and replication domain. After a change has been successfully 188 * published, it becomes available to be returned by the External ChangeLog. 189 * 190 * @param baseDN 191 * the replication domain baseDN 192 * @param updateMsg 193 * the update message to publish to the replicaDB 194 * @return true if a db had to be created to publish this message 195 * @throws ChangelogException 196 * If a database problem happened 197 */ 198 boolean publishUpdateMsg(DN baseDN, UpdateMsg updateMsg) 199 throws ChangelogException; 200 201 /** 202 * Let the DB know this replica is alive. 203 * <p> 204 * This method allows the medium consistency point to move forward in case 205 * this replica did not publish new changes. 206 * 207 * @param baseDN 208 * the replication domain baseDN 209 * @param heartbeatCSN 210 * The CSN heartbeat sent by this replica (contains the serverId and 211 * timestamp of the heartbeat) 212 * @throws ChangelogException 213 * If a database problem happened 214 */ 215 void replicaHeartbeat(DN baseDN, CSN heartbeatCSN) throws ChangelogException; 216 217 /** 218 * Let the DB know this replica is going down. 219 * <p> 220 * This method allows to let the medium consistency point move forward while 221 * this replica is offline. 222 * <p> 223 * Note: This method must not be called to let the DB know the replica is not 224 * sending heartbeats anymore, i.e. it must not be used in case of suspected 225 * network partition. 226 * 227 * @param baseDN 228 * the replication domain baseDN 229 * @param offlineCSN 230 * The CSN (serverId and timestamp) for the replica's going offline 231 * @throws ChangelogException 232 * If a database problem happened 233 */ 234 void notifyReplicaOffline(DN baseDN, CSN offlineCSN) throws ChangelogException; 235}