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