Search in sources :

Example 16 with FlowSegmentRequestFactory

use of org.openkilda.floodlight.api.request.factory.FlowSegmentRequestFactory in project open-kilda by telstra.

the class OnReceivedInstallResponseAction method perform.

@Override
protected void perform(State from, State to, Event event, FlowUpdateContext context, FlowUpdateFsm stateMachine) {
    SpeakerFlowSegmentResponse response = context.getSpeakerFlowResponse();
    UUID commandId = response.getCommandId();
    FlowSegmentRequestFactory command = stateMachine.getInstallCommand(commandId);
    if (!stateMachine.getPendingCommands().containsKey(commandId) || command == null) {
        log.info("Received a response for unexpected command: {}", response);
        return;
    }
    if (response.isSuccess()) {
        stateMachine.removePendingCommand(commandId);
        stateMachine.saveActionToHistory("Rule was installed", format("The rule was installed: switch %s, cookie %s", response.getSwitchId(), command.getCookie()));
    } else {
        FlowErrorResponse errorResponse = (FlowErrorResponse) response;
        int attempt = stateMachine.doRetryForCommand(commandId);
        if (attempt <= speakerCommandRetriesLimit) {
            stateMachine.saveErrorToHistory(FAILED_TO_INSTALL_RULE_ACTION, format("Failed to install the rule: commandId %s, switch %s, cookie %s. Error %s. " + "Retrying (attempt %d)", commandId, errorResponse.getSwitchId(), command.getCookie(), errorResponse, attempt));
            stateMachine.getCarrier().sendSpeakerRequest(command.makeInstallRequest(commandId));
        } else if (stateMachine.isDoNotRevert()) {
            stateMachine.removePendingCommand(commandId);
            stateMachine.saveErrorToHistory(FAILED_TO_INSTALL_RULE_ACTION, format("Failed to install the rule: commandId %s, switch %s, cookie %s. Error %s. " + "Skipping installing attempts", commandId, errorResponse.getSwitchId(), command.getCookie(), errorResponse));
            stateMachine.setNewFlowStatus(FlowStatus.DOWN);
            stateMachine.setErrorReason(FAILED_TO_INSTALL_RULE_ACTION);
        } else {
            stateMachine.removePendingCommand(commandId);
            stateMachine.saveErrorToHistory(FAILED_TO_INSTALL_RULE_ACTION, format("Failed to install the rule: commandId %s, switch %s, cookie %s. Error: %s", commandId, errorResponse.getSwitchId(), command.getCookie(), errorResponse));
            stateMachine.addFailedCommand(commandId, errorResponse);
        }
    }
    if (stateMachine.getPendingCommands().isEmpty()) {
        if (stateMachine.getFailedCommands().isEmpty()) {
            log.debug("Received responses for all pending install commands of the flow {}", stateMachine.getFlowId());
            stateMachine.fire(Event.RULES_INSTALLED);
        } else {
            String errorMessage = format("Received error response(s) for %d install commands", stateMachine.getFailedCommands().size());
            stateMachine.saveErrorToHistory(errorMessage);
            stateMachine.fireError(errorMessage);
        }
    }
}
Also used : FlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.FlowSegmentRequestFactory) FlowErrorResponse(org.openkilda.floodlight.flow.response.FlowErrorResponse) SpeakerFlowSegmentResponse(org.openkilda.floodlight.api.response.SpeakerFlowSegmentResponse) UUID(java.util.UUID)

Example 17 with FlowSegmentRequestFactory

use of org.openkilda.floodlight.api.request.factory.FlowSegmentRequestFactory in project open-kilda by telstra.

the class SpeakerFlowSegmentRequestBuilderTest method useActualFlowEndpoint.

@Test
public void useActualFlowEndpoint() {
    Switch srcSwitch = Switch.builder().switchId(SWITCH_1).build();
    Switch destSwitch = Switch.builder().switchId(SWITCH_2).build();
    // having flow stored in DB
    Flow origin = buildFlow(srcSwitch, 1, 5, destSwitch, 2, 0, 0);
    setSegmentsWithoutTransitSwitches(Objects.requireNonNull(origin.getForwardPath()), Objects.requireNonNull(origin.getReversePath()));
    // then new set of paths are created
    FlowPath goalForwardPath = buildFlowPath(origin, origin.getSrcSwitch(), origin.getDestSwitch(), new FlowSegmentCookie(FlowPathDirection.FORWARD, cookieFactory.next()));
    FlowPath goalReversePath = buildFlowPath(origin, origin.getDestSwitch(), origin.getSrcSwitch(), new FlowSegmentCookie(FlowPathDirection.REVERSE, cookieFactory.next()));
    setSegmentsWithTransitSwitches(goalForwardPath, goalReversePath);
    // than new version of flow is created to fulfill update request
    Flow goal = Flow.builder().flowId(origin.getFlowId()).srcSwitch(origin.getSrcSwitch()).srcPort(origin.getSrcPort()).srcVlan(// update
    origin.getSrcVlan() + 10).destSwitch(origin.getDestSwitch()).destPort(origin.getDestPort()).destVlan(origin.getDestVlan()).bandwidth(origin.getBandwidth()).encapsulationType(origin.getEncapsulationType()).build();
    // emulate db behaviour - flow will have "existing" paths after fetching it from DB
    goal.setForwardPath(origin.getForwardPath());
    goal.setReversePath(origin.getReversePath());
    goal.addPaths(goalForwardPath, goalReversePath);
    // then produce path segment request factories
    List<FlowSegmentRequestFactory> commands = target.buildIngressOnly(COMMAND_CONTEXT, goal, goalForwardPath, goalReversePath, SpeakerRequestBuildContext.getEmpty());
    boolean haveMatch = false;
    for (FlowSegmentRequestFactory entry : commands) {
        // search command for flow source side
        if (SWITCH_1.equals(entry.getSwitchId())) {
            haveMatch = true;
            Assert.assertTrue(entry instanceof IngressFlowSegmentRequestFactory);
            IngressFlowSegmentRequestFactory segment = (IngressFlowSegmentRequestFactory) entry;
            IngressFlowSegmentRequest request = segment.makeInstallRequest(commandIdGenerator.generate());
            Assert.assertEquals(goal.getSrcVlan(), request.getEndpoint().getOuterVlanId());
        }
    }
    Assert.assertTrue(haveMatch);
}
Also used : IngressFlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.IngressFlowSegmentRequestFactory) FlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.FlowSegmentRequestFactory) FlowSegmentCookie(org.openkilda.model.cookie.FlowSegmentCookie) IngressFlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.IngressFlowSegmentRequestFactory) Switch(org.openkilda.model.Switch) IngressFlowSegmentRequest(org.openkilda.floodlight.api.request.IngressFlowSegmentRequest) FlowPath(org.openkilda.model.FlowPath) Flow(org.openkilda.model.Flow) InMemoryGraphBasedTest(org.openkilda.persistence.inmemory.InMemoryGraphBasedTest) Test(org.junit.Test)

Example 18 with FlowSegmentRequestFactory

use of org.openkilda.floodlight.api.request.factory.FlowSegmentRequestFactory in project open-kilda by telstra.

the class SpeakerFlowSegmentRequestBuilder method makeRequests.

private List<FlowSegmentRequestFactory> makeRequests(CommandContext context, Flow flow, FlowPath path, FlowPath oppositePath, boolean doIngress, boolean doTransit, boolean doEgress, SpeakerRequestBuildContext speakerRequestBuildContext, MirrorContext mirrorContext) {
    // TODO: this swap is weird, need to clean this up and not to rely on luck.
    if (path == null) {
        path = oppositePath;
        oppositePath = null;
        speakerRequestBuildContext = SpeakerRequestBuildContext.builder().forward(speakerRequestBuildContext.getReverse()).reverse(speakerRequestBuildContext.getForward()).build();
    }
    if (path == null) {
        throw new IllegalArgumentException("At least one flow path must be not null");
    }
    boolean isDeleteOperation = speakerRequestBuildContext.isDeleteOperation();
    FlowTransitEncapsulation encapsulation = null;
    if (!flow.isOneSwitchFlow()) {
        try {
            encapsulation = getEncapsulation(flow.getEncapsulationType(), path.getPathId(), oppositePath != null ? oppositePath.getPathId() : null);
        } catch (IllegalStateException e) {
            if (!isDeleteOperation) {
                throw e;
            }
            encapsulation = DELETE_ENCAPSULATION_STUB;
        }
    }
    List<FlowSegmentRequestFactory> requests = new ArrayList<>(makePathRequests(flow, path, context, encapsulation, doIngress, doTransit, doEgress, createRulesContext(speakerRequestBuildContext.getForward()), mirrorContext));
    if (oppositePath != null) {
        if (!flow.isOneSwitchFlow()) {
            try {
                encapsulation = getEncapsulation(flow.getEncapsulationType(), oppositePath.getPathId(), path.getPathId());
            } catch (IllegalStateException e) {
                if (!isDeleteOperation) {
                    throw e;
                }
                encapsulation = DELETE_ENCAPSULATION_STUB;
            }
        }
        requests.addAll(makePathRequests(flow, oppositePath, context, encapsulation, doIngress, doTransit, doEgress, createRulesContext(speakerRequestBuildContext.getReverse()), mirrorContext));
    }
    return requests;
}
Also used : IngressMirrorFlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.IngressMirrorFlowSegmentRequestFactory) IngressFlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.IngressFlowSegmentRequestFactory) EgressMirrorFlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.EgressMirrorFlowSegmentRequestFactory) EgressFlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.EgressFlowSegmentRequestFactory) TransitFlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.TransitFlowSegmentRequestFactory) FlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.FlowSegmentRequestFactory) ArrayList(java.util.ArrayList) FlowTransitEncapsulation(org.openkilda.model.FlowTransitEncapsulation)

Example 19 with FlowSegmentRequestFactory

use of org.openkilda.floodlight.api.request.factory.FlowSegmentRequestFactory in project open-kilda by telstra.

the class SpeakerFlowSegmentRequestBuilder method makeOneSwitchRequest.

private List<FlowSegmentRequestFactory> makeOneSwitchRequest(CommandContext context, FlowPath path, FlowSideAdapter ingressSide, FlowSideAdapter egressSide, RulesContext rulesContext, MirrorContext mirrorContext) {
    Flow flow = ingressSide.getFlow();
    UUID commandId = commandIdGenerator.generate();
    MessageContext messageContext = new MessageContext(commandId.toString(), context.getCorrelationId());
    FlowSegmentMetadata metadata = makeMetadata(path, ensureEqualMultiTableFlag(path.isSrcWithMultiTable(), path.isDestWithMultiTable(), String.format("Flow(id:%s) have incompatible for one-switch flow per-side multi-table flags - " + "src(%s) != dst(%s)", flow.getFlowId(), path.isSrcWithMultiTable(), path.isDestWithMultiTable())));
    List<FlowSegmentRequestFactory> oneSwitchFactories = new ArrayList<>();
    if (!mirrorContext.isBuildMirrorFactoryOnly()) {
        oneSwitchFactories.add(OneSwitchFlowRequestFactory.builder().messageContext(messageContext).metadata(metadata).endpoint(ingressSide.getEndpoint()).meterConfig(getMeterConfig(path)).egressEndpoint(egressSide.getEndpoint()).rulesContext(rulesContext).build());
    }
    Optional<MirrorConfig> mirrorConfig = makeMirrorConfig(path, egressSide.getEndpoint(), mirrorContext);
    if (mirrorConfig.isPresent() || mirrorContext.isRemoveFlowOperation()) {
        FlowSegmentCookie mirrorCookie = path.getCookie().toBuilder().mirror(true).build();
        oneSwitchFactories.add(OneSwitchMirrorFlowRequestFactory.builder().messageContext(new MessageContext(commandIdGenerator.generate().toString(), context.getCorrelationId())).metadata(makeMetadata(metadata.getFlowId(), mirrorCookie, metadata.isMultiTable())).endpoint(ingressSide.getEndpoint()).meterConfig(getMeterConfig(path)).egressEndpoint(egressSide.getEndpoint()).rulesContext(rulesContext).mirrorConfig(mirrorConfig.orElse(null)).build());
    }
    return oneSwitchFactories;
}
Also used : IngressMirrorFlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.IngressMirrorFlowSegmentRequestFactory) IngressFlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.IngressFlowSegmentRequestFactory) EgressMirrorFlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.EgressMirrorFlowSegmentRequestFactory) EgressFlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.EgressFlowSegmentRequestFactory) TransitFlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.TransitFlowSegmentRequestFactory) FlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.FlowSegmentRequestFactory) FlowSegmentCookie(org.openkilda.model.cookie.FlowSegmentCookie) MirrorConfig(org.openkilda.model.MirrorConfig) ArrayList(java.util.ArrayList) MessageContext(org.openkilda.messaging.MessageContext) UUID(java.util.UUID) FlowSegmentMetadata(org.openkilda.floodlight.model.FlowSegmentMetadata) Flow(org.openkilda.model.Flow)

Example 20 with FlowSegmentRequestFactory

use of org.openkilda.floodlight.api.request.factory.FlowSegmentRequestFactory in project open-kilda by telstra.

the class SpeakerFlowSegmentRequestBuilder method makeEgressSegmentRequests.

private List<FlowSegmentRequestFactory> makeEgressSegmentRequests(CommandContext context, FlowPath path, FlowTransitEncapsulation encapsulation, PathSegment segment, FlowSideAdapter flowSide, FlowSideAdapter ingressFlowSide, MirrorContext mirrorContext) {
    Flow flow = flowSide.getFlow();
    PathSegmentSide segmentSide = makePathSegmentDestSide(segment);
    UUID commandId = commandIdGenerator.generate();
    MessageContext messageContext = new MessageContext(commandId.toString(), context.getCorrelationId());
    FlowSegmentMetadata metadata = makeMetadata(path, ensureEqualMultiTableFlag(segmentSide.isMultiTable(), path.isDestWithMultiTable(), String.format("Last flow(id:%s, path:%s) segment and flow path level multi-table flags value " + "are incompatible to each other - segment(%s) != flow path(%s)", flow.getFlowId(), path.getPathId(), segmentSide.isMultiTable(), path.isDestWithMultiTable())));
    List<FlowSegmentRequestFactory> egressFactories = new ArrayList<>();
    if (!mirrorContext.isBuildMirrorFactoryOnly()) {
        egressFactories.add(EgressFlowSegmentRequestFactory.builder().messageContext(messageContext).metadata(metadata).endpoint(flowSide.getEndpoint()).ingressEndpoint(ingressFlowSide.getEndpoint()).islPort(segmentSide.getEndpoint().getPortNumber()).encapsulation(encapsulation).build());
    }
    Optional<MirrorConfig> mirrorConfig = makeMirrorConfig(path, flowSide.getEndpoint(), mirrorContext);
    if (mirrorConfig.isPresent() || mirrorContext.isRemoveFlowOperation()) {
        FlowSegmentCookie mirrorCookie = path.getCookie().toBuilder().mirror(true).build();
        egressFactories.add(EgressMirrorFlowSegmentRequestFactory.builder().messageContext(new MessageContext(commandIdGenerator.generate().toString(), context.getCorrelationId())).metadata(makeMetadata(metadata.getFlowId(), mirrorCookie, metadata.isMultiTable())).endpoint(flowSide.getEndpoint()).ingressEndpoint(ingressFlowSide.getEndpoint()).islPort(segmentSide.getEndpoint().getPortNumber()).encapsulation(encapsulation).mirrorConfig(mirrorConfig.orElse(null)).build());
    }
    return egressFactories;
}
Also used : IngressMirrorFlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.IngressMirrorFlowSegmentRequestFactory) IngressFlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.IngressFlowSegmentRequestFactory) EgressMirrorFlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.EgressMirrorFlowSegmentRequestFactory) EgressFlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.EgressFlowSegmentRequestFactory) TransitFlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.TransitFlowSegmentRequestFactory) FlowSegmentRequestFactory(org.openkilda.floodlight.api.request.factory.FlowSegmentRequestFactory) FlowSegmentCookie(org.openkilda.model.cookie.FlowSegmentCookie) MirrorConfig(org.openkilda.model.MirrorConfig) ArrayList(java.util.ArrayList) MessageContext(org.openkilda.messaging.MessageContext) UUID(java.util.UUID) FlowSegmentMetadata(org.openkilda.floodlight.model.FlowSegmentMetadata) Flow(org.openkilda.model.Flow)

Aggregations

FlowSegmentRequestFactory (org.openkilda.floodlight.api.request.factory.FlowSegmentRequestFactory)53 UUID (java.util.UUID)33 Flow (org.openkilda.model.Flow)21 ArrayList (java.util.ArrayList)19 FlowErrorResponse (org.openkilda.floodlight.flow.response.FlowErrorResponse)15 SpeakerFlowSegmentResponse (org.openkilda.floodlight.api.response.SpeakerFlowSegmentResponse)14 FlowCommandBuilder (org.openkilda.wfm.topology.flowhs.service.FlowCommandBuilder)14 FlowPath (org.openkilda.model.FlowPath)12 IngressFlowSegmentRequestFactory (org.openkilda.floodlight.api.request.factory.IngressFlowSegmentRequestFactory)11 SpeakerRequestBuildContext (org.openkilda.wfm.share.model.SpeakerRequestBuildContext)11 FlowSegmentRequest (org.openkilda.floodlight.api.request.FlowSegmentRequest)9 EgressMirrorFlowSegmentRequestFactory (org.openkilda.floodlight.api.request.factory.EgressMirrorFlowSegmentRequestFactory)7 EgressFlowSegmentRequestFactory (org.openkilda.floodlight.api.request.factory.EgressFlowSegmentRequestFactory)6 IngressMirrorFlowSegmentRequestFactory (org.openkilda.floodlight.api.request.factory.IngressMirrorFlowSegmentRequestFactory)6 TransitFlowSegmentRequestFactory (org.openkilda.floodlight.api.request.factory.TransitFlowSegmentRequestFactory)6 Switch (org.openkilda.model.Switch)5 FlowSegmentCookie (org.openkilda.model.cookie.FlowSegmentCookie)5 MirrorContext (org.openkilda.wfm.share.model.MirrorContext)5 Test (org.junit.Test)4 SpeakerResponse (org.openkilda.floodlight.api.response.SpeakerResponse)4