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