use of com.sequenceiq.cloudbreak.common.event.AcceptResult in project cloudbreak by hortonworks.
the class Flow2Handler method handleFlowConflict.
private AcceptResult handleFlowConflict(String key, Payload payload, String flowChainId, Set<FlowLogIdWithTypeAndTimestamp> flowLogItems) {
AcceptResult acceptResult = null;
Optional<FlowLog> initFlowLog = flowLogService.findAllByFlowIdOrderByCreatedDesc(flowLogItems.iterator().next().getFlowId()).stream().min(Comparator.comparing(FlowLog::getCreated));
if (initFlowLog.isPresent()) {
LOGGER.info("Found previous init flow log: {}", initFlowLog.get());
if (NullUtil.allNotNull(initFlowLog.get().getFlowChainId(), flowChainId)) {
Optional<Pair<String, Payload>> previousTrigger = flowChains.getRootTriggerEvent(initFlowLog.get().getFlowChainId());
Optional<Pair<String, Payload>> currentTrigger = flowChains.getRootTriggerEvent(flowChainId);
if (previousTrigger.isPresent() && currentTrigger.isPresent()) {
if (isIdempotentTriggers(previousTrigger.get().getRight(), currentTrigger.get().getRight())) {
LOGGER.info("Idempotent flow chain trigger. Running {}, requested {}", previousTrigger, currentTrigger);
acceptResult = FlowAcceptResult.runningInFlowChain(previousTrigger.get().getLeft());
}
}
} else if (NullUtil.allNull(initFlowLog.get().getFlowChainId(), flowChainId)) {
Payload previousTrigger = FlowLogUtil.tryDeserializePayload(initFlowLog.get());
if (isIdempotentTriggers(previousTrigger, payload)) {
LOGGER.info("Idempotent flow trigger. Running {}, requested {}", previousTrigger, payload);
acceptResult = FlowAcceptResult.runningInFlow(initFlowLog.get().getFlowId());
}
}
}
if (acceptResult == null) {
LOGGER.info("Flow operation not allowed, other flow is running. Resource ID {}, event {}", payload.getResourceId(), key);
acceptResult = FlowAcceptResult.alreadyExistingFlow(flowLogItems);
}
flowChains.removeFullFlowChain(flowChainId, false);
return acceptResult;
}
use of com.sequenceiq.cloudbreak.common.event.AcceptResult in project cloudbreak by hortonworks.
the class Flow2Handler method doAccept.
private void doAccept(Event<? extends Payload> event, String key, Payload payload, String flowChainId, String flowChainType, FlowParameters flowParameters) {
try {
if (FLOW_CANCEL.equals(key)) {
cancelRunningFlows(payload.getResourceId());
} else if (FLOW_FINAL.equals(key)) {
finalizeFlow(flowParameters, flowChainId, payload.getResourceId(), getContextParams(event));
} else if (flowParameters.getFlowId() == null) {
AcceptResult result = handleNewFlowRequest(key, payload, flowParameters, flowChainId, flowChainType, getContextParams(event));
LOGGER.info("Create new flow result {}", result);
if (isAcceptablePayload(payload)) {
((Acceptable) payload).accepted().accept(result);
}
} else {
handleFlowControlEvent(key, payload, flowParameters, flowChainId);
}
} catch (FlowNotTriggerableException e) {
LOGGER.error("Failed to handle flow event.", e);
if (isAcceptablePayload(payload)) {
((Acceptable) payload).accepted().onError(e);
} else {
throw e;
}
} catch (CloudbreakServiceException e) {
LOGGER.error("Failed to handle flow event.", e);
throw e;
} catch (Exception e) {
LOGGER.error("Failed to handle flow event.", e);
throw new CloudbreakServiceException(e);
}
}
use of com.sequenceiq.cloudbreak.common.event.AcceptResult in project cloudbreak by hortonworks.
the class EventSender method doSend.
private FlowIdentifier doSend(BaseFlowEvent event, Event.Headers headers, String resourceName) {
Event<BaseFlowEvent> eventWithErrHandler = eventFactory.createEventWithErrHandler(new HashMap<>(headers.asMap()), event);
reactor.notify(event.selector(), eventWithErrHandler);
Promise<AcceptResult> accepted = eventWithErrHandler.getData().accepted();
String resourceCrn = event.getResourceCrn();
if (accepted != null) {
try {
FlowAcceptResult acceptResult = (FlowAcceptResult) accepted.await(TIMEOUT, TimeUnit.SECONDS);
return createFlowIdentifier(acceptResult, resourceCrn);
} catch (InterruptedException e) {
throw new IllegalStateException(e.getMessage());
}
}
if (headers.contains(FLOW_ID)) {
return new FlowIdentifier(FlowType.FLOW, headers.get(FLOW_ID));
} else if (headers.contains(FLOW_CHAIN_ID)) {
return new FlowIdentifier(FlowType.FLOW_CHAIN, headers.get(FLOW_CHAIN_ID));
}
LOGGER.error("Accepted is null, header does not contains flow or flow chain id, event: {}, header: {}", event, headers);
reactorReporter.logErrorReport();
throw new FlowNotAcceptedException(String.format("Timeout happened when trying to start the flow for stack %s.", resourceCrn));
}
use of com.sequenceiq.cloudbreak.common.event.AcceptResult in project cloudbreak by hortonworks.
the class FlowComponentTest method startNestedFlowChainThenWaitForComplete.
@Test
public void startNestedFlowChainThenWaitForComplete() throws InterruptedException {
long resourceId = RESOURCE_ID_SEC.incrementAndGet();
Promise<AcceptResult> accepted1 = new Promise<>();
SleepChainTriggerEvent sleepChainTriggerEvent1 = new SleepChainTriggerEvent(resourceId, Lists.newArrayList(new SleepConfig(SLEEP_TIME, SleepStartEvent.NEVER_FAIL)), accepted1);
SleepChainTriggerEvent sleepChainTriggerEvent2 = new SleepChainTriggerEvent(resourceId, Lists.newArrayList(new SleepConfig(SLEEP_TIME, SleepStartEvent.NEVER_FAIL)), accepted1);
NestedSleepChainTriggerEvent nestedSleepChainTriggerEvent1 = new NestedSleepChainTriggerEvent(resourceId, Lists.newArrayList(sleepChainTriggerEvent1, sleepChainTriggerEvent2), accepted1);
Promise<AcceptResult> accepted2 = new Promise<>();
SleepChainTriggerEvent sleepChainTriggerEvent3 = new SleepChainTriggerEvent(resourceId, Lists.newArrayList(new SleepConfig(SLEEP_TIME, SleepStartEvent.NEVER_FAIL)), accepted2);
SleepChainTriggerEvent sleepChainTriggerEvent4 = new SleepChainTriggerEvent(resourceId, Lists.newArrayList(new SleepConfig(SLEEP_TIME, SleepStartEvent.NEVER_FAIL)), accepted2);
NestedSleepChainTriggerEvent nestedSleepChainTriggerEvent2 = new NestedSleepChainTriggerEvent(resourceId, Lists.newArrayList(sleepChainTriggerEvent3, sleepChainTriggerEvent4), accepted2);
FlowAcceptResult acceptResult1 = startNestedSleepFlowChain(nestedSleepChainTriggerEvent1);
FlowAcceptResult acceptResult2 = startNestedSleepFlowChain(nestedSleepChainTriggerEvent2);
assertRunningInFlowChain(acceptResult1);
assertRunningInFlowChain(acceptResult2);
waitFlowChainToComplete(SLEEP_TIME.multipliedBy(WAIT_FACTOR), acceptResult1);
}
use of com.sequenceiq.cloudbreak.common.event.AcceptResult in project cloudbreak by hortonworks.
the class ReactorNotifierTest method testAcceptedReturnNull.
@Test(expected = FlowNotAcceptedException.class)
public void testAcceptedReturnNull() throws InterruptedException {
Stack stack = TestUtil.stack();
stack.setCluster(TestUtil.cluster());
when(stackService.getByIdWithTransaction(1L)).thenReturn(stack);
Acceptable data = mock(Acceptable.class);
Promise<AcceptResult> accepted = (Promise<AcceptResult>) mock(Promise.class);
when(data.accepted()).thenReturn(accepted);
when(data.getResourceId()).thenReturn(1L);
Event<Acceptable> event = new Event<>(data);
when(eventFactory.createEventWithErrHandler(anyMap(), any(Acceptable.class))).thenReturn(event);
when(accepted.await(10L, TimeUnit.SECONDS)).thenReturn(null);
underTest.notify(1L, "RANDOM", data, stackService::getByIdWithTransaction);
verify(reactorReporter, times(1)).logInfoReport();
verify(reactorReporter, times(1)).logErrorReport();
verify(reactor, times(1)).notify(eq("RANDOM"), eq(event));
verify(accepted, times(1)).await(10L, TimeUnit.SECONDS);
}
Aggregations