/*
|
* 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
|
* trunk/opends/resource/legal-notices/OpenDS.LICENSE
|
* or https://OpenDS.dev.java.net/OpenDS.LICENSE.
|
* 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
|
* trunk/opends/resource/legal-notices/OpenDS.LICENSE. 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 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.ChangeNumber;
|
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 = null;
|
|
// The requested assured mode of matching update message
|
private AssuredMode assuredMode = null;
|
|
/**
|
* The change number of the assured update message we want acks for.
|
*/
|
protected ChangeNumber changeNumber = null;
|
|
/**
|
* 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 = false;
|
|
/**
|
* 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<Integer,Boolean>();
|
|
/**
|
* 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 = null;
|
|
/**
|
* Creates a new ExpectedAcksInfo.
|
* @param changeNumber The change number 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(ChangeNumber changeNumber,
|
ServerHandler requesterServerHandler, AssuredMode assuredMode,
|
List<Integer> expectedServers)
|
{
|
this.requesterServerHandler = requesterServerHandler;
|
this.assuredMode = assuredMode;
|
this.changeNumber = changeNumber;
|
|
// 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;
|
}
|
}
|