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 2006-2010 Sun Microsystems, Inc. 015 * Portions copyright 2013-2014 ForgeRock AS. 016 */ 017package org.opends.server.replication.protocol; 018 019import java.util.zip.DataFormatException; 020 021/** 022 * Abstract class that must be used when defining messages that can 023 * be sent for replication purpose between servers. 024 * 025 * When extending this class one should also create a new MSG_TYPE 026 * and should update the generateMsg() method. 027 */ 028public abstract class ReplicationMsg 029{ 030 // PDU type values kept for compatibility with replication protocol version 1 031 static final byte MSG_TYPE_MODIFY_V1 = 1; 032 static final byte MSG_TYPE_ADD_V1 = 2; 033 static final byte MSG_TYPE_DELETE_V1 = 3; 034 static final byte MSG_TYPE_MODIFYDN_V1 = 4; 035 static final byte MSG_TYPE_SERVER_START_V1 = 6; 036 static final byte MSG_TYPE_REPL_SERVER_START_V1 = 7; 037 static final byte MSG_TYPE_REPL_SERVER_INFO_V1 = 16; 038 039 // PDU type values for current protocol version (see ProtocolVersion) 040 static final byte MSG_TYPE_ACK = 5; 041 static final byte MSG_TYPE_WINDOW = 8; 042 static final byte MSG_TYPE_HEARTBEAT = 9; 043 static final byte MSG_TYPE_INITIALIZE_REQUEST = 10; 044 static final byte MSG_TYPE_INITIALIZE_TARGET = 11; 045 static final byte MSG_TYPE_ENTRY = 12; 046 static final byte MSG_TYPE_DONE = 13; 047 static final byte MSG_TYPE_ERROR = 14; 048 static final byte MSG_TYPE_WINDOW_PROBE = 15; 049 static final byte MSG_TYPE_RESET_GENERATION_ID = 17; 050 static final byte MSG_TYPE_REPL_SERVER_MONITOR_REQUEST = 18; 051 static final byte MSG_TYPE_REPL_SERVER_MONITOR = 19; 052 static final byte MSG_TYPE_SERVER_START = 20; 053 static final byte MSG_TYPE_REPL_SERVER_START = 21; 054 static final byte MSG_TYPE_MODIFY = 22; 055 static final byte MSG_TYPE_ADD = 23; 056 static final byte MSG_TYPE_DELETE = 24; 057 static final byte MSG_TYPE_MODIFYDN = 25; 058 static final byte MSG_TYPE_TOPOLOGY = 26; 059 static final byte MSG_TYPE_START_SESSION = 27; 060 static final byte MSG_TYPE_CHANGE_STATUS = 28; 061 static final byte MSG_TYPE_GENERIC_UPDATE = 29; 062 063 // Added for protocol version 3 064 @Deprecated 065 static final byte MSG_TYPE_START_ECL = 30; 066 @Deprecated 067 static final byte MSG_TYPE_START_ECL_SESSION = 31; 068 @Deprecated 069 static final byte MSG_TYPE_ECL_UPDATE = 32; 070 static final byte MSG_TYPE_CT_HEARTBEAT = 33; 071 072 // Added for protocol version 4 073 // - New msgs types 074 static final byte MSG_TYPE_REPL_SERVER_START_DS = 34; 075 static final byte MSG_TYPE_STOP = 35; 076 static final byte MSG_TYPE_INITIALIZE_RCV_ACK = 36; 077 // - Modified msgs types 078 // EntryMsg, InitializeRequestMsg, InitializeTargetMsg, ErrorMsg 079 // TopologyMsg 080 081 /** @since {@link ProtocolVersion#REPLICATION_PROTOCOL_V8} */ 082 static final byte MSG_TYPE_REPLICA_OFFLINE = 37; 083 084 // Adding a new type of message here probably requires to 085 // change accordingly generateMsg method below 086 087 /** 088 * Protected constructor. 089 */ 090 protected ReplicationMsg() 091 { 092 // Nothing to do. 093 } 094 095 /** 096 * Serializes the PDU using the provided replication protocol version. 097 * WARNING: should be overwritten by a PDU (sub class) we want to support 098 * older protocol version serialization for. 099 * 100 * @param protocolVersion 101 * The protocol version to use for serialization. The version should 102 * normally be older than the current one. 103 * @return The encoded PDU, or <code>null</code> if the message isn't supported 104 * in that protocol version. 105 */ 106 public abstract byte[] getBytes(short protocolVersion); 107 108 /** 109 * Generates a ReplicationMsg from its encoded form. This un-serialization is 110 * done taking into account the various supported replication protocol 111 * versions. 112 * 113 * @param buffer 114 * The encode form of the ReplicationMsg. 115 * @param protocolVersion 116 * The version to use to decode the msg. 117 * @return The generated SynchronizationMessage. 118 * @throws DataFormatException 119 * If the encoded form was not a valid msg. 120 * @throws NotSupportedOldVersionPDUException 121 * If the PDU is part of an old protocol version and we do not 122 * support it. 123 */ 124 public static ReplicationMsg generateMsg(byte[] buffer, short protocolVersion) 125 throws DataFormatException, NotSupportedOldVersionPDUException 126 { 127 switch (buffer[0]) 128 { 129 case MSG_TYPE_SERVER_START_V1: 130 throw new NotSupportedOldVersionPDUException("Server Start", 131 ProtocolVersion.REPLICATION_PROTOCOL_V1, buffer[0]); 132 case MSG_TYPE_REPL_SERVER_INFO_V1: 133 throw new NotSupportedOldVersionPDUException("Replication Server Info", 134 ProtocolVersion.REPLICATION_PROTOCOL_V1, buffer[0]); 135 case MSG_TYPE_MODIFY: 136 return new ModifyMsg(buffer); 137 case MSG_TYPE_MODIFY_V1: 138 return ModifyMsg.createV1(buffer); 139 case MSG_TYPE_ADD: 140 case MSG_TYPE_ADD_V1: 141 return new AddMsg(buffer); 142 case MSG_TYPE_DELETE: 143 case MSG_TYPE_DELETE_V1: 144 return new DeleteMsg(buffer); 145 case MSG_TYPE_MODIFYDN: 146 case MSG_TYPE_MODIFYDN_V1: 147 return new ModifyDNMsg(buffer); 148 case MSG_TYPE_ACK: 149 return new AckMsg(buffer); 150 case MSG_TYPE_SERVER_START: 151 return new ServerStartMsg(buffer); 152 case MSG_TYPE_REPL_SERVER_START: 153 case MSG_TYPE_REPL_SERVER_START_V1: 154 return new ReplServerStartMsg(buffer); 155 case MSG_TYPE_WINDOW: 156 return new WindowMsg(buffer); 157 case MSG_TYPE_HEARTBEAT: 158 return new HeartbeatMsg(buffer); 159 case MSG_TYPE_INITIALIZE_REQUEST: 160 return new InitializeRequestMsg(buffer, protocolVersion); 161 case MSG_TYPE_INITIALIZE_TARGET: 162 return new InitializeTargetMsg(buffer, protocolVersion); 163 case MSG_TYPE_ENTRY: 164 return new EntryMsg(buffer, protocolVersion); 165 case MSG_TYPE_DONE: 166 return new DoneMsg(buffer); 167 case MSG_TYPE_ERROR: 168 return new ErrorMsg(buffer, protocolVersion); 169 case MSG_TYPE_RESET_GENERATION_ID: 170 return new ResetGenerationIdMsg(buffer); 171 case MSG_TYPE_WINDOW_PROBE: 172 return new WindowProbeMsg(buffer); 173 case MSG_TYPE_TOPOLOGY: 174 return new TopologyMsg(buffer, protocolVersion); 175 case MSG_TYPE_REPL_SERVER_MONITOR_REQUEST: 176 return new MonitorRequestMsg(buffer); 177 case MSG_TYPE_REPL_SERVER_MONITOR: 178 return new MonitorMsg(buffer, protocolVersion); 179 case MSG_TYPE_START_SESSION: 180 return new StartSessionMsg(buffer, protocolVersion); 181 case MSG_TYPE_CHANGE_STATUS: 182 return new ChangeStatusMsg(buffer); 183 case MSG_TYPE_GENERIC_UPDATE: 184 return new UpdateMsg(buffer); 185 case MSG_TYPE_START_ECL: 186 case MSG_TYPE_START_ECL_SESSION: 187 case MSG_TYPE_ECL_UPDATE: 188 // Legacy versions never sent such messages to other instances (other JVMs). 189 // They were only used in the combined DS-RS case. 190 // It is safe to totally ignore these values since code now uses the ChangelogBackend. 191 return null; 192 case MSG_TYPE_CT_HEARTBEAT: 193 return new ChangeTimeHeartbeatMsg(buffer, protocolVersion); 194 case MSG_TYPE_REPL_SERVER_START_DS: 195 return new ReplServerStartDSMsg(buffer); 196 case MSG_TYPE_STOP: 197 return new StopMsg(buffer); 198 case MSG_TYPE_INITIALIZE_RCV_ACK: 199 return new InitializeRcvAckMsg(buffer); 200 case MSG_TYPE_REPLICA_OFFLINE: 201 return new ReplicaOfflineMsg(buffer); 202 default: 203 throw new DataFormatException("received message with unknown type"); 204 } 205 } 206}