Search in sources :

Example 1 with OFErrorMsg

use of org.projectfloodlight.openflow.protocol.OFErrorMsg in project open-kilda by telstra.

the class MeterInstallCommand method handleOfError.

@Override
public CompletableFuture<Optional<OFMessage>> handleOfError(OFErrorMsg response) {
    CompletableFuture<Optional<OFMessage>> future = new CompletableFuture<>();
    if (!isInstallConflict(response)) {
        future.completeExceptionally(new SwitchErrorResponseException(getSw().getId(), String.format("Can't install meter %s - %s", meterConfig.getId(), response)));
        return future;
    }
    log.info("Meter conflict detected sw:{} meter:{}", getSw().getId(), meterConfig.getId());
    MeterVerifyCommand verifyCommand = new MeterVerifyCommand(messageContext, switchId, meterConfig);
    propagateFutureResponse(future, commandProcessor.chain(verifyCommand).thenAccept(this::handleMeterVerify).thenApply(ignore -> Optional.empty()));
    return future;
}
Also used : SwitchMissingMeterException(org.openkilda.floodlight.error.SwitchMissingMeterException) OFMeterModFailedErrorMsg(org.projectfloodlight.openflow.protocol.errormsg.OFMeterModFailedErrorMsg) Getter(lombok.Getter) InvalidMeterIdException(org.openkilda.floodlight.error.InvalidMeterIdException) Session(org.openkilda.floodlight.service.session.Session) OFMeterModFailedCode(org.projectfloodlight.openflow.protocol.OFMeterModFailedCode) MessageContext(org.openkilda.messaging.MessageContext) CompletableFuture(java.util.concurrent.CompletableFuture) SwitchIncorrectMeterException(org.openkilda.floodlight.error.SwitchIncorrectMeterException) UnsupportedSwitchOperationException(org.openkilda.floodlight.error.UnsupportedSwitchOperationException) MeterId(org.openkilda.model.MeterId) SwitchId(org.openkilda.model.SwitchId) SpeakerCommandProcessor(org.openkilda.floodlight.command.SpeakerCommandProcessor) OFMeterMod(org.projectfloodlight.openflow.protocol.OFMeterMod) MeterConfig(org.openkilda.model.MeterConfig) OFMessage(org.projectfloodlight.openflow.protocol.OFMessage) Optional(java.util.Optional) OFErrorMsg(org.projectfloodlight.openflow.protocol.OFErrorMsg) IOfErrorResponseHandler(org.openkilda.floodlight.command.IOfErrorResponseHandler) SwitchErrorResponseException(org.openkilda.floodlight.error.SwitchErrorResponseException) SwitchMeterConflictException(org.openkilda.floodlight.error.SwitchMeterConflictException) CompletableFuture(java.util.concurrent.CompletableFuture) Optional(java.util.Optional) SwitchErrorResponseException(org.openkilda.floodlight.error.SwitchErrorResponseException)

Example 2 with OFErrorMsg

use of org.projectfloodlight.openflow.protocol.OFErrorMsg in project open-kilda by telstra.

the class OfBatchExecutor method executeBatch.

/**
 * Execute current batch of commands.
 */
public void executeBatch() {
    log.debug("Execute batch start (key={})", kafkaKey);
    List<UUID> stageCommandsUuids = holder.getCurrentStage();
    List<OFMessage> ofMessages = new ArrayList<>();
    for (UUID uuid : stageCommandsUuids) {
        log.debug("Start processing UUID: {} (key={})", uuid, kafkaKey);
        if (holder.canExecute(uuid)) {
            BatchData batchData = holder.getByUUid(uuid);
            hasFlows |= batchData.isFlow();
            hasMeters |= batchData.isMeter();
            hasGroups |= batchData.isGroup();
            ofMessages.add(batchData.getMessage());
        } else {
            Map<UUID, String> blockingDependencies = holder.getBlockingDependencies(uuid);
            holder.recordFailedUuid(uuid, "Not all dependencies are satisfied: " + (blockingDependencies.isEmpty() ? "can't execute" : Joiner.on(",").withKeyValueSeparator("=").join(blockingDependencies)));
        }
    }
    List<CompletableFuture<Optional<OFMessage>>> requests = new ArrayList<>();
    try (Session session = sessionService.open(messageContext, iofSwitch)) {
        for (OFMessage message : ofMessages) {
            requests.add(session.write(message).whenComplete((res, ex) -> {
                log.debug("Check responses (key={})", kafkaKey);
                if (ex == null) {
                    res.ifPresent(ofMessage -> {
                        UUID uuid = holder.popAwaitingXid(ofMessage.getXid());
                        if (ofMessage instanceof OFErrorMsg) {
                            OFErrorMsg errorMsg = (OFErrorMsg) ofMessage;
                            holder.recordFailedUuid(uuid, errorMsg.getErrType().toString());
                        }
                    });
                } else {
                    log.error("Received error {}", ex.getMessage(), ex);
                }
            }));
        }
    }
    CompletableFuture.allOf(requests.toArray(new CompletableFuture<?>[0])).thenAccept(ignore -> checkOfResponses());
}
Also used : OfMeterConverter(org.openkilda.floodlight.converter.rulemanager.OfMeterConverter) Session(org.openkilda.floodlight.service.session.Session) SwitchFeature(org.openkilda.model.SwitchFeature) Collectors.counting(java.util.stream.Collectors.counting) Collectors.groupingBy(java.util.stream.Collectors.groupingBy) CompletableFuture(java.util.concurrent.CompletableFuture) IOFSwitch(net.floodlightcontroller.core.IOFSwitch) ArrayList(java.util.ArrayList) OFFlowStatsReply(org.projectfloodlight.openflow.protocol.OFFlowStatsReply) Map(java.util.Map) SessionService(org.openkilda.floodlight.service.session.SessionService) OFMessage(org.projectfloodlight.openflow.protocol.OFMessage) OFErrorMsg(org.projectfloodlight.openflow.protocol.OFErrorMsg) IKafkaProducerService(org.openkilda.floodlight.service.kafka.IKafkaProducerService) MeterSpeakerData(org.openkilda.rulemanager.MeterSpeakerData) OFMeterConfigStatsReply(org.projectfloodlight.openflow.protocol.OFMeterConfigStatsReply) MessageContext(org.openkilda.messaging.MessageContext) Set(java.util.Set) OfFlowConverter(org.openkilda.floodlight.converter.rulemanager.OfFlowConverter) UUID(java.util.UUID) OfGroupConverter(org.openkilda.floodlight.converter.rulemanager.OfGroupConverter) FlowSpeakerData(org.openkilda.rulemanager.FlowSpeakerData) String.format(java.lang.String.format) OFGroupDescStatsReply(org.projectfloodlight.openflow.protocol.OFGroupDescStatsReply) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) KafkaUtilityService(org.openkilda.floodlight.service.kafka.KafkaUtilityService) KafkaChannel(org.openkilda.floodlight.KafkaChannel) SwitchId(org.openkilda.model.SwitchId) Builder(lombok.Builder) GroupSpeakerData(org.openkilda.rulemanager.GroupSpeakerData) Function.identity(java.util.function.Function.identity) Optional(java.util.Optional) Joiner(com.google.common.base.Joiner) OFErrorMsg(org.projectfloodlight.openflow.protocol.OFErrorMsg) OFMessage(org.projectfloodlight.openflow.protocol.OFMessage) ArrayList(java.util.ArrayList) CompletableFuture(java.util.concurrent.CompletableFuture) UUID(java.util.UUID) Session(org.openkilda.floodlight.service.session.Session)

Example 3 with OFErrorMsg

use of org.projectfloodlight.openflow.protocol.OFErrorMsg in project open-kilda by telstra.

the class SpeakerCommand method setupErrorHandler.

protected CompletableFuture<Optional<OFMessage>> setupErrorHandler(CompletableFuture<Optional<OFMessage>> future, IOfErrorResponseHandler handler) {
    CompletableFuture<Optional<OFMessage>> branch = new CompletableFuture<>();
    future.whenComplete((response, error) -> {
        if (error == null) {
            branch.complete(response);
        } else {
            Throwable actualError = unwrapError(error);
            if (actualError instanceof SessionErrorResponseException) {
                OFErrorMsg errorResponse = ((SessionErrorResponseException) error).getErrorResponse();
                propagateFutureResponse(branch, handler.handleOfError(errorResponse));
            } else {
                branch.completeExceptionally(actualError);
            }
        }
    });
    return branch;
}
Also used : OFErrorMsg(org.projectfloodlight.openflow.protocol.OFErrorMsg) CompletableFuture(java.util.concurrent.CompletableFuture) Optional(java.util.Optional) SessionErrorResponseException(org.openkilda.floodlight.error.SessionErrorResponseException)

Example 4 with OFErrorMsg

use of org.projectfloodlight.openflow.protocol.OFErrorMsg in project open-kilda by telstra.

the class GroupInstallCommand method handleOfError.

@Override
public CompletableFuture<Optional<OFMessage>> handleOfError(OFErrorMsg response) {
    CompletableFuture<Optional<OFMessage>> future = new CompletableFuture<>();
    if (!isInstallConflict(response)) {
        future.completeExceptionally(new SwitchErrorResponseException(getSw().getId(), String.format("Can't install group %s - %s", mirrorConfig.getGroupId(), response)));
        return future;
    }
    log.info("Group conflict detected sw:{} group:{}", getSw().getId(), mirrorConfig.getGroupId());
    GroupVerifyCommand verifyCommand = new GroupVerifyCommand(messageContext, switchId, mirrorConfig, flowTransitData);
    propagateFutureResponse(future, commandProcessor.chain(verifyCommand).thenAccept(this::handleGroupVerify).thenApply(ignore -> Optional.empty()));
    return future;
}
Also used : MirrorConfig(org.openkilda.model.MirrorConfig) Getter(lombok.Getter) Session(org.openkilda.floodlight.service.session.Session) OFGroupMod(org.projectfloodlight.openflow.protocol.OFGroupMod) FlowTransitData(org.openkilda.floodlight.model.FlowTransitData) MessageContext(org.openkilda.messaging.MessageContext) CompletableFuture(java.util.concurrent.CompletableFuture) InvalidGroupIdException(org.openkilda.floodlight.error.InvalidGroupIdException) OFGroupModFailedErrorMsg(org.projectfloodlight.openflow.protocol.errormsg.OFGroupModFailedErrorMsg) SwitchIncorrectMirrorGroupException(org.openkilda.floodlight.error.SwitchIncorrectMirrorGroupException) UnsupportedSwitchOperationException(org.openkilda.floodlight.error.UnsupportedSwitchOperationException) OFGroupModFailedCode(org.projectfloodlight.openflow.protocol.OFGroupModFailedCode) SwitchId(org.openkilda.model.SwitchId) SpeakerCommandProcessor(org.openkilda.floodlight.command.SpeakerCommandProcessor) SwitchGroupConflictException(org.openkilda.floodlight.error.SwitchGroupConflictException) OFMessage(org.projectfloodlight.openflow.protocol.OFMessage) Optional(java.util.Optional) SwitchMissingGroupException(org.openkilda.floodlight.error.SwitchMissingGroupException) OFErrorMsg(org.projectfloodlight.openflow.protocol.OFErrorMsg) IOfErrorResponseHandler(org.openkilda.floodlight.command.IOfErrorResponseHandler) GroupId(org.openkilda.model.GroupId) SwitchErrorResponseException(org.openkilda.floodlight.error.SwitchErrorResponseException) CompletableFuture(java.util.concurrent.CompletableFuture) Optional(java.util.Optional) SwitchErrorResponseException(org.openkilda.floodlight.error.SwitchErrorResponseException)

Example 5 with OFErrorMsg

use of org.projectfloodlight.openflow.protocol.OFErrorMsg in project open-kilda by telstra.

the class Session method handleResponse.

/**
 * Handle switch response.
 *
 * <p>Lookup sent request by message Xid and mark it as completed(errored) if found. Return "true" if the
 * session is completed and can be wiped, return "false" if the session need more responses.
 */
boolean handleResponse(OFMessage message) {
    CompletableFuture<Optional<OFMessage>> future;
    future = requestsByXid.get(message.getXid());
    if (future == null) {
        throw new IllegalArgumentException(String.format("%s must never route \"foreign\" response", group.getClass().getName()));
    }
    if (future.isDone()) {
        // it can already be marked as failed by results of some session wide errors
        return false;
    }
    // Setup correlationId (because this method called asynchronously by FL core).
    try (CorrelationContext.CorrelationContextClosable closable = CorrelationContext.create(context.getCorrelationId())) {
        if (OFType.ERROR == message.getType()) {
            future.completeExceptionally(new SessionErrorResponseException(sw.getId(), (OFErrorMsg) message));
        } else {
            future.complete(Optional.of(message));
        }
        // check session completion (we have received all responses, if we got response for closing barrier request)
        if (closingBarrier != null && closingBarrier.isDone()) {
            incompleteRequestsStream().forEach(entry -> entry.complete(Optional.empty()));
            return true;
        }
        return false;
    }
}
Also used : OFErrorMsg(org.projectfloodlight.openflow.protocol.OFErrorMsg) Optional(java.util.Optional) CorrelationContext(org.openkilda.floodlight.utils.CorrelationContext) SessionErrorResponseException(org.openkilda.floodlight.error.SessionErrorResponseException)

Aggregations

OFErrorMsg (org.projectfloodlight.openflow.protocol.OFErrorMsg)7 Optional (java.util.Optional)5 CompletableFuture (java.util.concurrent.CompletableFuture)4 SessionErrorResponseException (org.openkilda.floodlight.error.SessionErrorResponseException)4 Session (org.openkilda.floodlight.service.session.Session)3 MessageContext (org.openkilda.messaging.MessageContext)3 SwitchId (org.openkilda.model.SwitchId)3 OFMessage (org.projectfloodlight.openflow.protocol.OFMessage)3 Getter (lombok.Getter)2 IOfErrorResponseHandler (org.openkilda.floodlight.command.IOfErrorResponseHandler)2 SpeakerCommandProcessor (org.openkilda.floodlight.command.SpeakerCommandProcessor)2 SwitchErrorResponseException (org.openkilda.floodlight.error.SwitchErrorResponseException)2 UnsupportedSwitchOperationException (org.openkilda.floodlight.error.UnsupportedSwitchOperationException)2 Joiner (com.google.common.base.Joiner)1 String.format (java.lang.String.format)1 ArrayList (java.util.ArrayList)1 List (java.util.List)1 Map (java.util.Map)1 Set (java.util.Set)1 UUID (java.util.UUID)1