use of org.apache.nifi.cluster.protocol.NodeIdentifier in project nifi by apache.
the class BulletinMerger method mergeBulletins.
/**
* Merges the bulletins.
*
* @param bulletins bulletins
*/
public static List<BulletinEntity> mergeBulletins(final Map<NodeIdentifier, List<BulletinEntity>> bulletins, final int totalNodes) {
final List<BulletinEntity> bulletinEntities = new ArrayList<>();
for (final Map.Entry<NodeIdentifier, List<BulletinEntity>> entry : bulletins.entrySet()) {
final NodeIdentifier nodeId = entry.getKey();
final List<BulletinEntity> nodeBulletins = entry.getValue();
final String nodeAddress = nodeId.getApiAddress() + ":" + nodeId.getApiPort();
for (final BulletinEntity bulletinEntity : nodeBulletins) {
if (bulletinEntity.getNodeAddress() == null) {
bulletinEntity.setNodeAddress(nodeAddress);
}
if (bulletinEntity.getCanRead() && bulletinEntity.getBulletin() != null && bulletinEntity.getBulletin().getNodeAddress() == null) {
bulletinEntity.getBulletin().setNodeAddress(nodeAddress);
}
bulletinEntities.add(bulletinEntity);
}
}
final List<BulletinEntity> entities = Lists.newArrayList();
// group by message when permissions allow
final Map<String, List<BulletinEntity>> groupingEntities = bulletinEntities.stream().filter(bulletinEntity -> bulletinEntity.getCanRead()).collect(Collectors.groupingBy(b -> b.getBulletin().getMessage()));
// add one from each grouped bulletin when all nodes report the same message
groupingEntities.forEach((message, groupedBulletinEntities) -> {
if (groupedBulletinEntities.size() == totalNodes) {
// get the most current bulletin
final BulletinEntity selectedBulletinEntity = groupedBulletinEntities.stream().max(Comparator.comparingLong(bulletinEntity -> {
if (bulletinEntity.getTimestamp() == null) {
return 0;
} else {
return bulletinEntity.getTimestamp().getTime();
}
})).orElse(null);
// should never be null, but just in case
if (selectedBulletinEntity != null) {
selectedBulletinEntity.setNodeAddress(ALL_NODES_MESSAGE);
selectedBulletinEntity.getBulletin().setNodeAddress(ALL_NODES_MESSAGE);
entities.add(selectedBulletinEntity);
}
} else {
// since all nodes didn't report the exact same bulletin, keep them all
entities.addAll(groupedBulletinEntities);
}
});
// ensure we also get the remainder of the bulletin entities
bulletinEntities.stream().filter(bulletinEntity -> !bulletinEntity.getCanRead()).forEach(entities::add);
// ensure the bulletins are sorted by time
Collections.sort(entities, (BulletinEntity o1, BulletinEntity o2) -> {
final int timeComparison = o1.getTimestamp().compareTo(o2.getTimestamp());
if (timeComparison != 0) {
return timeComparison;
}
return o1.getNodeAddress().compareTo(o2.getNodeAddress());
});
return entities;
}
use of org.apache.nifi.cluster.protocol.NodeIdentifier in project nifi by apache.
the class ComponentEntityMerger method merge.
/**
* Merges the ComponentEntity responses according to their {@link org.apache.nifi.web.api.dto.PermissionsDTO}s. Responsible for invoking
* {@link ComponentEntityMerger#mergeComponents(EntityType, Map)}.
*
* @param clientEntity the entity being returned to the client
* @param entityMap all node responses
*/
@SuppressWarnings("unchecked")
default void merge(final EntityType clientEntity, final Map<NodeIdentifier, EntityType> entityMap) {
for (final Map.Entry<NodeIdentifier, EntityType> entry : entityMap.entrySet()) {
final EntityType entity = entry.getValue();
PermissionsDtoMerger.mergePermissions(clientEntity.getPermissions(), entity.getPermissions());
}
if (clientEntity.getPermissions().getCanRead()) {
final Map<NodeIdentifier, List<BulletinEntity>> bulletinEntities = new HashMap<>();
for (final Map.Entry<NodeIdentifier, ? extends ComponentEntity> entry : entityMap.entrySet()) {
final NodeIdentifier nodeIdentifier = entry.getKey();
final ComponentEntity entity = entry.getValue();
// consider the bulletins if present and authorized
if (entity.getBulletins() != null) {
entity.getBulletins().forEach(bulletin -> {
bulletinEntities.computeIfAbsent(nodeIdentifier, nodeId -> new ArrayList<>()).add(bulletin);
});
}
}
clientEntity.setBulletins(BulletinMerger.mergeBulletins(bulletinEntities, entityMap.size()));
// sort the results
Collections.sort(clientEntity.getBulletins(), BULLETIN_COMPARATOR);
// prune the response to only include the max number of bulletins
if (clientEntity.getBulletins().size() > MAX_BULLETINS_PER_COMPONENT) {
clientEntity.setBulletins(clientEntity.getBulletins().subList(0, MAX_BULLETINS_PER_COMPONENT));
}
mergeComponents(clientEntity, entityMap);
} else {
clientEntity.setBulletins(null);
// unchecked warning suppressed
clientEntity.setComponent(null);
}
}
use of org.apache.nifi.cluster.protocol.NodeIdentifier in project nifi by apache.
the class ControllerServiceEntityMerger method mergeControllerServiceReferencingComponent.
private static void mergeControllerServiceReferencingComponent(ControllerServiceReferencingComponentEntity clientEntity, Map<NodeIdentifier, ControllerServiceReferencingComponentEntity> nodeEntities) {
final Map<String, Map<NodeIdentifier, PropertyDescriptorDTO>> propertyDescriptorMap = new HashMap<>();
final Map<NodeIdentifier, Set<ControllerServiceReferencingComponentEntity>> nodeReferencingComponentsMap = new HashMap<>();
// aggregate the property descriptors
for (Map.Entry<NodeIdentifier, ControllerServiceReferencingComponentEntity> entry : nodeEntities.entrySet()) {
final NodeIdentifier nodeIdentifier = entry.getKey();
final ControllerServiceReferencingComponentEntity nodeEntity = entry.getValue();
nodeEntity.getComponent().getDescriptors().values().stream().forEach(propertyDescriptor -> {
propertyDescriptorMap.computeIfAbsent(propertyDescriptor.getName(), nodeIdToPropertyDescriptor -> new HashMap<>()).put(nodeIdentifier, propertyDescriptor);
});
nodeReferencingComponentsMap.put(nodeIdentifier, nodeEntity.getComponent().getReferencingComponents());
}
// merge property descriptors
for (Map<NodeIdentifier, PropertyDescriptorDTO> propertyDescriptorByNodeId : propertyDescriptorMap.values()) {
final Collection<PropertyDescriptorDTO> nodePropertyDescriptors = propertyDescriptorByNodeId.values();
if (!nodePropertyDescriptors.isEmpty()) {
// get the name of the property descriptor and find that descriptor being returned to the client
final PropertyDescriptorDTO propertyDescriptor = nodePropertyDescriptors.iterator().next();
final PropertyDescriptorDTO clientPropertyDescriptor = clientEntity.getComponent().getDescriptors().get(propertyDescriptor.getName());
PropertyDescriptorDtoMerger.merge(clientPropertyDescriptor, propertyDescriptorByNodeId);
}
}
final Set<ControllerServiceReferencingComponentEntity> referencingComponents = clientEntity.getComponent().getReferencingComponents();
mergeControllerServiceReferences(referencingComponents, nodeReferencingComponentsMap);
}
use of org.apache.nifi.cluster.protocol.NodeIdentifier in project nifi by apache.
the class ControllerServiceEntityMerger method mergeControllerServiceReferences.
public static void mergeControllerServiceReferences(final Set<ControllerServiceReferencingComponentEntity> referencingComponents, final Map<NodeIdentifier, Set<ControllerServiceReferencingComponentEntity>> referencingComponentMap) {
final Map<String, Integer> activeThreadCounts = new HashMap<>();
final Map<String, String> states = new HashMap<>();
final Map<String, PermissionsDTO> canReads = new HashMap<>();
for (final Map.Entry<NodeIdentifier, Set<ControllerServiceReferencingComponentEntity>> nodeEntry : referencingComponentMap.entrySet()) {
final Set<ControllerServiceReferencingComponentEntity> nodeReferencingComponents = nodeEntry.getValue();
// go through all the nodes referencing components
if (nodeReferencingComponents != null) {
for (final ControllerServiceReferencingComponentEntity nodeReferencingComponentEntity : nodeReferencingComponents) {
final ControllerServiceReferencingComponentDTO nodeReferencingComponent = nodeReferencingComponentEntity.getComponent();
if (nodeReferencingComponentEntity.getPermissions().getCanRead()) {
// handle active thread counts
if (nodeReferencingComponent.getActiveThreadCount() != null && nodeReferencingComponent.getActiveThreadCount() > 0) {
final Integer current = activeThreadCounts.get(nodeReferencingComponent.getId());
if (current == null) {
activeThreadCounts.put(nodeReferencingComponent.getId(), nodeReferencingComponent.getActiveThreadCount());
} else {
activeThreadCounts.put(nodeReferencingComponent.getId(), nodeReferencingComponent.getActiveThreadCount() + current);
}
}
// handle controller service state
final String state = states.get(nodeReferencingComponent.getId());
if (state == null) {
if (ControllerServiceState.DISABLING.name().equals(nodeReferencingComponent.getState())) {
states.put(nodeReferencingComponent.getId(), ControllerServiceState.DISABLING.name());
} else if (ControllerServiceState.ENABLING.name().equals(nodeReferencingComponent.getState())) {
states.put(nodeReferencingComponent.getId(), ControllerServiceState.ENABLING.name());
}
}
}
// handle read permissions
final PermissionsDTO mergedPermissions = canReads.get(nodeReferencingComponentEntity.getId());
final PermissionsDTO permissions = nodeReferencingComponentEntity.getPermissions();
if (permissions != null) {
if (mergedPermissions == null) {
canReads.put(nodeReferencingComponentEntity.getId(), permissions);
} else {
PermissionsDtoMerger.mergePermissions(mergedPermissions, permissions);
}
}
}
}
}
// go through each referencing components
if (referencingComponents != null) {
for (final ControllerServiceReferencingComponentEntity referencingComponent : referencingComponents) {
final PermissionsDTO permissions = canReads.get(referencingComponent.getId());
if (permissions != null && permissions.getCanRead() != null && permissions.getCanRead()) {
final Integer activeThreadCount = activeThreadCounts.get(referencingComponent.getId());
if (activeThreadCount != null) {
referencingComponent.getComponent().setActiveThreadCount(activeThreadCount);
}
final String state = states.get(referencingComponent.getId());
if (state != null) {
referencingComponent.getComponent().setState(state);
}
final Map<NodeIdentifier, ControllerServiceReferencingComponentEntity> nodeEntities = new HashMap<>();
referencingComponentMap.entrySet().forEach(entry -> {
final NodeIdentifier nodeIdentifier = entry.getKey();
final Set<ControllerServiceReferencingComponentEntity> nodeControllerServiceReferencingComponents = entry.getValue();
nodeControllerServiceReferencingComponents.forEach(nodeControllerServiceReferencingComponent -> {
if (referencingComponent.getId() != null && referencingComponent.getId().equals(nodeControllerServiceReferencingComponent.getId())) {
nodeEntities.put(nodeIdentifier, nodeControllerServiceReferencingComponent);
}
});
});
mergeControllerServiceReferencingComponent(referencingComponent, nodeEntities);
} else {
referencingComponent.setPermissions(permissions);
referencingComponent.setComponent(null);
}
}
}
}
use of org.apache.nifi.cluster.protocol.NodeIdentifier in project nifi by apache.
the class PortEntityMerger method mergeDtos.
public static void mergeDtos(final PortDTO clientDto, final Map<NodeIdentifier, PortDTO> dtoMap) {
// if unauthorized for the client dto, simple return
if (clientDto == null) {
return;
}
final Map<String, Set<NodeIdentifier>> validationErrorMap = new HashMap<>();
for (final Map.Entry<NodeIdentifier, PortDTO> nodeEntry : dtoMap.entrySet()) {
final PortDTO nodePort = nodeEntry.getValue();
// merge the validation errors if authorized
if (nodePort != null) {
final NodeIdentifier nodeId = nodeEntry.getKey();
ErrorMerger.mergeErrors(validationErrorMap, nodeId, nodePort.getValidationErrors());
}
}
// set the merged the validation errors
clientDto.setValidationErrors(ErrorMerger.normalizedMergedErrors(validationErrorMap, dtoMap.size()));
}
Aggregations