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 2008-2009 Sun Microsystems, Inc.
025 *      Portions Copyright 2013-2015 ForgeRock AS.
026 */
027
028package org.opends.server.replication.server;
029
030import java.util.HashMap;
031import java.util.List;
032import java.util.Map;
033
034import org.opends.server.replication.common.AssuredMode;
035import org.opends.server.replication.common.CSN;
036import org.opends.server.replication.protocol.AckMsg;
037
038/**
039 * This class is the mother class for sub-classes holding any information needed
040 * about the acks that the replication server will wait for, when he receives an
041 * update message with the assured flag on (assured replication acknowledgments
042 * expected).
043 * It also includes info/routines for constructing the final ack to be sent to
044 * the sender of the update message.
045 *
046 * It is expected to have one sub-class per assured replication sub mode.
047 */
048public abstract class ExpectedAcksInfo
049{
050  /**
051   * The server handler of the server that sent the assured update message and
052   * to who we want to return the final ack.
053   */
054  private ServerHandler requesterServerHandler;
055
056  /** The requested assured mode of matching update message. */
057  private AssuredMode assuredMode;
058
059  /** The CSN of the assured update message we want acks for. */
060  protected CSN csn;
061
062  /**
063   * Is the treatment of the acks for the update message completed or not ?
064   * This is used for concurrent access to this object by either the assured
065   * timeout task or the code for processing an ack for the matching update
066   * message. This should be set to true when the treatment of the expected
067   * acks is completed or an ack timeout has occurred and we are going to
068   * remove this object from the map where it is stored.
069   */
070  private boolean completed;
071
072  /**
073   * This gives the list of servers we are willing to wait acks from and the
074   * information about the ack from the servers.
075   * key: the id of the server.
076   * value: a boolean true if we received the ack from the server,
077   * false otherwise.
078   */
079  protected Map<Integer,Boolean> expectedServersAckStatus = new HashMap<>();
080
081  /**
082   * Facility for monitoring:
083   * If the timeout occurs for the original update, we call createAck(true)
084   * in the timeout code for sending back an error ack to the original server.
085   * We use this call to also save the list of server ids for server we did not
086   * have time to receive an ack from. For updating its counters, the timeout
087   * code can then call getTimeoutServers() method to now which servers did not
088   * respond in time.
089   */
090  protected List<Integer> serversInTimeout;
091
092  /**
093   * Creates a new ExpectedAcksInfo.
094   * @param csn The CSN of the assured update message
095   * @param requesterServerHandler The server handler of the server that sent
096   * the assured update message
097   * @param assuredMode The assured mode requested by the assured update message
098   * @param expectedServers The list of servers we want an ack from
099   */
100  protected ExpectedAcksInfo(CSN csn, ServerHandler requesterServerHandler,
101      AssuredMode assuredMode, List<Integer> expectedServers)
102  {
103    this.requesterServerHandler = requesterServerHandler;
104    this.assuredMode = assuredMode;
105    this.csn = csn;
106
107    // Initialize list of servers we expect acks from
108    for (Integer serverId : expectedServers)
109    {
110      expectedServersAckStatus.put(serverId, false);
111    }
112  }
113
114  /**
115   * Gets the server handler of the server which requested the acknowledgments.
116   * @return The server handler of the server which requested the
117   * acknowledgments.
118   */
119  public ServerHandler getRequesterServer()
120  {
121    return requesterServerHandler;
122  }
123
124  /**
125   * Gets the list of expected servers that did not respond in time.
126   * @return The list of expected servers that did not respond in time.
127   */
128  public List<Integer> getTimeoutServers()
129  {
130    return serversInTimeout;
131  }
132
133  /**
134   * Gets the requested assured mode for the matching update message.
135   * @return The requested assured mode for the matching update message.
136   */
137  public AssuredMode getAssuredMode()
138  {
139    return assuredMode;
140  }
141
142  /**
143   * Process the received ack from a server we are waiting an ack from.
144   * @param ackingServer The server handler of the server that sent the ack
145   * @param ackMsg The ack message to process
146   * @return True if the expected number of acks has just been reached
147   */
148  public abstract boolean processReceivedAck(ServerHandler ackingServer,
149    AckMsg ackMsg);
150
151  /**
152   * Creates the ack message to be returned to the requester server, taking into
153   * account the information in the received acks from every servers.
154   * @param timeout True if we call this method when the timeout occurred, that
155   * is we did not received every expected acks in time, and thus, the timeout
156   * flag should also be enabled in the returned ack message.
157   * @return The ack message ready to be sent to the requester server
158   */
159  public abstract AckMsg createAck(boolean timeout);
160
161  /**
162   * Has the treatment of this object been completed or not?
163   * If true is returned, one must not modify this object (useless) nor remove
164   * it from the map where it is stored (will be or has already been done by the
165   * other code (ack timeout code, or ack processing code)).
166   * @return True if treatment of this object has been completed.
167   */
168  public boolean isCompleted()
169  {
170    return completed;
171  }
172
173  /**
174   * Signal that treatment of this object has been completed and that it is
175   * going to be removed from the map where it is stored.
176   */
177  public void completed()
178  {
179    completed = true;
180  }
181}