Search in sources :

Example 1 with PeriscopeNode

use of com.sequenceiq.periscope.domain.PeriscopeNode in project cloudbreak by hortonworks.

the class MetricTest method testLeaderElection.

@Test
public void testLeaderElection() {
    metricService.submit(MetricType.LEADER, 0);
    PeriscopeNode periscopeNode = new PeriscopeNode();
    when(periscopeNodeRepository.findById(periscopeNodeConfig.getId())).thenReturn(Optional.of(periscopeNode));
    leaderElectionService.leaderElection();
    MultiValueMap<String, String> metrics = responseToMap(readMetricsEndpoint());
    assertEquals(1.0, Double.parseDouble(metrics.get(toReportedMetricName(PERISCOPE_METRICS_LEADER, false)).get(0)), DELTA);
}
Also used : PeriscopeNode(com.sequenceiq.periscope.domain.PeriscopeNode) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) SpringBootTest(org.springframework.boot.test.context.SpringBootTest) Test(org.junit.Test)

Example 2 with PeriscopeNode

use of com.sequenceiq.periscope.domain.PeriscopeNode in project cloudbreak by hortonworks.

the class HeartbeatService method heartbeat.

private void heartbeat(boolean unLeaderIt) {
    if (periscopeNodeConfig.isNodeIdSpecified()) {
        String nodeId = periscopeNodeConfig.getId();
        try {
            retryService.testWith2SecDelayMax5Times(() -> {
                try {
                    PeriscopeNode self = periscopeNodeRepository.findById(nodeId).orElse(new PeriscopeNode(nodeId));
                    self.setLastUpdated(clock.getCurrentTimeMillis());
                    if (unLeaderIt) {
                        self.setLeader(false);
                    }
                    periscopeNodeRepository.save(self);
                } catch (RuntimeException e) {
                    LOGGER.error("Failed to update the heartbeat timestamp", e);
                    throw new ActionFailedException(e.getMessage());
                }
                return Boolean.TRUE;
            });
        } catch (ActionFailedException af) {
            LOGGER.error("Failed to update the heartbeat timestamp 5 times for node {}: {}", nodeId, af.getMessage());
            try {
                transactionService.required(() -> {
                    clusterRepository.deallocateClustersOfNode(nodeId);
                    return null;
                });
            } catch (TransactionExecutionException e) {
                LOGGER.error("Unable to deallocate clusters", e);
            }
        }
    }
}
Also used : PeriscopeNode(com.sequenceiq.periscope.domain.PeriscopeNode) ActionFailedException(com.sequenceiq.cloudbreak.service.Retry.ActionFailedException) TransactionExecutionException(com.sequenceiq.cloudbreak.common.service.TransactionService.TransactionExecutionException)

Example 3 with PeriscopeNode

use of com.sequenceiq.periscope.domain.PeriscopeNode in project cloudbreak by hortonworks.

the class LeaderElectionService method reallocateOrphanClusters.

private void reallocateOrphanClusters(List<PeriscopeNode> activeNodes) {
    if (activeNodes.stream().noneMatch(n -> n.isLeader() && n.getUuid().equals(periscopeNodeConfig.getId()))) {
        Optional<PeriscopeNode> leader = activeNodes.stream().filter(PeriscopeNode::isLeader).findFirst();
        LOGGER.info("Leader is {}, let's drop leader scope", leader.isPresent() ? leader.get().getUuid() : "-");
        resetTimer();
        return;
    }
    List<String> nodeIds = activeNodes.stream().map(PeriscopeNode::getUuid).collect(Collectors.toList());
    List<Cluster> orphanClusters = clusterRepository.findAllByPeriscopeNodeIdNotInOrPeriscopeNodeIdIsNull(nodeIds);
    if (!orphanClusters.isEmpty()) {
        Iterator<PeriscopeNode> iterator = activeNodes.iterator();
        for (Cluster cluster : orphanClusters) {
            if (!iterator.hasNext()) {
                iterator = activeNodes.iterator();
            }
            if (isExecutionOfMissedTimeBasedAlertsNeeded(cluster)) {
                LOGGER.info("Executing missed alerts on cluster {}", cluster.getId());
                executeMissedTimeBasedAlerts(cluster);
            }
            cluster.setPeriscopeNodeId(iterator.next().getUuid());
            LOGGER.info("Allocationg cluster {} to node {}", cluster.getId(), cluster.getPeriscopeNodeId());
        }
        clusterRepository.saveAll(orphanClusters);
    }
}
Also used : PeriscopeNode(com.sequenceiq.periscope.domain.PeriscopeNode) Cluster(com.sequenceiq.periscope.domain.Cluster)

Example 4 with PeriscopeNode

use of com.sequenceiq.periscope.domain.PeriscopeNode in project cloudbreak by hortonworks.

the class LeaderElectionService method leaderElection.

@Scheduled(initialDelay = 35000L, fixedDelay = 30000L)
public void leaderElection() {
    if (periscopeNodeConfig.isNodeIdSpecified()) {
        long leaders = periscopeNodeRepository.countByLeaderIsTrueAndLastUpdatedIsGreaterThan(clock.getCurrentTimeMillis() - heartbeatThresholdRate);
        if (leaders == 0L) {
            metricService.submit(MetricType.LEADER, 0);
            LOGGER.info("There is no active leader available");
            resetTimer();
            try {
                transactionService.required(() -> {
                    periscopeNodeRepository.deallocateLeader();
                    PeriscopeNode me = periscopeNodeRepository.findById(periscopeNodeConfig.getId()).orElseThrow(notFound("Periscope node", periscopeNodeConfig.getId()));
                    me.setLeader(true);
                    periscopeNodeRepository.save(me);
                    return null;
                });
            } catch (TransactionExecutionException e) {
                LOGGER.error("Failed to select node as leader, something went wrong. Message: {}", e.getMessage());
                return;
            }
            metricService.submit(MetricType.LEADER, 1);
            LOGGER.info("Selected {} as leader", periscopeNodeConfig.getId());
            timer.schedule(new TimerTask() {

                @Override
                public void run() {
                    try {
                        long limit = clock.getCurrentTimeMillis() - heartbeatThresholdRate;
                        List<PeriscopeNode> activeNodes = periscopeNodeRepository.findAllByLastUpdatedIsGreaterThan(limit);
                        if (!activeNodes.isEmpty()) {
                            reallocateOrphanClusters(activeNodes);
                            cleanupInactiveNodesByActiveNodes(activeNodes);
                        }
                    } catch (RuntimeException e) {
                        LOGGER.error("Error happend during fetching cluster allocating them to nodes", e);
                    }
                }
            }, LEADER_TASK_DELAY, STACK_COLLECTOR_PERIOD);
        }
    }
}
Also used : PeriscopeNode(com.sequenceiq.periscope.domain.PeriscopeNode) TimerTask(java.util.TimerTask) TransactionExecutionException(com.sequenceiq.cloudbreak.common.service.TransactionService.TransactionExecutionException) List(java.util.List) Scheduled(org.springframework.scheduling.annotation.Scheduled)

Example 5 with PeriscopeNode

use of com.sequenceiq.periscope.domain.PeriscopeNode in project cloudbreak by hortonworks.

the class LeaderElectionServiceTest method testReallocateOrphanClustersIsLeader.

@Test
public void testReallocateOrphanClustersIsLeader() throws TransactionExecutionException {
    when(periscopeNodeRepository.countByLeaderIsTrueAndLastUpdatedIsGreaterThan(anyLong())).thenReturn(0L);
    SpyTimer spyTimer = new SpyTimer();
    when(timerFactory.get()).thenReturn(spyTimer);
    PeriscopeNode leader = new PeriscopeNode("nodeid");
    leader.setLeader(true);
    when(periscopeNodeRepository.findAllByLastUpdatedIsGreaterThan(anyLong())).thenReturn(Collections.singletonList(leader));
    when(clusterRepository.findAllByPeriscopeNodeIdNotInOrPeriscopeNodeIdIsNull(any())).thenReturn(Collections.singletonList(new Cluster()));
    underTest.leaderElection();
    spyTimer.lastTask.run();
    verify(transactionService, times(2)).required(any(Supplier.class));
    verify(clusterRepository, times(1)).findAllByPeriscopeNodeIdNotInOrPeriscopeNodeIdIsNull(any(List.class));
    verify(clusterRepository, times(1)).saveAll(any(List.class));
}
Also used : PeriscopeNode(com.sequenceiq.periscope.domain.PeriscopeNode) Cluster(com.sequenceiq.periscope.domain.Cluster) Supplier(java.util.function.Supplier) List(java.util.List) Test(org.junit.Test)

Aggregations

PeriscopeNode (com.sequenceiq.periscope.domain.PeriscopeNode)5 TransactionExecutionException (com.sequenceiq.cloudbreak.common.service.TransactionService.TransactionExecutionException)2 Cluster (com.sequenceiq.periscope.domain.Cluster)2 List (java.util.List)2 Test (org.junit.Test)2 ActionFailedException (com.sequenceiq.cloudbreak.service.Retry.ActionFailedException)1 TimerTask (java.util.TimerTask)1 Supplier (java.util.function.Supplier)1 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)1 SpringBootTest (org.springframework.boot.test.context.SpringBootTest)1 Scheduled (org.springframework.scheduling.annotation.Scheduled)1