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 2007-2008 Sun Microsystems, Inc.
026 */
027
028 package org.opends.server.replication.protocol;
029
030 import java.io.ByteArrayOutputStream;
031 import java.io.IOException;
032 import java.io.UnsupportedEncodingException;
033 import java.util.ArrayList;
034 import java.util.List;
035 import java.util.zip.DataFormatException;
036
037 /**
038 *
039 * This class defines a message that is sent by a replication server
040 * to the other replication servers in the topology containing the list
041 * of LDAP servers directly connected to it.
042 * A replication server sends a ReplServerInfoMessage when an LDAP
043 * server connects or disconnects.
044 *
045 * Exchanging these messages allows to have each replication server
046 * knowing the complete list of LDAP servers in the topology and
047 * their associated replication server and thus take the appropriate
048 * decision to route a message to an LDAP server.
049 *
050 */
051 public class ReplServerInfoMessage extends ReplicationMessage
052 {
053 private List<String> connectedServers = null;
054 private long generationId;
055
056 /**
057 * Creates a new changelogInfo message from its encoded form.
058 *
059 * @param in The byte array containing the encoded form of the message.
060 * @throws java.util.zip.DataFormatException If the byte array does not
061 * contain a valid encoded form of the message.
062 */
063 public ReplServerInfoMessage(byte[] in) throws DataFormatException
064 {
065 try
066 {
067 /* first byte is the type */
068 if (in.length < 1 || in[0] != MSG_TYPE_REPL_SERVER_INFO)
069 throw new DataFormatException(
070 "Input is not a valid " + this.getClass().getCanonicalName());
071
072 int pos = 1;
073
074 /* read the generationId */
075 int length = getNextLength(in, pos);
076 generationId = Long.valueOf(new String(in, pos, length,
077 "UTF-8"));
078 pos += length +1;
079
080 /* read the connected servers */
081 connectedServers = new ArrayList<String>();
082 while (pos < in.length)
083 {
084 /*
085 * Read the next server ID
086 * first calculate the length then construct the string
087 */
088 length = getNextLength(in, pos);
089 connectedServers.add(new String(in, pos, length, "UTF-8"));
090 pos += length +1;
091 }
092 } catch (UnsupportedEncodingException e)
093 {
094 throw new DataFormatException("UTF-8 is not supported by this jvm.");
095 }
096 }
097
098
099 /**
100 * Creates a new ReplServerInfo message from a list of the currently
101 * connected servers.
102 *
103 * @param connectedServers The list of currently connected servers ID.
104 * @param generationId The generationId currently associated with this
105 * domain.
106 */
107 public ReplServerInfoMessage(List<String> connectedServers,
108 long generationId)
109 {
110 this.connectedServers = connectedServers;
111 this.generationId = generationId;
112 }
113
114 /**
115 * {@inheritDoc}
116 */
117 @Override
118 public byte[] getBytes()
119 {
120 try
121 {
122 ByteArrayOutputStream oStream = new ByteArrayOutputStream();
123
124 /* Put the message type */
125 oStream.write(MSG_TYPE_REPL_SERVER_INFO);
126
127 // Put the generationId
128 oStream.write(String.valueOf(generationId).getBytes("UTF-8"));
129 oStream.write(0);
130
131 // Put the servers
132 if (connectedServers.size() >= 1)
133 {
134 for (String server : connectedServers)
135 {
136 byte[] byteServerURL = server.getBytes("UTF-8");
137 oStream.write(byteServerURL);
138 oStream.write(0);
139 }
140 }
141
142 return oStream.toByteArray();
143 }
144 catch (IOException e)
145 {
146 // never happens
147 return null;
148 }
149 }
150
151 /**
152 * Get the list of servers currently connected to the Changelog server
153 * that generated this message.
154 *
155 * @return A collection of the servers currently connected to the Changelog
156 * server that generated this message.
157 */
158 public List<String> getConnectedServers()
159 {
160 return connectedServers;
161 }
162
163 /**
164 * Get the generationId from this message.
165 * @return The generationId.
166 */
167 public long getGenerationId()
168 {
169 return generationId;
170 }
171
172 /**
173 * {@inheritDoc}
174 */
175 @Override
176 public String toString()
177 {
178 String csrvs = "";
179 for (String s : connectedServers)
180 {
181 csrvs += s + "/";
182 }
183 return ("ReplServerInfoMessage: genId=" + getGenerationId() +
184 " Connected peers:" + csrvs);
185 }
186
187 }