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 2008-2010 Sun Microsystems, Inc.
015 * Portions copyright 2011-2016 ForgeRock AS.
016 */
017package org.opends.server.replication.common;
018
019import java.util.ArrayList;
020import java.util.Collection;
021import java.util.Collections;
022import java.util.HashSet;
023import java.util.List;
024import java.util.Objects;
025import java.util.Set;
026
027import net.jcip.annotations.Immutable;
028
029/**
030 * This class holds information about a DS connected to the topology. This
031 * information is to be exchanged through the replication protocol in topology
032 * messages, to keep every member (RS or DS) of the topology aware of the DS
033 * topology.
034 */
035@Immutable
036public final class DSInfo
037{
038  /** DS server id. */
039  private final int dsId;
040  /** DS server url. */
041  private final String dsUrl;
042  /** Server id of the RS that the DS is connected to. */
043  private final int rsId;
044  /** DS Generation Id. */
045  private final long generationId;
046  /** DS Status. */
047  private final ServerStatus status;
048  /** Assured replication enabled on DS or not. */
049  private final boolean assuredFlag;
050  /** DS assured mode (relevant if assured replication enabled). */
051  private final AssuredMode assuredMode;
052  /** DS safe data level (relevant if assured mode is safe data). */
053  private final byte safeDataLevel;
054  /** List of referrals URLs exported by the DS. */
055  private final List<String> refUrls;
056  /** Group id. */
057  private final byte groupId;
058  /** Protocol version. */
059  private final short protocolVersion;
060
061  private final Set<String> eclIncludes;
062  private final Set<String> eclIncludesForDeletes;
063
064
065  /**
066   * Creates a new instance of DSInfo with every given info.
067   *
068   * @param dsId
069   *          The DS id
070   * @param dsUrl Url of the DS
071   * @param rsId
072   *          The RS id the DS is connected to
073   * @param generationId
074   *          The generation id the DS is using
075   * @param status
076   *          The DS status
077   * @param assuredFlag
078   *          DS assured replication enabled or not
079   * @param assuredMode
080   *          DS assured mode
081   * @param safeDataLevel
082   *          DS safe data level
083   * @param groupId
084   *          DS group id
085   * @param refUrls
086   *          DS exported referrals URLs
087   * @param eclIncludes
088   *          The list of entry attributes to include in the ECL.
089   * @param eclIncludesForDeletes
090   *          The list of entry attributes to include in the ECL for deletes.
091   * @param protocolVersion
092   *          Protocol version supported by this server.
093   */
094  public DSInfo(int dsId, String dsUrl, int rsId, long generationId,
095      ServerStatus status, boolean assuredFlag,
096      AssuredMode assuredMode, byte safeDataLevel, byte groupId,
097      Collection<String> refUrls, Collection<String> eclIncludes,
098      Collection<String> eclIncludesForDeletes, short protocolVersion)
099  {
100    this.dsId = dsId;
101    this.dsUrl = dsUrl;
102    this.rsId = rsId;
103    this.generationId = generationId;
104    this.status = status;
105    this.assuredFlag = assuredFlag;
106    this.assuredMode = assuredMode;
107    this.safeDataLevel = safeDataLevel;
108    this.groupId = groupId;
109    this.refUrls = Collections.unmodifiableList(new ArrayList<String>(refUrls));
110    this.eclIncludes =
111        Collections.unmodifiableSet(new HashSet<String>(eclIncludes));
112    this.eclIncludesForDeletes =
113        Collections.unmodifiableSet(new HashSet<String>(eclIncludesForDeletes));
114    this.protocolVersion = protocolVersion;
115  }
116
117  /**
118   * Get the DS id.
119   * @return the DS id
120   */
121  public int getDsId()
122  {
123    return dsId;
124  }
125
126  /**
127   * Get the DS URL.
128   * @return the DS URL
129   */
130  public String getDsUrl()
131  {
132    return dsUrl;
133  }
134
135  /**
136   * Get the RS id the DS is connected to.
137   * @return the RS id the DS is connected to
138   */
139  public int getRsId()
140  {
141    return rsId;
142  }
143
144  /**
145   * Get the generation id DS is using.
146   * @return the generation id DS is using.
147   */
148  public long getGenerationId()
149  {
150    return generationId;
151  }
152
153  /**
154   * Get the DS status.
155   * @return the DS status
156   */
157  public ServerStatus getStatus()
158  {
159    return status;
160  }
161
162  /**
163   * Tells if the DS has assured replication enabled.
164   * @return True if the DS has assured replication enabled
165   */
166  public boolean isAssured()
167  {
168    return assuredFlag;
169  }
170
171  /**
172   * Get the DS assured mode (relevant if DS has assured replication enabled).
173   * @return The DS assured mode
174   */
175  public AssuredMode getAssuredMode()
176  {
177    return assuredMode;
178  }
179
180  /**
181   * Get the DS safe data level (relevant if assured mode is safe data).
182   * @return The DS safe data level
183   */
184  public byte getSafeDataLevel()
185  {
186    return safeDataLevel;
187  }
188
189  /**
190   * Get the DS group id.
191   * @return The DS group id
192   */
193  public byte getGroupId()
194  {
195    return groupId;
196  }
197
198  /**
199   * Get the DS exported URLs for referrals.
200   * @return The DS exported URLs for referrals
201   */
202  public List<String> getRefUrls()
203  {
204    return refUrls;
205  }
206
207  /**
208   * Get the entry attributes to be included in the ECL.
209   * @return The entry attributes to be included in the ECL.
210   */
211  public Set<String> getEclIncludes()
212  {
213    return eclIncludes;
214  }
215
216  /**
217   * Get the entry attributes to be included in the ECL for delete operations.
218   * @return The entry attributes to be included in the ECL.
219   */
220  public Set<String> getEclIncludesForDeletes()
221  {
222    return eclIncludesForDeletes;
223  }
224
225  /**
226   * Get the protocol version supported by this server.
227   * Returns -1 when the protocol version is not known (too old version).
228   * @return The protocol version.
229   */
230  public short getProtocolVersion()
231  {
232    return protocolVersion;
233  }
234
235  /**
236   * Returns a new instance of {@link DSInfo} with the specified replication
237   * server Id.
238   *
239   * @param rsId
240   *          the replication server Id to set on the new DSInfo object.
241   * @return a new instance of {@link DSInfo} with the specified replication
242   *         server Id.
243   */
244  public DSInfo cloneWithReplicationServerId(int rsId)
245  {
246    return new DSInfo(dsId, dsUrl, rsId, generationId, status, assuredFlag,
247        assuredMode, safeDataLevel, groupId, refUrls, eclIncludes,
248        eclIncludesForDeletes, protocolVersion);
249  }
250
251  /**
252   * Test if the passed object is equal to this one.
253   * @param obj The object to test
254   * @return True if both objects are equal
255   */
256  @Override
257  public boolean equals(Object obj)
258  {
259    if (obj == null)
260    {
261      return false;
262    }
263    if (obj.getClass() != getClass())
264    {
265      return false;
266    }
267    final DSInfo dsInfo = (DSInfo) obj;
268    return dsId == dsInfo.getDsId()
269        && rsId == dsInfo.getRsId()
270        && generationId == dsInfo.getGenerationId()
271        && status == dsInfo.getStatus()
272        && assuredFlag == dsInfo.isAssured()
273        && assuredMode == dsInfo.getAssuredMode()
274        && safeDataLevel == dsInfo.getSafeDataLevel()
275        && groupId == dsInfo.getGroupId()
276        && protocolVersion == dsInfo.getProtocolVersion()
277        && refUrls.equals(dsInfo.getRefUrls())
278        && Objects.equals(eclIncludes, dsInfo.getEclIncludes())
279        && Objects.equals(eclIncludesForDeletes, dsInfo.getEclIncludesForDeletes());
280  }
281
282  /**
283   * Computes hash code for this object instance.
284   * @return Hash code for this object instance.
285   */
286  @Override
287  public int hashCode()
288  {
289    int hash = 7;
290    hash = 73 * hash + this.dsId;
291    hash = 73 * hash + this.rsId;
292    hash = 73 * hash + (int) (this.generationId ^ (this.generationId >>> 32));
293    hash = 73 * hash + (this.status != null ? this.status.hashCode() : 0);
294    hash = 73 * hash + (this.assuredFlag ? 1 : 0);
295    hash =
296      73 * hash + (this.assuredMode != null ? this.assuredMode.hashCode() : 0);
297    hash = 73 * hash + this.safeDataLevel;
298    hash = 73 * hash + (this.refUrls != null ? this.refUrls.hashCode() : 0);
299    hash = 73 * hash + (this.eclIncludes != null ? eclIncludes.hashCode() : 0);
300    hash = 73 * hash + (this.eclIncludesForDeletes != null ?
301        eclIncludesForDeletes.hashCode() : 0);
302    hash = 73 * hash + this.groupId;
303    hash = 73 * hash + this.protocolVersion;
304    return hash;
305  }
306
307  /**
308   * Returns a string representation of the DS info.
309   * @return A string representation of the DS info
310   */
311  @Override
312  public String toString()
313  {
314    final StringBuilder sb = new StringBuilder();
315    sb.append("DS id: ").append(dsId);
316    sb.append(" ; DS url: ").append(dsUrl);
317    sb.append(" ; RS id: ").append(rsId);
318    sb.append(" ; Generation id: ").append(generationId);
319    sb.append(" ; Status: ").append(status);
320    sb.append(" ; Assured replication: ").append(assuredFlag);
321    if (assuredFlag)
322    {
323      sb.append(" ; Assured mode: ").append(assuredMode);
324      sb.append(" ; Safe data level: ").append(safeDataLevel);
325    }
326    sb.append(" ; Group id: ").append(groupId);
327    sb.append(" ; Protocol version: ").append(protocolVersion);
328    sb.append(" ; Referral URLs: ").append(refUrls);
329    sb.append(" ; ECL Include: ").append(eclIncludes);
330    sb.append(" ; ECL Include for Deletes: ").append(eclIncludesForDeletes);
331    return sb.toString();
332  }
333
334}