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 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.replication.protocol; 028 029 import java.io.UnsupportedEncodingException; 030 import java.util.zip.DataFormatException; 031 032 /** 033 * Abstract class that must be used when defining messages that can 034 * be sent for replication purpose between servers. 035 * 036 * When extending this class one should also create a new MSG_TYPE 037 * and should update the generateMsg() method. 038 */ 039 public abstract class ReplicationMessage 040 { 041 static final byte MSG_TYPE_MODIFY_REQUEST = 1; 042 static final byte MSG_TYPE_ADD_REQUEST = 2; 043 static final byte MSG_TYPE_DELETE_REQUEST = 3; 044 static final byte MSG_TYPE_MODIFYDN_REQUEST = 4; 045 static final byte MSG_TYPE_ACK = 5; 046 static final byte MSG_TYPE_SERVER_START = 6; 047 static final byte MSG_TYPE_REPL_SERVER_START = 7; 048 static final byte MSG_TYPE_WINDOW = 8; 049 static final byte MSG_TYPE_HEARTBEAT = 9; 050 static final byte MSG_TYPE_INITIALIZE_REQUEST = 10; 051 static final byte MSG_TYPE_INITIALIZE_TARGET = 11; 052 static final byte MSG_TYPE_ENTRY = 12; 053 static final byte MSG_TYPE_DONE = 13; 054 static final byte MSG_TYPE_ERROR = 14; 055 static final byte MSG_TYPE_WINDOW_PROBE = 15; 056 static final byte MSG_TYPE_REPL_SERVER_INFO = 16; 057 static final byte MSG_TYPE_RESET_GENERATION_ID = 17; 058 static final byte MSG_TYPE_REPL_SERVER_MONITOR_REQUEST = 18; 059 static final byte MSG_TYPE_REPL_SERVER_MONITOR = 19; 060 061 // Adding a new type of message here probably requires to 062 // change accordingly generateMsg method below 063 064 /** 065 * Return the byte[] representation of this message. 066 * Depending on the message type, the first byte of the byte[] must be. 067 * MSG_TYPE_MODIFY_REQUEST 068 * MSG_TYPE_ADD_REQUEST 069 * MSG_TYPE_DELETE_REQUEST 070 * MSG_TYPE_MODIFY_DN_REQUEST 071 * MSG_TYPE_ACK 072 * MSG_TYPE_SERVER_START 073 * MSG_TYPE_REPL_SERVER_START 074 * MSG_TYPE_WINDOW 075 * MSG_TYPE_HEARTBEAT 076 * MSG_TYPE_INITIALIZE 077 * MSG_TYPE_INITIALIZE_TARGET 078 * MSG_TYPE_ENTRY 079 * MSG_TYPE_DONE 080 * MSG_TYPE_ERROR 081 * MSG_TYPE_WINDOW_PROBE 082 * MSG_TYPE_REPL_SERVER_INFO 083 * MSG_TYPE_RESET_GENERATION_ID 084 * MSG_TYPE_REPL_SERVER_MONITOR_REQUEST 085 * MSG_TYPE_REPL_SERVER_MONITOR 086 * 087 * @return the byte[] representation of this message. 088 * @throws UnsupportedEncodingException When the encoding of the message 089 * failed because the UTF-8 encoding is not supported. 090 */ 091 public abstract byte[] getBytes() throws UnsupportedEncodingException; 092 093 094 /** 095 * Generates a ReplicationMessage from its encoded form. 096 * 097 * @param buffer The encode form of the ReplicationMessage. 098 * @return the generated SycnhronizationMessage. 099 * @throws DataFormatException if the encoded form was not a valid msg. 100 * @throws UnsupportedEncodingException if UTF8 is not supported. 101 */ 102 public static ReplicationMessage generateMsg(byte[] buffer) 103 throws DataFormatException, UnsupportedEncodingException 104 { 105 ReplicationMessage msg = null; 106 switch (buffer[0]) 107 { 108 case MSG_TYPE_MODIFY_REQUEST: 109 msg = new ModifyMsg(buffer); 110 break; 111 case MSG_TYPE_ADD_REQUEST: 112 msg = new AddMsg(buffer); 113 break; 114 case MSG_TYPE_DELETE_REQUEST: 115 msg = new DeleteMsg(buffer); 116 break; 117 case MSG_TYPE_MODIFYDN_REQUEST: 118 msg = new ModifyDNMsg(buffer); 119 break; 120 case MSG_TYPE_ACK: 121 msg = new AckMessage(buffer); 122 break; 123 case MSG_TYPE_SERVER_START: 124 msg = new ServerStartMessage(buffer); 125 break; 126 case MSG_TYPE_REPL_SERVER_START: 127 msg = new ReplServerStartMessage(buffer); 128 break; 129 case MSG_TYPE_WINDOW: 130 msg = new WindowMessage(buffer); 131 break; 132 case MSG_TYPE_HEARTBEAT: 133 msg = new HeartbeatMessage(buffer); 134 break; 135 case MSG_TYPE_INITIALIZE_REQUEST: 136 msg = new InitializeRequestMessage(buffer); 137 break; 138 case MSG_TYPE_INITIALIZE_TARGET: 139 msg = new InitializeTargetMessage(buffer); 140 break; 141 case MSG_TYPE_ENTRY: 142 msg = new EntryMessage(buffer); 143 break; 144 case MSG_TYPE_DONE: 145 msg = new DoneMessage(buffer); 146 break; 147 case MSG_TYPE_ERROR: 148 msg = new ErrorMessage(buffer); 149 break; 150 case MSG_TYPE_RESET_GENERATION_ID: 151 msg = new ResetGenerationId(buffer); 152 break; 153 case MSG_TYPE_WINDOW_PROBE: 154 msg = new WindowProbe(buffer); 155 break; 156 case MSG_TYPE_REPL_SERVER_INFO: 157 msg = new ReplServerInfoMessage(buffer); 158 break; 159 case MSG_TYPE_REPL_SERVER_MONITOR_REQUEST: 160 msg = new MonitorRequestMessage(buffer); 161 break; 162 case MSG_TYPE_REPL_SERVER_MONITOR: 163 msg = new MonitorMessage(buffer); 164 break; 165 default: 166 throw new DataFormatException("received message with unknown type"); 167 } 168 return msg; 169 } 170 171 /** 172 * Concatenate the tail byte array into the resultByteArray. 173 * The resultByteArray must be large enough before calling this method. 174 * 175 * @param tail the byte array to concatenate. 176 * @param resultByteArray The byte array to concatenate to. 177 * @param pos the position where to concatenate. 178 * @return the next position to use in the resultByteArray. 179 */ 180 protected int addByteArray(byte[] tail, byte[] resultByteArray, int pos) 181 { 182 for (int i=0; i<tail.length; i++,pos++) 183 { 184 resultByteArray[pos] = tail[i]; 185 } 186 resultByteArray[pos++] = 0; 187 return pos; 188 } 189 190 /** 191 * Get the length of the next String encoded in the in byte array. 192 * 193 * @param in the byte array where to calculate the string. 194 * @param pos the position whre to start from in the byte array. 195 * @return the length of the next string. 196 * @throws DataFormatException If the byte array does not end with null. 197 */ 198 protected int getNextLength(byte[] in, int pos) throws DataFormatException 199 { 200 int offset = pos; 201 int length = 0; 202 while (in[offset++] != 0) 203 { 204 if (offset >= in.length) 205 throw new DataFormatException("byte[] is not a valid msg"); 206 length++; 207 } 208 return length; 209 } 210 }