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.Serializable;
030 import java.io.UnsupportedEncodingException;
031 import java.util.zip.DataFormatException;
032
033 import org.opends.server.replication.common.ServerState;
034 import org.opends.server.types.DirectoryException;
035 import org.opends.server.types.DN;
036
037 /**
038 * Message sent by a replication server to another replication server
039 * at Startup.
040 */
041 public class ReplServerStartMessage extends StartMessage implements
042 Serializable
043 {
044 private static final long serialVersionUID = -5871385537169856856L;
045
046 private short serverId;
047 private String serverURL;
048 private String baseDn = null;
049 private int windowSize;
050 private ServerState serverState;
051
052 /**
053 * Whether to continue using SSL to encrypt messages after the start
054 * messages have been exchanged.
055 */
056 private boolean sslEncryption;
057
058
059 /**
060 * Create a ReplServerStartMessage.
061 *
062 * @param serverId replication server id
063 * @param serverURL replication server URL
064 * @param baseDn base DN for which the ReplServerStartMessage is created.
065 * @param windowSize The window size.
066 * @param serverState our ServerState for this baseDn.
067 * @param protocolVersion The replication protocol version of the creator.
068 * @param generationId The generationId for this server.
069 * @param sslEncryption Whether to continue using SSL to encrypt messages
070 * after the start messages have been exchanged.
071 */
072 public ReplServerStartMessage(short serverId, String serverURL, DN baseDn,
073 int windowSize,
074 ServerState serverState,
075 short protocolVersion,
076 long generationId,
077 boolean sslEncryption)
078 {
079 super(protocolVersion, generationId);
080 this.serverId = serverId;
081 this.serverURL = serverURL;
082 if (baseDn != null)
083 this.baseDn = baseDn.toNormalizedString();
084 else
085 this.baseDn = null;
086 this.windowSize = windowSize;
087 this.serverState = serverState;
088 this.sslEncryption = sslEncryption;
089 }
090
091 /**
092 * Creates a new ReplServerStartMessage by decoding the provided byte array.
093 * @param in A byte array containing the encoded information for the
094 * ReplServerStartMessage
095 * @throws DataFormatException If the in does not contain a properly
096 * encoded ReplServerStartMessage.
097 */
098 public ReplServerStartMessage(byte[] in) throws DataFormatException
099 {
100 /* The ReplServerStartMessage is encoded in the form :
101 * <baseDn><ServerId><ServerUrl><windowsize><ServerState>
102 */
103 super(MSG_TYPE_REPL_SERVER_START, in);
104
105 try
106 {
107 /* first bytes are the header */
108 int pos = headerLength;
109
110 /* read the dn
111 * first calculate the length then construct the string
112 */
113 int length = getNextLength(in, pos);
114 baseDn = new String(in, pos, length, "UTF-8");
115 pos += length +1;
116
117 /*
118 * read the ServerId
119 */
120 length = getNextLength(in, pos);
121 String serverIdString = new String(in, pos, length, "UTF-8");
122 serverId = Short.valueOf(serverIdString);
123 pos += length +1;
124
125 /*
126 * read the ServerURL
127 */
128 length = getNextLength(in, pos);
129 serverURL = new String(in, pos, length, "UTF-8");
130 pos += length +1;
131
132 /*
133 * read the window size
134 */
135 length = getNextLength(in, pos);
136 windowSize = Integer.valueOf(new String(in, pos, length, "UTF-8"));
137 pos += length +1;
138
139 /*
140 * read the sslEncryption setting
141 */
142 length = getNextLength(in, pos);
143 sslEncryption = Boolean.valueOf(new String(in, pos, length, "UTF-8"));
144 pos += length +1;
145
146 /*
147 * read the ServerState
148 */
149 serverState = new ServerState(in, pos, in.length-1);
150 } catch (UnsupportedEncodingException e)
151 {
152 throw new DataFormatException("UTF-8 is not supported by this jvm.");
153 }
154 }
155
156 /**
157 * Get the Server Id.
158 * @return the server id
159 */
160 public short getServerId()
161 {
162 return this.serverId;
163 }
164
165 /**
166 * Set the server URL.
167 * @return the server URL
168 */
169 public String getServerURL()
170 {
171 return this.serverURL;
172 }
173
174 /**
175 * Get the base DN from this ReplServerStartMessage.
176 *
177 * @return the base DN from this ReplServerStartMessage.
178 */
179 public DN getBaseDn()
180 {
181 if (baseDn == null)
182 return null;
183 try
184 {
185 return DN.decode(baseDn);
186 } catch (DirectoryException e)
187 {
188 return null;
189 }
190 }
191
192 /**
193 * Get the serverState.
194 * @return Returns the serverState.
195 */
196 public ServerState getServerState()
197 {
198 return this.serverState;
199 }
200
201 /**
202 * {@inheritDoc}
203 */
204 @Override
205 public byte[] getBytes()
206 {
207 /* The ReplServerStartMessage is stored in the form :
208 * <operation type><basedn><serverid><serverURL><windowsize><serverState>
209 */
210 try {
211 byte[] byteDn = baseDn.getBytes("UTF-8");
212 byte[] byteServerId = String.valueOf(serverId).getBytes("UTF-8");
213 byte[] byteServerUrl = serverURL.getBytes("UTF-8");
214 byte[] byteServerState = serverState.getBytes();
215 byte[] byteWindowSize = String.valueOf(windowSize).getBytes("UTF-8");
216 byte[] byteSSLEncryption =
217 String.valueOf(sslEncryption).getBytes("UTF-8");
218
219 int length = byteDn.length + 1 + byteServerId.length + 1 +
220 byteServerUrl.length + 1 + byteWindowSize.length + 1 +
221 byteSSLEncryption.length + 1 +
222 byteServerState.length + 1;
223
224 /* encode the header in a byte[] large enough to also contain the mods */
225 byte resultByteArray[] = encodeHeader(MSG_TYPE_REPL_SERVER_START, length);
226 int pos = headerLength;
227
228 /* put the baseDN and a terminating 0 */
229 pos = addByteArray(byteDn, resultByteArray, pos);
230
231 /* put the ServerId */
232 pos = addByteArray(byteServerId, resultByteArray, pos);
233
234 /* put the ServerURL */
235 pos = addByteArray(byteServerUrl, resultByteArray, pos);
236
237 /* put the window size */
238 pos = addByteArray(byteWindowSize, resultByteArray, pos);
239
240 /* put the SSL Encryption setting */
241 pos = addByteArray(byteSSLEncryption, resultByteArray, pos);
242
243 /* put the ServerState */
244 pos = addByteArray(byteServerState, resultByteArray, pos);
245
246 return resultByteArray;
247 }
248 catch (UnsupportedEncodingException e)
249 {
250 return null;
251 }
252 }
253
254 /**
255 * get the window size for the server that created this message.
256 *
257 * @return The window size for the server that created this message.
258 */
259 public int getWindowSize()
260 {
261 return windowSize;
262 }
263
264 /**
265 * Get the SSL encryption value for the server that created the
266 * message.
267 *
268 * @return The SSL encryption value for the server that created the
269 * message.
270 */
271 public boolean getSSLEncryption()
272 {
273 return sslEncryption;
274 }
275 }