/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
* or http://forgerock.org/license/CDDLv1.0.html.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at legal-notices/CDDLv1_0.txt.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information:
* Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2008-2009 Sun Microsystems, Inc.
* Portions Copyright 2013-2015 ForgeRock AS.
*/
package org.opends.server.replication.server;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.opends.server.replication.common.AssuredMode;
import org.opends.server.replication.common.CSN;
import org.opends.server.replication.protocol.AckMsg;
/**
* This class is the mother class for sub-classes holding any information needed
* about the acks that the replication server will wait for, when he receives an
* update message with the assured flag on (assured replication acknowledgments
* expected).
* It also includes info/routines for constructing the final ack to be sent to
* the sender of the update message.
*
* It is expected to have one sub-class per assured replication sub mode.
*/
public abstract class ExpectedAcksInfo
{
/**
* The server handler of the server that sent the assured update message and
* to who we want to return the final ack.
*/
private ServerHandler requesterServerHandler;
/** The requested assured mode of matching update message. */
private AssuredMode assuredMode;
/** The CSN of the assured update message we want acks for. */
protected CSN csn;
/**
* Is the treatment of the acks for the update message completed or not ?
* This is used for concurrent access to this object by either the assured
* timeout task or the code for processing an ack for the matching update
* message. This should be set to true when the treatment of the expected
* acks is completed or an ack timeout has occurred and we are going to
* remove this object from the map where it is stored.
*/
private boolean completed;
/**
* This gives the list of servers we are willing to wait acks from and the
* information about the ack from the servers.
* key: the id of the server.
* value: a boolean true if we received the ack from the server,
* false otherwise.
*/
protected Map<Integer,Boolean> expectedServersAckStatus = new HashMap<>();
/**
* Facility for monitoring:
* If the timeout occurs for the original update, we call createAck(true)
* in the timeout code for sending back an error ack to the original server.
* We use this call to also save the list of server ids for server we did not
* have time to receive an ack from. For updating its counters, the timeout
* code can then call getTimeoutServers() method to now which servers did not
* respond in time.
*/
protected List<Integer> serversInTimeout;
/**
* Creates a new ExpectedAcksInfo.
* @param csn The CSN of the assured update message
* @param requesterServerHandler The server handler of the server that sent
* the assured update message
* @param assuredMode The assured mode requested by the assured update message
* @param expectedServers The list of servers we want an ack from
*/
protected ExpectedAcksInfo(CSN csn, ServerHandler requesterServerHandler,
AssuredMode assuredMode, List<Integer> expectedServers)
{
this.requesterServerHandler = requesterServerHandler;
this.assuredMode = assuredMode;
this.csn = csn;
// Initialize list of servers we expect acks from
for (Integer serverId : expectedServers)
{
expectedServersAckStatus.put(serverId, false);
}
}
/**
* Gets the server handler of the server which requested the acknowledgments.
* @return The server handler of the server which requested the
* acknowledgments.
*/
public ServerHandler getRequesterServer()
{
return requesterServerHandler;
}
/**
* Gets the list of expected servers that did not respond in time.
* @return The list of expected servers that did not respond in time.
*/
public List<Integer> getTimeoutServers()
{
return serversInTimeout;
}
/**
* Gets the requested assured mode for the matching update message.
* @return The requested assured mode for the matching update message.
*/
public AssuredMode getAssuredMode()
{
return assuredMode;
}
/**
* Process the received ack from a server we are waiting an ack from.
* @param ackingServer The server handler of the server that sent the ack
* @param ackMsg The ack message to process
* @return True if the expected number of acks has just been reached
*/
public abstract boolean processReceivedAck(ServerHandler ackingServer,
AckMsg ackMsg);
/**
* Creates the ack message to be returned to the requester server, taking into
* account the information in the received acks from every servers.
* @param timeout True if we call this method when the timeout occurred, that
* is we did not received every expected acks in time, and thus, the timeout
* flag should also be enabled in the returned ack message.
* @return The ack message ready to be sent to the requester server
*/
public abstract AckMsg createAck(boolean timeout);
/**
* Has the treatment of this object been completed or not?
* If true is returned, one must not modify this object (useless) nor remove
* it from the map where it is stored (will be or has already been done by the
* other code (ack timeout code, or ack processing code)).
* @return True if treatment of this object has been completed.
*/
public boolean isCompleted()
{
return completed;
}
/**
* Signal that treatment of this object has been completed and that it is
* going to be removed from the map where it is stored.
*/
public void completed()
{
completed = true;
}
}