@Test public void shouldRegisterNewHealthyHosts() { when(stackService.findByCrn(STACK_CRN)).thenReturn(stack); InstanceMetaData host1 = getHost("host1", "master", InstanceStatus.SERVICES_UNHEALTHY, InstanceGroupType.GATEWAY); when(instanceMetaDataService.findNotTerminatedForStack(eq(stack.getId()))).thenReturn(new HashSet<>(Arrays.asList(host1))); when(cloudbreakMessagesService.getMessage(any(), anyCollection())).thenReturn("recovery detected"); underTest.reportHealthChange(STACK_CRN, Set.of(), Set.of("host1")); verify(cloudbreakMessagesService).getMessage("cluster.recoverednodes.reported", Set.of("host1")); verify(cloudbreakEventService).fireCloudbreakEvent(STACK_ID, "AVAILABLE", CLUSTER_RECOVERED_NODES_REPORTED, List.of("host1")); assertEquals(InstanceStatus.SERVICES_HEALTHY, host1.getInstanceStatus()); }
public void reportHealthChange(String crn, Set<String> failedNodes, Set<String> newHealthyNodes) { if (!Sets.intersection(failedNodes, newHealthyNodes).isEmpty()) { throw new BadRequestException("Failed nodes " + failedNodes + " and healthy nodes " + newHealthyNodes + " should not have common items."); } if (failedNodes.isEmpty() && newHealthyNodes.isEmpty()) { return; } try { transactionService.required(() -> { Stack stack = stackService.findByCrn(crn); if (stack != null && !stack.getStatus().isInProgress()) { handleHealthChange(failedNodes, newHealthyNodes, stack); } else { LOGGER.debug("Stack [{}] status is {}, thus we do not handle failure report.", stack.getName(), stack.getStatus()); } return null; }); } catch (TransactionExecutionException e) { throw new TransactionRuntimeExecutionException(e); } }
ClusterOperationService { public void reportHealthChange(String crn, Set<String> failedNodes, Set<String> newHealthyNodes) { if (!Sets.intersection(failedNodes, newHealthyNodes).isEmpty()) { throw new BadRequestException("Failed nodes " + failedNodes + " and healthy nodes " + newHealthyNodes + " should not have common items."); } if (failedNodes.isEmpty() && newHealthyNodes.isEmpty()) { return; } try { transactionService.required(() -> { Stack stack = stackService.findByCrn(crn); if (stack != null && !stack.getStatus().isInProgress()) { handleHealthChange(failedNodes, newHealthyNodes, stack); } else { LOGGER.debug("Stack [{}] status is {}, thus we do not handle failure report.", stack.getName(), stack.getStatus()); } return null; }); } catch (TransactionExecutionException e) { throw new TransactionRuntimeExecutionException(e); } } }
ClusterOperationService { public void reportHealthChange(String crn, Set<String> failedNodes, Set<String> newHealthyNodes) { if (!Sets.intersection(failedNodes, newHealthyNodes).isEmpty()) { throw new BadRequestException("Failed nodes " + failedNodes + " and healthy nodes " + newHealthyNodes + " should not have common items."); } if (failedNodes.isEmpty() && newHealthyNodes.isEmpty()) { return; } try { transactionService.required(() -> { Stack stack = stackService.findByCrn(crn); if (stack != null && !stack.getStatus().isInProgress()) { handleHealthChange(failedNodes, newHealthyNodes, stack); } else { LOGGER.debug("Stack [{}] status is {}, thus we do not handle failure report.", stack.getName(), stack.getStatus()); } return null; }); } catch (TransactionExecutionException e) { throw new TransactionRuntimeExecutionException(e); } }  }
ClusterOperationService { public void reportHealthChange(String crn, Set<String> failedNodes, Set<String> newHealthyNodes) { if (!Sets.intersection(failedNodes, newHealthyNodes).isEmpty()) { throw new BadRequestException("Failed nodes " + failedNodes + " and healthy nodes " + newHealthyNodes + " should not have common items."); } if (failedNodes.isEmpty() && newHealthyNodes.isEmpty()) { return; } try { transactionService.required(() -> { Stack stack = stackService.findByCrn(crn); if (stack != null && !stack.getStatus().isInProgress()) { handleHealthChange(failedNodes, newHealthyNodes, stack); } else { LOGGER.debug("Stack [{}] status is {}, thus we do not handle failure report.", stack.getName(), stack.getStatus()); } return null; }); } catch (TransactionExecutionException e) { throw new TransactionRuntimeExecutionException(e); } }  @Measure(ClusterOperationService.class) Cluster create(Stack stack, Cluster cluster, List<ClusterComponent> components, User user); void delete(Long stackId, boolean forced); FlowIdentifier updateHosts(Long stackId, HostGroupAdjustmentV4Request hostGroupAdjustment); FlowIdentifier updateUserNamePassword(Long stackId, UserNamePasswordV4Request userNamePasswordJson); void reportHealthChange(String crn, Set<String> failedNodes, Set<String> newHealthyNodes); FlowIdentifier updateStatus(Long stackId, StatusRequest statusRequest); FlowIdentifier updateStatus(Stack stack, StatusRequest statusRequest); FlowIdentifier recreate(Stack stack, String blueprintName, Set<HostGroup> hostGroups, boolean validateBlueprint); FlowIdentifier triggerMaintenanceModeValidation(Stack stack); FlowIdentifier updateSalt(Stack stack); FlowIdentifier updatePillarConfiguration(Stack stack); FlowIdentifier rotateClusterCertificates(Stack stack, CertificatesRotationV4Request certificatesRotationV4Request); }
ClusterOperationService { public void reportHealthChange(String crn, Set<String> failedNodes, Set<String> newHealthyNodes) { if (!Sets.intersection(failedNodes, newHealthyNodes).isEmpty()) { throw new BadRequestException("Failed nodes " + failedNodes + " and healthy nodes " + newHealthyNodes + " should not have common items."); } if (failedNodes.isEmpty() && newHealthyNodes.isEmpty()) { return; } try { transactionService.required(() -> { Stack stack = stackService.findByCrn(crn); if (stack != null && !stack.getStatus().isInProgress()) { handleHealthChange(failedNodes, newHealthyNodes, stack); } else { LOGGER.debug("Stack [{}] status is {}, thus we do not handle failure report.", stack.getName(), stack.getStatus()); } return null; }); } catch (TransactionExecutionException e) { throw new TransactionRuntimeExecutionException(e); } }  @Measure(ClusterOperationService.class) Cluster create(Stack stack, Cluster cluster, List<ClusterComponent> components, User user); void delete(Long stackId, boolean forced); FlowIdentifier updateHosts(Long stackId, HostGroupAdjustmentV4Request hostGroupAdjustment); FlowIdentifier updateUserNamePassword(Long stackId, UserNamePasswordV4Request userNamePasswordJson); void reportHealthChange(String crn, Set<String> failedNodes, Set<String> newHealthyNodes); FlowIdentifier updateStatus(Long stackId, StatusRequest statusRequest); FlowIdentifier updateStatus(Stack stack, StatusRequest statusRequest); FlowIdentifier recreate(Stack stack, String blueprintName, Set<HostGroup> hostGroups, boolean validateBlueprint); FlowIdentifier triggerMaintenanceModeValidation(Stack stack); FlowIdentifier updateSalt(Stack stack); FlowIdentifier updatePillarConfiguration(Stack stack); FlowIdentifier rotateClusterCertificates(Stack stack, CertificatesRotationV4Request certificatesRotationV4Request);  }