use of org.apache.nifi.cluster.protocol.message.HeartbeatMessage in project nifi by apache.
the class ClusterProtocolHeartbeatMonitor method handleHeartbeat.
private ProtocolMessage handleHeartbeat(final HeartbeatMessage msg) {
final HeartbeatMessage heartbeatMsg = msg;
final Heartbeat heartbeat = heartbeatMsg.getHeartbeat();
final NodeIdentifier nodeId = heartbeat.getNodeIdentifier();
final NodeConnectionStatus connectionStatus = heartbeat.getConnectionStatus();
final byte[] payloadBytes = heartbeat.getPayload();
final HeartbeatPayload payload = HeartbeatPayload.unmarshal(payloadBytes);
final int activeThreadCount = payload.getActiveThreadCount();
final int flowFileCount = (int) payload.getTotalFlowFileCount();
final long flowFileBytes = payload.getTotalFlowFileBytes();
final long systemStartTime = payload.getSystemStartTime();
final NodeHeartbeat nodeHeartbeat = new StandardNodeHeartbeat(nodeId, System.currentTimeMillis(), connectionStatus, flowFileCount, flowFileBytes, activeThreadCount, systemStartTime);
heartbeatMessages.put(heartbeat.getNodeIdentifier(), nodeHeartbeat);
logger.debug("Received new heartbeat from {}", nodeId);
// Formulate a List of differences between our view of the cluster topology and the node's view
// and send that back to the node so that it is in-sync with us
List<NodeConnectionStatus> nodeStatusList = payload.getClusterStatus();
if (nodeStatusList == null) {
nodeStatusList = Collections.emptyList();
}
final List<NodeConnectionStatus> updatedStatuses = getUpdatedStatuses(nodeStatusList);
final HeartbeatResponseMessage responseMessage = new HeartbeatResponseMessage();
responseMessage.setUpdatedNodeStatuses(updatedStatuses);
if (!getClusterCoordinator().isFlowElectionComplete()) {
responseMessage.setFlowElectionMessage(getClusterCoordinator().getFlowElectionStatus());
}
return responseMessage;
}
use of org.apache.nifi.cluster.protocol.message.HeartbeatMessage in project nifi by apache.
the class ClusterProtocolHeartbeater method send.
@Override
public synchronized void send(final HeartbeatMessage heartbeatMessage) throws IOException {
final long sendStart = System.nanoTime();
final String heartbeatAddress = getHeartbeatAddress();
final HeartbeatResponseMessage responseMessage = protocolSender.heartbeat(heartbeatMessage, heartbeatAddress);
final byte[] payloadBytes = heartbeatMessage.getHeartbeat().getPayload();
final HeartbeatPayload payload = HeartbeatPayload.unmarshal(payloadBytes);
final List<NodeConnectionStatus> nodeStatusList = payload.getClusterStatus();
final Map<NodeIdentifier, Long> updateIdMap = nodeStatusList.stream().collect(Collectors.toMap(status -> status.getNodeIdentifier(), status -> status.getUpdateIdentifier()));
final List<NodeConnectionStatus> updatedStatuses = responseMessage.getUpdatedNodeStatuses();
if (updatedStatuses != null) {
for (final NodeConnectionStatus updatedStatus : updatedStatuses) {
final NodeIdentifier nodeId = updatedStatus.getNodeIdentifier();
final Long updateId = updateIdMap.get(nodeId);
final boolean updated = clusterCoordinator.resetNodeStatus(updatedStatus, updateId == null ? -1L : updateId);
if (updated) {
logger.info("After receiving heartbeat response, updated status of {} to {}", updatedStatus.getNodeIdentifier(), updatedStatus);
} else {
logger.debug("After receiving heartbeat response, did not update status of {} to {} because the update is out-of-date", updatedStatus.getNodeIdentifier(), updatedStatus);
}
}
}
final long sendNanos = System.nanoTime() - sendStart;
final long sendMillis = TimeUnit.NANOSECONDS.toMillis(sendNanos);
final DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS", Locale.US);
final String flowElectionMessage = responseMessage.getFlowElectionMessage();
final String formattedElectionMessage = flowElectionMessage == null ? "" : "; " + flowElectionMessage;
logger.info("Heartbeat created at {} and sent to {} at {}; send took {} millis{}", dateFormatter.format(new Date(heartbeatMessage.getHeartbeat().getCreatedTimestamp())), heartbeatAddress, dateFormatter.format(new Date()), sendMillis, formattedElectionMessage);
}
use of org.apache.nifi.cluster.protocol.message.HeartbeatMessage in project nifi by apache.
the class TestJaxbProtocolUtils method testRoundTripHeartbeat.
@Test
public void testRoundTripHeartbeat() throws JAXBException {
final NodeIdentifier nodeId = new NodeIdentifier("id", "localhost", 8000, "localhost", 8001, "localhost", 8002, 8003, true);
final NodeConnectionStatus nodeStatus = new NodeConnectionStatus(nodeId, DisconnectionCode.NOT_YET_CONNECTED);
final HeartbeatPayload payload = new HeartbeatPayload();
payload.setActiveThreadCount(1);
payload.setSystemStartTime(System.currentTimeMillis());
payload.setTotalFlowFileBytes(83L);
payload.setTotalFlowFileCount(4);
final List<NodeConnectionStatus> clusterStatus = Collections.singletonList(nodeStatus);
payload.setClusterStatus(clusterStatus);
final Heartbeat heartbeat = new Heartbeat(nodeId, nodeStatus, payload.marshal());
final HeartbeatMessage msg = new HeartbeatMessage();
msg.setHeartbeat(heartbeat);
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
JaxbProtocolUtils.JAXB_CONTEXT.createMarshaller().marshal(msg, baos);
final Object unmarshalled = JaxbProtocolUtils.JAXB_CONTEXT.createUnmarshaller().unmarshal(new ByteArrayInputStream(baos.toByteArray()));
assertTrue(unmarshalled instanceof HeartbeatMessage);
}
use of org.apache.nifi.cluster.protocol.message.HeartbeatMessage in project nifi by apache.
the class FlowController method createHeartbeatMessage.
HeartbeatMessage createHeartbeatMessage() {
try {
HeartbeatBean bean = heartbeatBeanRef.get();
if (bean == null) {
readLock.lock();
try {
bean = new HeartbeatBean(getGroup(getRootGroupId()), isPrimary());
} finally {
readLock.unlock();
}
}
// create heartbeat payload
final HeartbeatPayload hbPayload = new HeartbeatPayload();
hbPayload.setSystemStartTime(systemStartTime);
hbPayload.setActiveThreadCount(getActiveThreadCount());
final QueueSize queueSize = getTotalFlowFileCount(bean.getRootGroup());
hbPayload.setTotalFlowFileCount(queueSize.getObjectCount());
hbPayload.setTotalFlowFileBytes(queueSize.getByteCount());
hbPayload.setClusterStatus(clusterCoordinator.getConnectionStatuses());
// create heartbeat message
final NodeIdentifier nodeId = getNodeId();
if (nodeId == null) {
LOG.warn("Cannot create Heartbeat Message because node's identifier is not known at this time");
return null;
}
final Heartbeat heartbeat = new Heartbeat(nodeId, connectionStatus, hbPayload.marshal());
final HeartbeatMessage message = new HeartbeatMessage();
message.setHeartbeat(heartbeat);
LOG.debug("Generated heartbeat");
return message;
} catch (final Throwable ex) {
LOG.warn("Failed to create heartbeat due to: " + ex, ex);
return null;
}
}
Aggregations