diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/coordination/ClusterCoordinator.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/coordination/ClusterCoordinator.java
index a2e17b5c9e..4894fc5396 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/coordination/ClusterCoordinator.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/coordination/ClusterCoordinator.java
@@ -172,6 +172,11 @@ public interface ClusterCoordinator {
*/
NodeIdentifier getElectedActiveCoordinatorNode();
+ /**
+ * @return the identifier of this node, if it is known, null if the Node Identifier has not yet been established.
+ */
+ NodeIdentifier getLocalNodeIdentifier();
+
/**
* @return true if this node has been elected the active cluster coordinator, false otherwise.
*/
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/coordination/node/DisconnectionCode.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/coordination/node/DisconnectionCode.java
index ae18699c38..48ca41d554 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/coordination/node/DisconnectionCode.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/coordination/node/DisconnectionCode.java
@@ -67,6 +67,11 @@ public enum DisconnectionCode {
*/
FAILED_TO_SERVICE_REQUEST("Failed to Service Request"),
+ /**
+ * Coordinator received a heartbeat from node, but the node is disconnected from the cluster
+ */
+ HEARTBEAT_RECEIVED_FROM_DISCONNECTED_NODE("Heartbeat Received from Disconnected Node"),
+
/**
* Node is being shut down
*/
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/ClusterCoordinationProtocolSender.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/ClusterCoordinationProtocolSender.java
index a1af0f8f5c..b49f57ca79 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/ClusterCoordinationProtocolSender.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster-protocol/src/main/java/org/apache/nifi/cluster/protocol/ClusterCoordinationProtocolSender.java
@@ -25,7 +25,7 @@ import org.apache.nifi.cluster.protocol.message.ReconnectionResponseMessage;
import org.apache.nifi.reporting.BulletinRepository;
/**
- * An interface for sending protocol messages from the cluster manager to nodes.
+ * An interface for sending protocol messages from the cluster coordinator to nodes.
*
*/
public interface ClusterCoordinationProtocolSender {
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/heartbeat/AbstractHeartbeatMonitor.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/heartbeat/AbstractHeartbeatMonitor.java
index be9559dad9..0bd84d6d42 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/heartbeat/AbstractHeartbeatMonitor.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/heartbeat/AbstractHeartbeatMonitor.java
@@ -126,9 +126,7 @@ public abstract class AbstractHeartbeatMonitor implements HeartbeatMonitor {
protected synchronized void monitorHeartbeats() {
final Map latestHeartbeats = getLatestHeartbeats();
if (latestHeartbeats == null || latestHeartbeats.isEmpty()) {
- // failed to fetch heartbeats; don't change anything.
- clusterCoordinator.reportEvent(null, Severity.INFO, "Failed to retrieve any new heartbeat information for nodes. "
- + "Will not make any decisions based on heartbeats.");
+ logger.debug("Received no new heartbeats. Will not disconnect any nodes due to lack of heartbeat");
return;
}
@@ -213,7 +211,7 @@ public abstract class AbstractHeartbeatMonitor implements HeartbeatMonitor {
} else {
// disconnected nodes should not heartbeat, so we need to issue a disconnection request.
logger.info("Ignoring received heartbeat from disconnected node " + nodeId + ". Issuing disconnection request.");
- clusterCoordinator.requestNodeDisconnect(nodeId, connectionStatus.getDisconnectCode(), connectionStatus.getDisconnectReason());
+ clusterCoordinator.requestNodeDisconnect(nodeId, DisconnectionCode.HEARTBEAT_RECEIVED_FROM_DISCONNECTED_NODE, DisconnectionCode.HEARTBEAT_RECEIVED_FROM_DISCONNECTED_NODE.toString());
removeHeartbeat(nodeId);
}
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/RequestReplicator.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/RequestReplicator.java
index 672490173a..bfe528df88 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/RequestReplicator.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/RequestReplicator.java
@@ -98,10 +98,13 @@ public interface RequestReplicator {
* @param headers any HTTP headers
* @param indicateReplicated if true, will add a header indicating to the receiving nodes that the request
* has already been replicated, so the receiving node will not replicate the request itself.
+ * @param performVerification if true, and the request is mutable, will verify that all nodes are connected before
+ * making the request and that all nodes are able to perform the request before acutally attempting to perform the task.
+ * If false, will perform no such verification
*
* @return an AsyncClusterResponse that indicates the current status of the request and provides an identifier for obtaining an updated response later
*/
- AsyncClusterResponse replicate(Set nodeIds, String method, URI uri, Object entity, Map headers, boolean indicateReplicated);
+ AsyncClusterResponse replicate(Set nodeIds, String method, URI uri, Object entity, Map headers, boolean indicateReplicated, boolean performVerification);
/**
*
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/ThreadPoolRequestReplicator.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/ThreadPoolRequestReplicator.java
index f4fcc851a2..c5a8af54a5 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/ThreadPoolRequestReplicator.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/http/replication/ThreadPoolRequestReplicator.java
@@ -211,11 +211,12 @@ public class ThreadPoolRequestReplicator implements RequestReplicator {
final Set nodeIdSet = new HashSet<>(nodeIds);
- return replicate(nodeIdSet, method, uri, entity, headers, true);
+ return replicate(nodeIdSet, method, uri, entity, headers, true, true);
}
@Override
- public AsyncClusterResponse replicate(Set nodeIds, String method, URI uri, Object entity, Map headers, final boolean indicateReplicated) {
+ public AsyncClusterResponse replicate(Set nodeIds, String method, URI uri, Object entity, Map headers,
+ final boolean indicateReplicated, final boolean performVerification) {
final Map updatedHeaders = new HashMap<>(headers);
updatedHeaders.put(RequestReplicator.CLUSTER_ID_GENERATION_SEED_HEADER, TypeOneUUIDGenerator.generateId().toString());
@@ -242,12 +243,12 @@ public class ThreadPoolRequestReplicator implements RequestReplicator {
lock.lock();
try {
logger.debug("Lock {} obtained in order to replicate request {} {}", method, uri);
- return replicate(nodeIds, method, uri, entity, updatedHeaders, true, null);
+ return replicate(nodeIds, method, uri, entity, updatedHeaders, performVerification, null);
} finally {
lock.unlock();
}
} else {
- return replicate(nodeIds, method, uri, entity, updatedHeaders, true, null);
+ return replicate(nodeIds, method, uri, entity, updatedHeaders, performVerification, null);
}
}
@@ -259,13 +260,13 @@ public class ThreadPoolRequestReplicator implements RequestReplicator {
* @param uri the URI to send the request to
* @param entity the entity to use
* @param headers the HTTP Headers
- * @param performVerification whether or not to use 2-phase commit to verify that all nodes can handle the request. Ignored if request is not mutable.
+ * @param performVerification whether or not to verify that all nodes in the cluster are connected and that all nodes can perform request. Ignored if request is not mutable.
* @param response the response to update with the results
*
* @return an AsyncClusterResponse that can be used to obtain the result
*/
private AsyncClusterResponse replicate(Set nodeIds, String method, URI uri, Object entity, Map headers, boolean performVerification,
- StandardAsyncClusterResponse response) {
+ StandardAsyncClusterResponse response) {
// state validation
Objects.requireNonNull(nodeIds);
@@ -298,7 +299,7 @@ public class ThreadPoolRequestReplicator implements RequestReplicator {
final String requestId = updatedHeaders.computeIfAbsent(REQUEST_TRANSACTION_ID_HEADER, key -> UUID.randomUUID().toString());
if (performVerification) {
- verifyState(method, uri.getPath());
+ verifyClusterState(method, uri.getPath());
}
int numRequests = responseMap.size();
@@ -530,7 +531,7 @@ public class ThreadPoolRequestReplicator implements RequestReplicator {
*
* @throw IllegalClusterStateException if the cluster is not in a state that allows a request to made to the given URI Path using the given HTTP Method
*/
- private void verifyState(final String httpMethod, final String uriPath) {
+ private void verifyClusterState(final String httpMethod, final String uriPath) {
final boolean mutableRequest = HttpMethod.DELETE.equals(httpMethod) || HttpMethod.POST.equals(httpMethod) || HttpMethod.PUT.equals(httpMethod);
// check that the request can be applied
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/node/NodeClusterCoordinator.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/node/NodeClusterCoordinator.java
index 3f8fa76bf5..b31530f631 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/node/NodeClusterCoordinator.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/main/java/org/apache/nifi/cluster/coordination/node/NodeClusterCoordinator.java
@@ -30,6 +30,7 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.function.Supplier;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@@ -138,14 +139,23 @@ public class NodeClusterCoordinator implements ClusterCoordinator, ProtocolHandl
this.nodeId = nodeId;
}
- NodeIdentifier getLocalNodeIdentifier() {
+ @Override
+ public NodeIdentifier getLocalNodeIdentifier() {
return nodeId;
}
private NodeIdentifier waitForLocalNodeIdentifier() {
+ return waitForNodeIdentifier(() -> getLocalNodeIdentifier());
+ }
+
+ private NodeIdentifier waitForElectedClusterCoordinator() {
+ return waitForNodeIdentifier(() -> getElectedActiveCoordinatorNode(false));
+ }
+
+ private NodeIdentifier waitForNodeIdentifier(final Supplier fetchNodeId) {
NodeIdentifier localNodeId = null;
while (localNodeId == null) {
- localNodeId = getLocalNodeIdentifier();
+ localNodeId = fetchNodeId.get();
if (localNodeId == null) {
try {
Thread.sleep(100L);
@@ -279,8 +289,8 @@ public class NodeClusterCoordinator implements ClusterCoordinator, ProtocolHandl
@Override
public void requestNodeDisconnect(final NodeIdentifier nodeId, final DisconnectionCode disconnectionCode, final String explanation) {
- final int numConnected = getNodeIdentifiers(NodeConnectionState.CONNECTED).size();
- if (numConnected == 1) {
+ final Set connectedNodeIds = getNodeIdentifiers(NodeConnectionState.CONNECTED);
+ if (connectedNodeIds.size() == 1 && connectedNodeIds.contains(nodeId)) {
throw new IllegalNodeDisconnectionException("Cannot disconnect node " + nodeId + " because it is the only node currently connected");
}
@@ -514,17 +524,27 @@ public class NodeClusterCoordinator implements ClusterCoordinator, ProtocolHandl
@Override
public NodeIdentifier getElectedActiveCoordinatorNode() {
+ return getElectedActiveCoordinatorNode(true);
+ }
+
+ private NodeIdentifier getElectedActiveCoordinatorNode(final boolean warnOnError) {
final String electedNodeAddress;
try {
electedNodeAddress = getElectedActiveCoordinatorAddress();
} catch (final IOException ioe) {
- logger.warn("Failed to determine which node is elected active Cluster Coordinator. There may be no coordinator currently:", ioe);
+ if (warnOnError) {
+ logger.warn("Failed to determine which node is elected active Cluster Coordinator. There may be no coordinator currently:", ioe);
+ }
+
return null;
}
final int colonLoc = electedNodeAddress.indexOf(':');
if (colonLoc < 1) {
- logger.warn("Failed to determine which node is elected active Cluster Coordinator: ZooKeeper reports the address as {}, but this is not a valid address", electedNodeAddress);
+ if (warnOnError) {
+ logger.warn("Failed to determine which node is elected active Cluster Coordinator: ZooKeeper reports the address as {}, but this is not a valid address", electedNodeAddress);
+ }
+
return null;
}
@@ -534,7 +554,10 @@ public class NodeClusterCoordinator implements ClusterCoordinator, ProtocolHandl
try {
electedNodePort = Integer.parseInt(portString);
} catch (final NumberFormatException nfe) {
- logger.warn("Failed to determine which node is elected active Cluster Coordinator: ZooKeeper reports the address as {}, but this is not a valid address", electedNodeAddress);
+ if (warnOnError) {
+ logger.warn("Failed to determine which node is elected active Cluster Coordinator: ZooKeeper reports the address as {}, but this is not a valid address", electedNodeAddress);
+ }
+
return null;
}
@@ -544,7 +567,7 @@ public class NodeClusterCoordinator implements ClusterCoordinator, ProtocolHandl
.findFirst()
.orElse(null);
- if (electedNodeId == null) {
+ if (electedNodeId == null && warnOnError) {
logger.warn("Failed to determine which node is elected active Cluster Coordinator: ZooKeeper reports the address as {}, but there is no node with this address", electedNodeAddress);
}
@@ -610,16 +633,37 @@ public class NodeClusterCoordinator implements ClusterCoordinator, ProtocolHandl
logger.debug("State of cluster nodes is now {}", nodeStatuses);
if (currentState == null || currentState != status.getState()) {
- notifyOthersOfNodeStatusChange(status);
+ // We notify all nodes of the status change if either this node is the current cluster coordinator, OR if the node was
+ // the cluster coordinator and no longer is. This is done because if a user disconnects the cluster coordinator, we need
+ // to broadcast to the cluster that this node is no longer the coordinator. Otherwise, all nodes but this one will still
+ // believe that this node is connected to the cluster.
+ final boolean notifyAllNodes = isActiveClusterCoordinator() || (currentStatus != null && currentStatus.getRoles().contains(ClusterRoles.CLUSTER_COORDINATOR));
+ notifyOthersOfNodeStatusChange(status, notifyAllNodes);
}
}
+ void notifyOthersOfNodeStatusChange(final NodeConnectionStatus updatedStatus) {
+ notifyOthersOfNodeStatusChange(updatedStatus, isActiveClusterCoordinator());
+ }
- private void notifyOthersOfNodeStatusChange(final NodeConnectionStatus updatedStatus) {
- final Set nodesToNotify = getNodeIdentifiers(NodeConnectionState.CONNECTED, NodeConnectionState.CONNECTING);
+ /**
+ * Notifies other nodes that the status of a node changed
+ *
+ * @param updatedStatus the updated status for a node in the cluster
+ * @param notifyAllNodes if true will notify all nodes. If false, will notify only the cluster coordinator
+ */
+ void notifyOthersOfNodeStatusChange(final NodeConnectionStatus updatedStatus, final boolean notifyAllNodes) {
+ // If this node is the active cluster coordinator, then we are going to replicate to all nodes.
+ // Otherwise, get the active coordinator (or wait for one to become active) and then notify the coordinator.
+ final Set nodesToNotify;
+ if (notifyAllNodes) {
+ nodesToNotify = getNodeIdentifiers(NodeConnectionState.CONNECTED, NodeConnectionState.CONNECTING);
- // Do not notify ourselves because we already know about the status update.
- nodesToNotify.remove(getLocalNodeIdentifier());
+ // Do not notify ourselves because we already know about the status update.
+ nodesToNotify.remove(getLocalNodeIdentifier());
+ } else {
+ nodesToNotify = Collections.singleton(waitForElectedClusterCoordinator());
+ }
final NodeStatusChangeMessage message = new NodeStatusChangeMessage();
message.setNodeId(updatedStatus.getNodeIdentifier());
@@ -767,6 +811,10 @@ public class NodeClusterCoordinator implements ClusterCoordinator, ProtocolHandl
nodeId, updatedStatus, oldStatus);
}
}
+
+ if (isActiveClusterCoordinator()) {
+ notifyOthersOfNodeStatusChange(statusChangeMessage.getNodeConnectionStatus());
+ }
}
private NodeIdentifier resolveNodeId(final NodeIdentifier proposedIdentifier) {
@@ -872,6 +920,12 @@ public class NodeClusterCoordinator implements ClusterCoordinator, ProtocolHandl
*/
@Override
public void afterRequest(final String uriPath, final String method, final Set nodeResponses) {
+ // if we are not the active cluster coordinator, then we are not responsible for monitoring the responses,
+ // as the cluster coordinator is responsible for performing the actual request replication.
+ if (!isActiveClusterCoordinator()) {
+ return;
+ }
+
final boolean mutableRequest = isMutableRequest(method);
/*
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/heartbeat/TestAbstractHeartbeatMonitor.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/heartbeat/TestAbstractHeartbeatMonitor.java
index 81d72ed432..9ef0a14c96 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/heartbeat/TestAbstractHeartbeatMonitor.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/heartbeat/TestAbstractHeartbeatMonitor.java
@@ -305,6 +305,11 @@ public class TestAbstractHeartbeatMonitor {
@Override
public void removeRole(String clusterRole) {
}
+
+ @Override
+ public NodeIdentifier getLocalNodeIdentifier() {
+ return null;
+ }
}
public static class ReportedEvent {
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/http/replication/TestThreadPoolRequestReplicator.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/http/replication/TestThreadPoolRequestReplicator.java
index 2af3e88d9d..5eac84616c 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/http/replication/TestThreadPoolRequestReplicator.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/http/replication/TestThreadPoolRequestReplicator.java
@@ -87,7 +87,7 @@ public class TestThreadPoolRequestReplicator {
final URI uri = new URI("http://localhost:8080/processors/1");
final Entity entity = new ProcessorEntity();
- final AsyncClusterResponse response = replicator.replicate(nodeIds, HttpMethod.GET, uri, entity, new HashMap<>(), true);
+ final AsyncClusterResponse response = replicator.replicate(nodeIds, HttpMethod.GET, uri, entity, new HashMap<>(), true, true);
// We should get back the same response object
assertTrue(response == replicator.getClusterResponse(response.getRequestIdentifier()));
@@ -115,7 +115,7 @@ public class TestThreadPoolRequestReplicator {
final URI uri = new URI("http://localhost:8080/processors/1");
final Entity entity = new ProcessorEntity();
- final AsyncClusterResponse response = replicator.replicate(nodeIds, HttpMethod.GET, uri, entity, new HashMap<>(), true);
+ final AsyncClusterResponse response = replicator.replicate(nodeIds, HttpMethod.GET, uri, entity, new HashMap<>(), true, true);
// We should get back the same response object
assertTrue(response == replicator.getClusterResponse(response.getRequestIdentifier()));
@@ -151,7 +151,7 @@ public class TestThreadPoolRequestReplicator {
final URI uri = new URI("http://localhost:8080/processors/1");
final Entity entity = new ProcessorEntity();
- final AsyncClusterResponse response = replicator.replicate(nodeIds, HttpMethod.GET, uri, entity, new HashMap<>(), true);
+ final AsyncClusterResponse response = replicator.replicate(nodeIds, HttpMethod.GET, uri, entity, new HashMap<>(), true, true);
assertNotNull(response.awaitMergedResponse(1, TimeUnit.SECONDS));
} , null, 0L, new IllegalArgumentException("Exception created for unit test"));
}
@@ -191,7 +191,7 @@ public class TestThreadPoolRequestReplicator {
try {
final AsyncClusterResponse clusterResponse = replicator.replicate(nodeIds, HttpMethod.POST,
- new URI("http://localhost:80/processors/1"), new ProcessorEntity(), new HashMap<>(), true);
+ new URI("http://localhost:80/processors/1"), new ProcessorEntity(), new HashMap<>(), true, true);
clusterResponse.awaitMergedResponse();
// Ensure that we received two requests - the first should contain the X-NcmExpects header; the second should not.
@@ -235,7 +235,8 @@ public class TestThreadPoolRequestReplicator {
Mockito.when(coordinator.getConnectionStates()).thenReturn(nodeMap);
final ThreadPoolRequestReplicator replicator = new ThreadPoolRequestReplicator(2, new Client(), coordinator, "1 sec", "1 sec", null, null) {
@Override
- public AsyncClusterResponse replicate(Set nodeIds, String method, URI uri, Object entity, Map headers, boolean indicateReplicated) {
+ public AsyncClusterResponse replicate(Set nodeIds, String method, URI uri, Object entity, Map headers,
+ boolean indicateReplicated, boolean verify) {
return null;
}
};
@@ -308,7 +309,7 @@ public class TestThreadPoolRequestReplicator {
try {
final AsyncClusterResponse clusterResponse = replicator.replicate(nodeIds, HttpMethod.POST,
- new URI("http://localhost:80/processors/1"), new ProcessorEntity(), new HashMap<>(), true);
+ new URI("http://localhost:80/processors/1"), new ProcessorEntity(), new HashMap<>(), true, true);
clusterResponse.awaitMergedResponse();
Assert.fail("Expected to get an IllegalClusterStateException but did not");
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/node/TestNodeClusterCoordinator.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/node/TestNodeClusterCoordinator.java
index 25c55a06ee..6f0ad0f07e 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/node/TestNodeClusterCoordinator.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-cluster/src/test/java/org/apache/nifi/cluster/coordination/node/TestNodeClusterCoordinator.java
@@ -59,7 +59,7 @@ import org.mockito.stubbing.Answer;
public class TestNodeClusterCoordinator {
private NodeClusterCoordinator coordinator;
private ClusterCoordinationProtocolSenderListener senderListener;
- private List nodeStatusChangeMessages;
+ private List nodeStatuses;
private Properties createProperties() {
final Properties props = new Properties();
@@ -68,25 +68,20 @@ public class TestNodeClusterCoordinator {
}
@Before
- @SuppressWarnings("unchecked")
public void setup() throws IOException {
senderListener = Mockito.mock(ClusterCoordinationProtocolSenderListener.class);
- nodeStatusChangeMessages = Collections.synchronizedList(new ArrayList<>());
-
- Mockito.doAnswer(new Answer