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