mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Jean-Noel Rouvignac
07.46.2013 d27f6ff0f4483ea6da1ec2dbb9044e720e148ded
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
/*
 * 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.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 = null;
 
  /** The requested assured mode of matching update message. */
  private AssuredMode assuredMode = null;
 
  /** The CSN of the assured update message we want acks for. */
  protected CSN csn = 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 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;
  }
}