Search in sources :

Example 6 with YFlowRerouteRequest

use of org.openkilda.messaging.command.yflow.YFlowRerouteRequest in project open-kilda by telstra.

the class ValidateYFlowAction method performWithResponse.

@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, YFlowRerouteContext context, YFlowRerouteFsm stateMachine) {
    boolean isOperationAllowed = featureTogglesRepository.getOrDefault().getModifyYFlowEnabled();
    if (!isOperationAllowed) {
        throw new FlowProcessingException(ErrorType.NOT_PERMITTED, "Y-flow reroute feature is disabled");
    }
    YFlowRerouteRequest request = context.getRerouteRequest();
    String yFlowId = request.getYFlowId();
    Set<IslEndpoint> affectedIsls = new HashSet<>(Optional.ofNullable(request.getAffectedIsl()).orElse(emptySet()));
    dashboardLogger.onYFlowReroute(yFlowId, affectedIsls, request.isForce());
    stateMachine.setAffectedIsls(affectedIsls);
    stateMachine.setRerouteReason(request.getReason());
    stateMachine.setForceReroute(request.isForce());
    stateMachine.setIgnoreBandwidth(request.isIgnoreBandwidth());
    YFlow yFlow = transactionManager.doInTransaction(() -> {
        YFlow result = yFlowRepository.findById(yFlowId).orElseThrow(() -> new FlowProcessingException(ErrorType.NOT_FOUND, format("Y-flow %s not found", yFlowId)));
        if (result.getStatus() == FlowStatus.IN_PROGRESS) {
            throw new FlowProcessingException(ErrorType.REQUEST_INVALID, format("Y-flow %s is in progress now", yFlowId));
        }
        // Keep it, just in case we have to revert it.
        stateMachine.setOriginalYFlowStatus(result.getStatus());
        result.setStatus(FlowStatus.IN_PROGRESS);
        return result;
    });
    Collection<Flow> subFlows = yFlow.getSubFlows().stream().map(YSubFlow::getFlow).collect(Collectors.toList());
    Flow mainAffinitySubFlow = subFlows.stream().filter(flow -> flow.getFlowId().equals(flow.getAffinityGroupId())).findFirst().orElseThrow(() -> new FlowProcessingException(ErrorType.DATA_INVALID, format("Main affinity sub-flow of the y-flow %s not found", yFlowId)));
    stateMachine.setMainAffinityFlowId(mainAffinitySubFlow.getFlowId());
    boolean mainAffinitySubFlowIsAffected = isFlowAffected(mainAffinitySubFlow, affectedIsls);
    Set<String> affectedFlowIds = subFlows.stream().filter(flow -> mainAffinitySubFlowIsAffected || isFlowAffected(flow, affectedIsls)).map(Flow::getFlowId).collect(Collectors.toSet());
    stateMachine.setTargetSubFlowIds(affectedFlowIds);
    stateMachine.saveNewEventToHistory("Y-flow was validated successfully", FlowEventData.Event.REROUTE);
    return Optional.empty();
}
Also used : YFlow(org.openkilda.model.YFlow) IslEndpoint(org.openkilda.model.IslEndpoint) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) YFlowRerouteRequest(org.openkilda.messaging.command.yflow.YFlowRerouteRequest) HashSet(java.util.HashSet) Flow(org.openkilda.model.Flow) YFlow(org.openkilda.model.YFlow) YSubFlow(org.openkilda.model.YSubFlow)

Example 7 with YFlowRerouteRequest

use of org.openkilda.messaging.command.yflow.YFlowRerouteRequest in project open-kilda by telstra.

the class RerouteQueueServiceTest method shouldMergeAndSendRetryWithPendingRequestWhenReceivedFailedRuleInstallResponseOnTransitSwitchYFlow.

@Test
public void shouldMergeAndSendRetryWithPendingRequestWhenReceivedFailedRuleInstallResponseOnTransitSwitchYFlow() {
    FlowThrottlingData inProgress = getFlowThrottlingData(yFlow, CORRELATION_ID).build();
    FlowThrottlingData pending = FlowThrottlingData.builder().correlationId("pending").priority(7).timeCreate(yFlow.getTimeCreate()).affectedIsl(Collections.singleton(new IslEndpoint(SWITCH_ID_A, 1))).force(false).effectivelyDown(true).reason("another reason").yFlow(true).build();
    RerouteQueue rerouteQueue = RerouteQueue.builder().inProgress(inProgress).pending(pending).build();
    rerouteQueueService.getReroutes().put(YFLOW_ID, rerouteQueue);
    RerouteResultInfoData rerouteResultInfoData = RerouteResultInfoData.builder().flowId(YFLOW_ID).success(false).rerouteError(new SpeakerRequestError("Failed to install rules", Collections.singleton(SWITCH_C.getSwitchId()))).yFlow(true).build();
    rerouteQueueService.processRerouteResult(rerouteResultInfoData, CORRELATION_ID);
    String retryCorrelationId = CORRELATION_ID + " : retry #1 ignore_bw false";
    FlowThrottlingData expected = getFlowThrottlingData(yFlow, retryCorrelationId).build();
    expected.setPriority(pending.getPriority());
    expected.setReason(pending.getReason());
    assertEquals(expected, rerouteQueue.getInProgress());
    assertNull(rerouteQueue.getPending());
    assertNull(rerouteQueue.getThrottling());
    YFlowRerouteRequest expectedRequest = getYFlowRerouteRequest(YFLOW_ID, expected);
    verify(carrier).sendRerouteRequest(eq(retryCorrelationId), eq(expectedRequest));
}
Also used : IslEndpoint(org.openkilda.model.IslEndpoint) FlowThrottlingData(org.openkilda.wfm.topology.reroute.model.FlowThrottlingData) RerouteQueue(org.openkilda.wfm.topology.reroute.model.RerouteQueue) YFlowRerouteRequest(org.openkilda.messaging.command.yflow.YFlowRerouteRequest) RerouteResultInfoData(org.openkilda.messaging.info.reroute.RerouteResultInfoData) SpeakerRequestError(org.openkilda.messaging.info.reroute.error.SpeakerRequestError) Test(org.junit.Test)

Example 8 with YFlowRerouteRequest

use of org.openkilda.messaging.command.yflow.YFlowRerouteRequest in project open-kilda by telstra.

the class RerouteBolt method handleCommandMessage.

private void handleCommandMessage(CommandMessage commandMessage) {
    CommandData commandData = commandMessage.getData();
    String correlationId = getCommandContext().getCorrelationId();
    if (commandData instanceof RerouteAffectedFlows) {
        rerouteService.rerouteAffectedFlows(this, correlationId, (RerouteAffectedFlows) commandData);
    } else if (commandData instanceof RerouteAffectedInactiveFlows) {
        rerouteService.rerouteInactiveAffectedFlows(this, correlationId, ((RerouteAffectedInactiveFlows) commandData).getSwitchId());
    } else if (commandData instanceof RerouteInactiveFlows) {
        rerouteService.rerouteInactiveFlows(this, correlationId, (RerouteInactiveFlows) commandData);
    } else if (commandData instanceof FlowRerouteRequest) {
        rerouteService.processRerouteRequest(this, correlationId, (FlowRerouteRequest) commandData);
    } else if (commandData instanceof YFlowRerouteRequest) {
        rerouteService.processRerouteRequest(this, correlationId, (YFlowRerouteRequest) commandData);
    } else {
        unhandledInput(getCurrentTuple());
    }
}
Also used : YFlowRerouteRequest(org.openkilda.messaging.command.yflow.YFlowRerouteRequest) FlowRerouteRequest(org.openkilda.messaging.command.flow.FlowRerouteRequest) YFlowRerouteRequest(org.openkilda.messaging.command.yflow.YFlowRerouteRequest) RerouteAffectedFlows(org.openkilda.messaging.command.reroute.RerouteAffectedFlows) CommandData(org.openkilda.messaging.command.CommandData) RerouteInactiveFlows(org.openkilda.messaging.command.reroute.RerouteInactiveFlows) RerouteAffectedInactiveFlows(org.openkilda.messaging.command.reroute.RerouteAffectedInactiveFlows)

Example 9 with YFlowRerouteRequest

use of org.openkilda.messaging.command.yflow.YFlowRerouteRequest in project open-kilda by telstra.

the class RerouteQueueServiceTest method shouldSendManualRerouteRequestWithoutThrottlingForYFlow.

@Test
public void shouldSendManualRerouteRequestWithoutThrottlingForYFlow() {
    FlowThrottlingData throttling = getFlowThrottlingData(yFlow, "another one").build();
    RerouteQueue rerouteQueue = RerouteQueue.builder().throttling(throttling).build();
    rerouteQueueService.getReroutes().put(YFLOW_ID, rerouteQueue);
    FlowThrottlingData actual = getFlowThrottlingData(yFlow, CORRELATION_ID).build();
    rerouteQueueService.processManualRequest(YFLOW_ID, actual);
    assertEquals(1, rerouteQueueService.getReroutes().size());
    assertEquals(actual, rerouteQueue.getInProgress());
    assertNull(rerouteQueue.getPending());
    assertEquals(throttling, rerouteQueue.getThrottling());
    YFlowRerouteRequest expected = getYFlowRerouteRequest(YFLOW_ID, actual);
    verify(carrier).sendRerouteRequest(eq(CORRELATION_ID), eq(expected));
}
Also used : FlowThrottlingData(org.openkilda.wfm.topology.reroute.model.FlowThrottlingData) RerouteQueue(org.openkilda.wfm.topology.reroute.model.RerouteQueue) YFlowRerouteRequest(org.openkilda.messaging.command.yflow.YFlowRerouteRequest) Test(org.junit.Test)

Example 10 with YFlowRerouteRequest

use of org.openkilda.messaging.command.yflow.YFlowRerouteRequest in project open-kilda by telstra.

the class RouterBolt method handleInput.

@Override
protected void handleInput(Tuple input) {
    if (active) {
        String key = input.getStringByField(FIELD_ID_KEY);
        if (StringUtils.isBlank(key)) {
            // TODO: the key must be unique, but the correlationId comes in from outside and we can't guarantee that.
            // IMPORTANT: Storm may initiate reprocessing of the same tuple (e.g. in the case of timeout) and
            // cause creating multiple FSMs for the same tuple. This must be avoided.
            // As for now tuples are routed by the key field, and services can check FSM uniqueness.
            key = getCommandContext().getCorrelationId();
        }
        CommandMessage message = (CommandMessage) input.getValueByField(FIELD_ID_PAYLOAD);
        MessageData data = message.getData();
        if (data instanceof FlowRequest) {
            FlowRequest request = (FlowRequest) data;
            log.debug("Received request {} with key {}", request, key);
            Values values = new Values(key, request.getFlowId(), request);
            switch(request.getType()) {
                case CREATE:
                    emitWithContext(ROUTER_TO_FLOW_CREATE_HUB.name(), input, values);
                    break;
                case UPDATE:
                    emitWithContext(ROUTER_TO_FLOW_UPDATE_HUB.name(), input, values);
                    break;
                default:
                    throw new UnsupportedOperationException(format("Flow operation %s is not supported", request.getType()));
            }
        } else if (data instanceof FlowRerouteRequest) {
            FlowRerouteRequest rerouteRequest = (FlowRerouteRequest) data;
            log.debug("Received a reroute request {}/{} with key {}. MessageId {}", rerouteRequest.getFlowId(), rerouteRequest.getAffectedIsl(), key, input.getMessageId());
            Values values = new Values(key, rerouteRequest.getFlowId(), data);
            emitWithContext(ROUTER_TO_FLOW_REROUTE_HUB.name(), input, values);
        } else if (data instanceof FlowDeleteRequest) {
            FlowDeleteRequest deleteRequest = (FlowDeleteRequest) data;
            log.debug("Received a delete request {} with key {}. MessageId {}", deleteRequest.getFlowId(), key, input.getMessageId());
            Values values = new Values(key, deleteRequest.getFlowId(), data);
            emitWithContext(ROUTER_TO_FLOW_DELETE_HUB.name(), input, values);
        } else if (data instanceof FlowPathSwapRequest) {
            FlowPathSwapRequest pathSwapRequest = (FlowPathSwapRequest) data;
            log.debug("Received a path swap request {} with key {}. MessageId {}", pathSwapRequest.getFlowId(), key, input.getMessageId());
            Values values = new Values(key, pathSwapRequest.getFlowId(), data);
            emitWithContext(ROUTER_TO_FLOW_PATH_SWAP_HUB.name(), input, values);
        } else if (data instanceof SwapFlowEndpointRequest) {
            log.debug("Received a swap flow endpoints request with key {}. MessageId {}", key, input.getMessageId());
            emitWithContext(ROUTER_TO_FLOW_SWAP_ENDPOINTS_HUB.name(), input, new Values(key, data));
        } else if (data instanceof CreateFlowLoopRequest) {
            log.debug("Received a create flow loop request with key {}. MessageId {}", key, input.getMessageId());
            CreateFlowLoopRequest request = (CreateFlowLoopRequest) data;
            emitWithContext(ROUTER_TO_FLOW_UPDATE_HUB.name(), input, new Values(key, request.getFlowId(), data));
        } else if (data instanceof DeleteFlowLoopRequest) {
            log.debug("Received a delete flow loop request with key {}. MessageId {}", key, input.getMessageId());
            DeleteFlowLoopRequest request = (DeleteFlowLoopRequest) data;
            emitWithContext(ROUTER_TO_FLOW_UPDATE_HUB.name(), input, new Values(key, request.getFlowId(), data));
        } else if (data instanceof FlowMirrorPointCreateRequest) {
            log.debug("Received a flow mirror point create request with key {}. MessageId {}", key, input.getMessageId());
            FlowMirrorPointCreateRequest request = (FlowMirrorPointCreateRequest) data;
            emitWithContext(ROUTER_TO_FLOW_CREATE_MIRROR_POINT_HUB.name(), input, new Values(key, request.getFlowId(), data));
        } else if (data instanceof FlowMirrorPointDeleteRequest) {
            log.debug("Received a flow mirror point delete request with key {}. MessageId {}", key, input.getMessageId());
            FlowMirrorPointDeleteRequest request = (FlowMirrorPointDeleteRequest) data;
            emitWithContext(ROUTER_TO_FLOW_DELETE_MIRROR_POINT_HUB.name(), input, new Values(key, request.getFlowId(), data));
        } else if (data instanceof FlowValidationRequest) {
            log.debug("Received a flow validation request with key {}. MessageId {}", key, input.getMessageId());
            FlowValidationRequest request = (FlowValidationRequest) data;
            emitWithContext(ROUTER_TO_FLOW_VALIDATION_HUB.name(), input, new Values(key, request.getFlowId(), data));
        } else if (data instanceof YFlowRequest) {
            YFlowRequest request = (YFlowRequest) data;
            log.debug("Received request {} with key {}", request, key);
            Values values = new Values(key, request.getYFlowId(), request);
            switch(request.getType()) {
                case CREATE:
                    emitWithContext(ROUTER_TO_YFLOW_CREATE_HUB.name(), input, values);
                    break;
                case UPDATE:
                    emitWithContext(ROUTER_TO_YFLOW_UPDATE_HUB.name(), input, values);
                    break;
                default:
                    throw new UnsupportedOperationException(format("Y-flow operation %s is not supported", request.getType()));
            }
        } else if (data instanceof YFlowPartialUpdateRequest) {
            YFlowPartialUpdateRequest request = (YFlowPartialUpdateRequest) data;
            log.debug("Received a y-flow partial update request {} with key {}", request, key);
            emitWithContext(ROUTER_TO_YFLOW_UPDATE_HUB.name(), input, new Values(key, request.getYFlowId(), data));
        } else if (data instanceof YFlowRerouteRequest) {
            YFlowRerouteRequest request = (YFlowRerouteRequest) data;
            log.debug("Received a y-flow reroute request {} with key {}", data, key);
            emitWithContext(ROUTER_TO_YFLOW_REROUTE_HUB.name(), input, new Values(key, request.getYFlowId(), data));
        } else if (data instanceof YFlowDeleteRequest) {
            YFlowDeleteRequest request = (YFlowDeleteRequest) data;
            log.debug("Received a y-flow delete request {} with key {}", request, key);
            emitWithContext(ROUTER_TO_YFLOW_DELETE_HUB.name(), input, new Values(key, request.getYFlowId(), data));
        } else if (data instanceof YFlowsDumpRequest) {
            log.debug("Received a y-flow dump request {} with key {}", data, key);
            emitWithContext(ROUTER_TO_YFLOW_READ.name(), input, new Values(key, data));
        } else if (data instanceof YFlowReadRequest) {
            log.debug("Received a y-flow read request {} with key {}", data, key);
            emitWithContext(ROUTER_TO_YFLOW_READ.name(), input, new Values(key, data));
        } else if (data instanceof YFlowPathsReadRequest) {
            log.debug("Received a y-flow read path request {} with key {}", data, key);
            emitWithContext(ROUTER_TO_YFLOW_READ.name(), input, new Values(key, data));
        } else if (data instanceof SubFlowsReadRequest) {
            log.debug("Received a y-flow sub-flows request {} with key {}", data, key);
            emitWithContext(ROUTER_TO_YFLOW_READ.name(), input, new Values(key, data));
        } else if (data instanceof YFlowValidationRequest) {
            YFlowValidationRequest request = (YFlowValidationRequest) data;
            log.debug("Received a y-flow validation request {} with key {}", request, key);
            emitWithContext(ROUTER_TO_YFLOW_VALIDATION_HUB.name(), input, new Values(key, request.getYFlowId(), data));
        } else if (data instanceof YFlowSyncRequest) {
            YFlowSyncRequest request = (YFlowSyncRequest) data;
            log.debug("Received a y-flow synchronization request {} with key {}", request, key);
            YFlowRerouteRequest rerouteRequest = new YFlowRerouteRequest(request.getYFlowId(), emptySet(), true, "initiated via synchronization request", false);
            emitWithContext(ROUTER_TO_YFLOW_REROUTE_HUB.name(), input, new Values(key, rerouteRequest.getYFlowId(), rerouteRequest));
        } else {
            unhandledInput(input);
        }
    }
}
Also used : YFlowSyncRequest(org.openkilda.messaging.command.yflow.YFlowSyncRequest) YFlowRequest(org.openkilda.messaging.command.yflow.YFlowRequest) FlowRequest(org.openkilda.messaging.command.flow.FlowRequest) FlowDeleteRequest(org.openkilda.messaging.command.flow.FlowDeleteRequest) YFlowDeleteRequest(org.openkilda.messaging.command.yflow.YFlowDeleteRequest) CreateFlowLoopRequest(org.openkilda.messaging.command.flow.CreateFlowLoopRequest) Values(org.apache.storm.tuple.Values) SwapFlowEndpointRequest(org.openkilda.messaging.command.flow.SwapFlowEndpointRequest) YFlowRequest(org.openkilda.messaging.command.yflow.YFlowRequest) YFlowsDumpRequest(org.openkilda.messaging.command.yflow.YFlowsDumpRequest) YFlowDeleteRequest(org.openkilda.messaging.command.yflow.YFlowDeleteRequest) FlowPathSwapRequest(org.openkilda.messaging.command.flow.FlowPathSwapRequest) FlowRerouteRequest(org.openkilda.messaging.command.flow.FlowRerouteRequest) YFlowRerouteRequest(org.openkilda.messaging.command.yflow.YFlowRerouteRequest) YFlowPartialUpdateRequest(org.openkilda.messaging.command.yflow.YFlowPartialUpdateRequest) FlowMirrorPointDeleteRequest(org.openkilda.messaging.command.flow.FlowMirrorPointDeleteRequest) DeleteFlowLoopRequest(org.openkilda.messaging.command.flow.DeleteFlowLoopRequest) MessageData(org.openkilda.messaging.MessageData) FlowMirrorPointCreateRequest(org.openkilda.messaging.command.flow.FlowMirrorPointCreateRequest) CommandMessage(org.openkilda.messaging.command.CommandMessage) YFlowValidationRequest(org.openkilda.messaging.command.yflow.YFlowValidationRequest) FlowValidationRequest(org.openkilda.messaging.command.flow.FlowValidationRequest) YFlowValidationRequest(org.openkilda.messaging.command.yflow.YFlowValidationRequest) YFlowRerouteRequest(org.openkilda.messaging.command.yflow.YFlowRerouteRequest) YFlowReadRequest(org.openkilda.messaging.command.yflow.YFlowReadRequest) YFlowPathsReadRequest(org.openkilda.messaging.command.yflow.YFlowPathsReadRequest) SubFlowsReadRequest(org.openkilda.messaging.command.yflow.SubFlowsReadRequest)

Aggregations

YFlowRerouteRequest (org.openkilda.messaging.command.yflow.YFlowRerouteRequest)20 Test (org.junit.Test)13 YFlowRequest (org.openkilda.messaging.command.yflow.YFlowRequest)11 AbstractYFlowTest (org.openkilda.wfm.topology.flowhs.service.AbstractYFlowTest)10 RerouteError (org.openkilda.messaging.info.reroute.error.RerouteError)5 IslEndpoint (org.openkilda.model.IslEndpoint)5 FlowRerouteRequest (org.openkilda.messaging.command.flow.FlowRerouteRequest)4 CommandContext (org.openkilda.wfm.CommandContext)3 FlowThrottlingData (org.openkilda.wfm.topology.reroute.model.FlowThrottlingData)3 MessageData (org.openkilda.messaging.MessageData)2 CommandMessage (org.openkilda.messaging.command.CommandMessage)2 FlowPathSwapRequest (org.openkilda.messaging.command.flow.FlowPathSwapRequest)2 RerouteResultInfoData (org.openkilda.messaging.info.reroute.RerouteResultInfoData)2 UnroutableFlowException (org.openkilda.pce.exception.UnroutableFlowException)2 RerouteQueue (org.openkilda.wfm.topology.reroute.model.RerouteQueue)2 HashSet (java.util.HashSet)1 Values (org.apache.storm.tuple.Values)1 CommandData (org.openkilda.messaging.command.CommandData)1 CreateFlowLoopRequest (org.openkilda.messaging.command.flow.CreateFlowLoopRequest)1 DeleteFlowLoopRequest (org.openkilda.messaging.command.flow.DeleteFlowLoopRequest)1