Search in sources :

Example 46 with YFlowRequest

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

the class YFlowServiceImpl method updateYFlow.

@Override
public CompletableFuture<YFlow> updateYFlow(String yFlowId, YFlowUpdatePayload updatePayload) {
    log.debug("Processing y-flow update: {}", updatePayload);
    String correlationId = RequestCorrelationId.getId();
    YFlowRequest flowRequest;
    try {
        flowRequest = flowMapper.toYFlowUpdateRequest(yFlowId, updatePayload);
    } catch (IllegalArgumentException e) {
        throw new MessageException(correlationId, System.currentTimeMillis(), ErrorType.DATA_INVALID, e.getMessage(), "Can not parse arguments of the create y-flow request");
    }
    CommandMessage command = new CommandMessage(flowRequest, System.currentTimeMillis(), correlationId);
    return messagingChannel.sendAndGet(flowHsTopic, command).thenApply(YFlowResponse.class::cast).thenApply(YFlowResponse::getYFlow).thenApply(flowMapper::toYFlow);
}
Also used : MessageException(org.openkilda.messaging.error.MessageException) YFlowResponse(org.openkilda.messaging.command.yflow.YFlowResponse) YFlowRequest(org.openkilda.messaging.command.yflow.YFlowRequest) CommandMessage(org.openkilda.messaging.command.CommandMessage)

Example 47 with YFlowRequest

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

the class YFlowServiceImpl method createYFlow.

@Override
public CompletableFuture<YFlow> createYFlow(YFlowCreatePayload createPayload) {
    log.debug("Processing y-flow creation: {}", createPayload);
    String correlationId = RequestCorrelationId.getId();
    YFlowRequest flowRequest;
    try {
        flowRequest = flowMapper.toYFlowCreateRequest(createPayload);
    } catch (IllegalArgumentException e) {
        throw new MessageException(correlationId, System.currentTimeMillis(), ErrorType.DATA_INVALID, e.getMessage(), "Can not parse arguments of the create y-flow request");
    }
    CommandMessage command = new CommandMessage(flowRequest, System.currentTimeMillis(), correlationId);
    return messagingChannel.sendAndGet(flowHsTopic, command).thenApply(YFlowResponse.class::cast).thenApply(YFlowResponse::getYFlow).thenApply(flowMapper::toYFlow);
}
Also used : MessageException(org.openkilda.messaging.error.MessageException) YFlowResponse(org.openkilda.messaging.command.yflow.YFlowResponse) YFlowRequest(org.openkilda.messaging.command.yflow.YFlowRequest) CommandMessage(org.openkilda.messaging.command.CommandMessage)

Example 48 with YFlowRequest

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

the class YFlowUpdateService method handlePartialUpdateRequest.

/**
 * Handles request for y-flow patch updating.
 *
 * @param key command identifier.
 * @param request request data.
 */
public void handlePartialUpdateRequest(@NonNull String key, @NonNull CommandContext commandContext, @NonNull YFlowPartialUpdateRequest request) throws DuplicateKeyException {
    YFlowRequest target;
    if (request.getYFlowId() != null) {
        YFlow yFlow = yFlowRepository.findById(request.getYFlowId()).orElse(null);
        target = YFlowRequestMapper.INSTANCE.toYFlowRequest(yFlow);
    } else {
        throw new FlowProcessingException(ErrorType.REQUEST_INVALID, "Need to specify the y-flow id");
    }
    if (target == null) {
        throw new FlowProcessingException(ErrorType.NOT_FOUND, format("Y-flow was not found by the specified y-flow id: %s", request.getYFlowId()));
    }
    if (request.getSharedEndpoint() != null) {
        if (target.getSharedEndpoint() == null) {
            target.setSharedEndpoint(new FlowEndpoint(request.getSharedEndpoint().getSwitchId(), request.getSharedEndpoint().getPortNumber()));
        } else {
            SwitchId switchId = Optional.ofNullable(request.getSharedEndpoint().getSwitchId()).orElse(target.getSharedEndpoint().getSwitchId());
            int portNumber = Optional.ofNullable(request.getSharedEndpoint().getPortNumber()).orElse(target.getSharedEndpoint().getPortNumber());
            target.setSharedEndpoint(new FlowEndpoint(switchId, portNumber));
        }
    }
    Optional.ofNullable(request.getMaximumBandwidth()).ifPresent(target::setMaximumBandwidth);
    Optional.ofNullable(request.getPathComputationStrategy()).ifPresent(target::setPathComputationStrategy);
    Optional.ofNullable(request.getEncapsulationType()).ifPresent(target::setEncapsulationType);
    Optional.ofNullable(request.getMaxLatency()).ifPresent(target::setMaxLatency);
    Optional.ofNullable(request.getMaxLatencyTier2()).ifPresent(target::setMaxLatencyTier2);
    Optional.ofNullable(request.getIgnoreBandwidth()).ifPresent(target::setIgnoreBandwidth);
    Optional.ofNullable(request.getPeriodicPings()).ifPresent(target::setPeriodicPings);
    Optional.ofNullable(request.getPinned()).ifPresent(target::setPinned);
    Optional.ofNullable(request.getPriority()).ifPresent(target::setPriority);
    Optional.ofNullable(request.getStrictBandwidth()).ifPresent(target::setStrictBandwidth);
    Optional.ofNullable(request.getDescription()).ifPresent(target::setDescription);
    Optional.ofNullable(request.getAllocateProtectedPath()).ifPresent(target::setAllocateProtectedPath);
    Optional.ofNullable(request.getDiverseFlowId()).ifPresent(target::setDiverseFlowId);
    if (request.getSubFlows() != null && !request.getSubFlows().isEmpty()) {
        Map<String, SubFlowDto> stringSubFlowDtoMap;
        if (target.getSubFlows() != null) {
            stringSubFlowDtoMap = target.getSubFlows().stream().collect(Collectors.toMap(SubFlowDto::getFlowId, Function.identity()));
        } else {
            throw new FlowProcessingException(ErrorType.INTERNAL_ERROR, format("Sub-flows for y-flow %s not found", target.getYFlowId()));
        }
        List<SubFlowDto> subFlows = new ArrayList<>();
        for (SubFlowPartialUpdateDto subFlowPartialUpdate : request.getSubFlows()) {
            SubFlowDto subFlow = stringSubFlowDtoMap.get(subFlowPartialUpdate.getFlowId());
            if (subFlow != null) {
                if (subFlowPartialUpdate.getEndpoint() != null) {
                    if (subFlow.getEndpoint() == null) {
                        subFlow.setEndpoint(new FlowEndpoint(subFlowPartialUpdate.getEndpoint().getSwitchId(), subFlowPartialUpdate.getEndpoint().getPortNumber(), subFlowPartialUpdate.getEndpoint().getVlanId(), subFlowPartialUpdate.getEndpoint().getInnerVlanId()));
                    } else {
                        SwitchId switchId = Optional.ofNullable(subFlowPartialUpdate.getEndpoint().getSwitchId()).orElse(subFlow.getEndpoint().getSwitchId());
                        int portNumber = Optional.ofNullable(subFlowPartialUpdate.getEndpoint().getPortNumber()).orElse(subFlow.getEndpoint().getPortNumber());
                        int vlanId = Optional.ofNullable(subFlowPartialUpdate.getEndpoint().getVlanId()).orElse(subFlow.getEndpoint().getOuterVlanId());
                        int innerVlanId = Optional.ofNullable(subFlowPartialUpdate.getEndpoint().getInnerVlanId()).orElse(subFlow.getEndpoint().getInnerVlanId());
                        subFlow.setEndpoint(new FlowEndpoint(switchId, portNumber, vlanId, innerVlanId));
                    }
                }
                if (subFlowPartialUpdate.getSharedEndpoint() != null) {
                    if (subFlow.getSharedEndpoint() == null) {
                        subFlow.setSharedEndpoint(new SubFlowSharedEndpointEncapsulation(subFlowPartialUpdate.getSharedEndpoint().getVlanId(), subFlowPartialUpdate.getSharedEndpoint().getInnerVlanId()));
                    } else {
                        int vlanId = Optional.ofNullable(subFlowPartialUpdate.getSharedEndpoint().getVlanId()).orElse(subFlow.getSharedEndpoint().getVlanId());
                        int innerVlanId = Optional.ofNullable(subFlowPartialUpdate.getSharedEndpoint().getInnerVlanId()).orElse(subFlow.getSharedEndpoint().getInnerVlanId());
                        subFlow.setSharedEndpoint(new SubFlowSharedEndpointEncapsulation(vlanId, innerVlanId));
                    }
                }
                Optional.ofNullable(subFlowPartialUpdate.getDescription()).ifPresent(subFlow::setDescription);
                subFlows.add(subFlow);
            } else {
                throw new FlowProcessingException(ErrorType.REQUEST_INVALID, format("There is no sub-flows with sub-flow id: %s", subFlowPartialUpdate.getFlowId()));
            }
        }
        target.setSubFlows(subFlows);
    }
    target.setType(Type.UPDATE);
    handleRequest(key, commandContext, target);
}
Also used : YFlow(org.openkilda.model.YFlow) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) ArrayList(java.util.ArrayList) SwitchId(org.openkilda.model.SwitchId) SubFlowSharedEndpointEncapsulation(org.openkilda.messaging.command.yflow.SubFlowSharedEndpointEncapsulation) SubFlowDto(org.openkilda.messaging.command.yflow.SubFlowDto) YFlowRequest(org.openkilda.messaging.command.yflow.YFlowRequest) FlowEndpoint(org.openkilda.model.FlowEndpoint) FlowEndpoint(org.openkilda.model.FlowEndpoint) SubFlowPartialUpdateDto(org.openkilda.messaging.command.yflow.SubFlowPartialUpdateDto)

Example 49 with YFlowRequest

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

the class UpdateYFlowAction method perform.

@Override
protected void perform(State from, State to, Event event, YFlowUpdateContext context, YFlowUpdateFsm stateMachine) {
    YFlowRequest targetFlow = stateMachine.getTargetFlow();
    stateMachine.setDiverseFlowId(targetFlow.getDiverseFlowId());
    FlowStatus flowStatus = transactionManager.doInTransaction(() -> {
        YFlow yFlow = getYFlow(targetFlow.getYFlowId());
        saveOldResources(stateMachine, yFlow);
        stateMachine.setDeleteOldYFlowCommands(buildYFlowDeleteCommands(yFlow, stateMachine.getCommandContext()));
        updateFlow(yFlow, YFlowRequestMapper.INSTANCE.toYFlow(targetFlow));
        return yFlow.getStatus();
    });
    stateMachine.saveActionToHistory(format("The y-flow was updated. The status %s", flowStatus));
}
Also used : YFlow(org.openkilda.model.YFlow) YFlowRequest(org.openkilda.messaging.command.yflow.YFlowRequest) FlowStatus(org.openkilda.model.FlowStatus)

Example 50 with YFlowRequest

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

the class ValidateYFlowAction method performWithResponse.

@Override
protected Optional<Message> performWithResponse(State from, State to, Event event, YFlowUpdateContext context, YFlowUpdateFsm stateMachine) {
    YFlowRequest targetFlow = context.getTargetFlow();
    boolean isOperationAllowed = featureTogglesRepository.getOrDefault().getModifyYFlowEnabled();
    if (!isOperationAllowed) {
        throw new FlowProcessingException(ErrorType.NOT_PERMITTED, "Y-flow create feature is disabled");
    }
    try {
        yFlowValidator.validate(targetFlow);
    } catch (InvalidFlowException e) {
        throw new FlowProcessingException(e.getType(), e.getMessage(), e);
    } catch (UnavailableFlowEndpointException e) {
        throw new FlowProcessingException(ErrorType.DATA_INVALID, e.getMessage(), e);
    }
    String yFlowId = targetFlow.getYFlowId();
    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;
    });
    Set<String> requestedSubFlowIds = targetFlow.getSubFlows().stream().map(SubFlowDto::getFlowId).collect(Collectors.toSet());
    Set<String> originalSubFlowIds = yFlow.getSubFlows().stream().map(YSubFlow::getSubFlowId).collect(Collectors.toSet());
    if (!requestedSubFlowIds.equals(originalSubFlowIds)) {
        throw new FlowProcessingException(ErrorType.PARAMETERS_INVALID, format("Unable to map provided sub-flows set onto existing y-flow %s", yFlowId));
    }
    YSubFlow subFlow = yFlow.getSubFlows().stream().findAny().orElseThrow(() -> new FlowProcessingException(ErrorType.DATA_INVALID, format("No sub-flows of the y-flow %s were found", yFlowId)));
    stateMachine.setMainAffinityFlowId(subFlow.getFlow().getAffinityGroupId());
    List<FlowEndpoint> subFlowEndpoints = targetFlow.getSubFlows().stream().map(SubFlowDto::getEndpoint).collect(Collectors.toList());
    dashboardLogger.onYFlowUpdate(yFlowId, targetFlow.getSharedEndpoint(), subFlowEndpoints, targetFlow.getMaximumBandwidth());
    stateMachine.setTargetFlow(targetFlow);
    stateMachine.saveNewEventToHistory("Y-flow was validated successfully", FlowEventData.Event.UPDATE);
    return Optional.empty();
}
Also used : UnavailableFlowEndpointException(org.openkilda.wfm.topology.flowhs.validation.UnavailableFlowEndpointException) YFlow(org.openkilda.model.YFlow) FlowEndpoint(org.openkilda.model.FlowEndpoint) FlowProcessingException(org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException) InvalidFlowException(org.openkilda.wfm.topology.flowhs.validation.InvalidFlowException) YFlowRequest(org.openkilda.messaging.command.yflow.YFlowRequest) YSubFlow(org.openkilda.model.YSubFlow)

Aggregations

YFlowRequest (org.openkilda.messaging.command.yflow.YFlowRequest)50 Test (org.junit.Test)35 AbstractYFlowTest (org.openkilda.wfm.topology.flowhs.service.AbstractYFlowTest)27 YFlow (org.openkilda.model.YFlow)12 YFlowRerouteRequest (org.openkilda.messaging.command.yflow.YFlowRerouteRequest)11 CommandContext (org.openkilda.wfm.CommandContext)10 SwitchId (org.openkilda.model.SwitchId)9 SubFlowSharedEndpointEncapsulation (org.openkilda.messaging.command.yflow.SubFlowSharedEndpointEncapsulation)8 UnroutableFlowException (org.openkilda.pce.exception.UnroutableFlowException)7 RerouteError (org.openkilda.messaging.info.reroute.error.RerouteError)5 FlowProcessingException (org.openkilda.wfm.topology.flowhs.exception.FlowProcessingException)5 ResourceAllocationException (org.openkilda.wfm.share.flow.resources.ResourceAllocationException)4 Ignore (org.junit.Ignore)3 CommandMessage (org.openkilda.messaging.command.CommandMessage)3 YFlowResponse (org.openkilda.messaging.command.yflow.YFlowResponse)3 FlowEndpoint (org.openkilda.model.FlowEndpoint)3 FlowStatus (org.openkilda.model.FlowStatus)3 IslEndpoint (org.openkilda.model.IslEndpoint)3 DuplicateKeyException (org.openkilda.wfm.topology.flowhs.exception.DuplicateKeyException)3 YFlowPartialUpdateRequest (org.openkilda.messaging.command.yflow.YFlowPartialUpdateRequest)2