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}