Search in sources :

Example 1 with FlowRerouteRequest

use of org.openkilda.messaging.command.flow.FlowRerouteRequest in project open-kilda by telstra.

the class CacheBolt method emitRerouteCommands.

private void emitRerouteCommands(Set<ImmutablePair<Flow, Flow>> flows, Tuple tuple, String correlationId, FlowOperation operation) {
    for (ImmutablePair<Flow, Flow> flow : flows) {
        try {
            flow.getLeft().setState(FlowState.DOWN);
            flow.getRight().setState(FlowState.DOWN);
            FlowRerouteRequest request = new FlowRerouteRequest(flow.getLeft(), operation);
            Values values = new Values(Utils.MAPPER.writeValueAsString(new CommandMessage(request, System.currentTimeMillis(), correlationId, Destination.WFM)));
            outputCollector.emit(StreamType.WFM_DUMP.toString(), tuple, values);
            logger.debug("Flow {} reroute command message sent with correlationId {}", flow.getLeft().getFlowId(), correlationId);
        } catch (JsonProcessingException exception) {
            logger.error("Could not format flow reroute request by flow={}", flow, exception);
        }
    }
}
Also used : Values(org.apache.storm.tuple.Values) FlowRerouteRequest(org.openkilda.messaging.command.flow.FlowRerouteRequest) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) Flow(org.openkilda.messaging.model.Flow) CommandMessage(org.openkilda.messaging.command.CommandMessage)

Example 2 with FlowRerouteRequest

use of org.openkilda.messaging.command.flow.FlowRerouteRequest in project open-kilda by telstra.

the class CrudBolt method handleRerouteRequest.

private void handleRerouteRequest(CommandMessage message, Tuple tuple) throws IOException {
    FlowRerouteRequest request = (FlowRerouteRequest) message.getData();
    Flow requestedFlow = request.getPayload();
    final String flowId = requestedFlow.getFlowId();
    ImmutablePair<Flow, Flow> flow;
    logger.debug("Handling reroute request with correlationId {}", message.getCorrelationId());
    switch(request.getOperation()) {
        case UPDATE:
            flow = flowCache.getFlow(flowId);
            try {
                ImmutablePair<PathInfoData, PathInfoData> path = pathComputer.getPath(flow.getLeft(), Strategy.COST);
                logger.info("Rerouted flow path: {}", path);
                // no need to emit changes if path wasn't changed and flow is active.
                if (!path.getLeft().equals(flow.getLeft().getFlowPath()) || !isFlowActive(flow)) {
                    flow.getLeft().setState(FlowState.DOWN);
                    flow.getRight().setState(FlowState.DOWN);
                    flow = flowCache.updateFlow(flow.getLeft(), path);
                    logger.info("Rerouted flow: {}", flow);
                    FlowInfoData data = new FlowInfoData(flowId, flow, FlowOperation.UPDATE, message.getCorrelationId());
                    InfoMessage infoMessage = new InfoMessage(data, System.currentTimeMillis(), message.getCorrelationId());
                    Values topology = new Values(MAPPER.writeValueAsString(infoMessage));
                    outputCollector.emit(StreamType.UPDATE.toString(), tuple, topology);
                } else {
                    logger.debug("Reroute was unsuccessful: can't find new path");
                }
                logger.debug("Sending response to NB. Correlation id {}", message.getCorrelationId());
                Values response = new Values(new InfoMessage(new FlowPathResponse(flow.left.getFlowPath()), message.getTimestamp(), message.getCorrelationId(), Destination.NORTHBOUND));
                outputCollector.emit(StreamType.RESPONSE.toString(), tuple, response);
            } catch (UnroutablePathException e) {
                flow.getLeft().setState(FlowState.DOWN);
                flow.getRight().setState(FlowState.DOWN);
                throw new MessageException(message.getCorrelationId(), System.currentTimeMillis(), ErrorType.UPDATE_FAILURE, "Could not reroute flow", "Path was not found");
            }
            break;
        case CREATE:
            flow = flowCache.getFlow(flowId);
            logger.info("State flow: {}={}", flow.getLeft().getFlowId(), FlowState.UP);
            flow.getLeft().setState(FlowState.UP);
            flow.getRight().setState(FlowState.UP);
            break;
        case DELETE:
            flow = flowCache.getFlow(flowId);
            logger.info("State flow: {}={}", flow.getLeft().getFlowId(), FlowState.DOWN);
            flow.getLeft().setState(FlowState.DOWN);
            flow.getRight().setState(FlowState.DOWN);
            break;
        default:
            logger.warn("Flow {} undefined reroute operation", request.getOperation());
            break;
    }
}
Also used : PathInfoData(org.openkilda.messaging.info.event.PathInfoData) MessageException(org.openkilda.messaging.error.MessageException) InfoMessage(org.openkilda.messaging.info.InfoMessage) Values(org.apache.storm.tuple.Values) FlowRerouteRequest(org.openkilda.messaging.command.flow.FlowRerouteRequest) UnroutablePathException(org.openkilda.pce.provider.UnroutablePathException) Flow(org.openkilda.messaging.model.Flow)

Example 3 with FlowRerouteRequest

use of org.openkilda.messaging.command.flow.FlowRerouteRequest in project open-kilda by telstra.

the class SplitterBolt method execute.

/**
 * {@inheritDoc}
 */
@Override
public void execute(Tuple tuple) {
    String request = tuple.getString(0);
    Values values = new Values(request);
    try {
        Message message = tryMessage(request);
        if (message == null || !Destination.WFM.equals(message.getDestination()) || !(message instanceof CommandMessage || message instanceof InfoMessage)) {
            return;
        }
        logger.debug("Request tuple={}", tuple);
        /*
             * First, try to see if this is a PUSH / UNPUSH (smaller code base vs other).
             * NB: InfoMessage was used since it has the relevant attributes/properties for
             * pushing the flow.
             */
        if (message instanceof InfoMessage) {
            InfoData data = ((InfoMessage) message).getData();
            if (data instanceof FlowInfoData) {
                FlowInfoData fid = (FlowInfoData) data;
                String flowId = fid.getFlowId();
                values = new Values(message, flowId);
                logger.info("Flow {} message: operation={} values={}", flowId, fid.getOperation(), values);
                if (fid.getOperation() == FlowOperation.PUSH) {
                    outputCollector.emit(StreamType.PUSH.toString(), tuple, values);
                } else if (fid.getOperation() == FlowOperation.UNPUSH) {
                    outputCollector.emit(StreamType.UNPUSH.toString(), tuple, values);
                } else {
                    logger.warn("Skip undefined FlowInfoData Operation {}: {}={}", fid.getOperation(), Utils.CORRELATION_ID, message.getCorrelationId());
                }
            } else {
                logger.warn("Skip undefined InfoMessage: {}={}", Utils.CORRELATION_ID, message.getCorrelationId());
            }
            return;
        }
        /*
             * Second, it isn't an InfoMessage, so it must be a CommandMessage.
             */
        CommandData data = ((CommandMessage) message).getData();
        if (data instanceof FlowCreateRequest) {
            String flowId = ((FlowCreateRequest) data).getPayload().getFlowId();
            logger.info("Flow {} create message: values={}", flowId, values);
            values = new Values(message, flowId);
            outputCollector.emit(StreamType.CREATE.toString(), tuple, values);
        } else if (data instanceof FlowDeleteRequest) {
            String flowId = ((FlowDeleteRequest) data).getPayload().getFlowId();
            logger.info("Flow {} delete message: values={}", flowId, values);
            values = new Values(message, flowId);
            outputCollector.emit(StreamType.DELETE.toString(), tuple, values);
        } else if (data instanceof FlowUpdateRequest) {
            String flowId = ((FlowUpdateRequest) data).getPayload().getFlowId();
            logger.info("Flow {} update message: values={}", flowId, values);
            values = new Values(message, flowId);
            outputCollector.emit(StreamType.UPDATE.toString(), tuple, values);
        } else if (data instanceof FlowRestoreRequest) {
            String flowId = ((FlowRestoreRequest) data).getPayload().getLeft().getFlowId();
            logger.info("Flow {} restore message: values={}", flowId, values);
            values = new Values(message, flowId);
            outputCollector.emit(StreamType.RESTORE.toString(), tuple, values);
        } else if (data instanceof FlowRerouteRequest) {
            String flowId = ((FlowRerouteRequest) data).getPayload().getFlowId();
            logger.info("Flow {} reroute message: values={}", flowId, values);
            values = new Values(message, flowId);
            outputCollector.emit(StreamType.REROUTE.toString(), tuple, values);
        } else if (data instanceof FlowStatusRequest) {
            String flowId = ((FlowStatusRequest) data).getPayload().getId();
            logger.info("Flow {} status message: values={}", flowId, values);
            values = new Values(message, flowId);
            outputCollector.emit(StreamType.STATUS.toString(), tuple, values);
        } else if (data instanceof FlowGetRequest) {
            String flowId = ((FlowGetRequest) data).getPayload().getId();
            logger.info("Flow {} get message: values={}", flowId, values);
            values = new Values(message, flowId);
            outputCollector.emit(StreamType.READ.toString(), tuple, values);
        } else if (data instanceof FlowsGetRequest) {
            logger.info("Flows get message: values={}", values);
            values = new Values(message, null);
            outputCollector.emit(StreamType.READ.toString(), tuple, values);
        } else if (data instanceof FlowPathRequest) {
            String flowId = ((FlowPathRequest) data).getPayload().getId();
            logger.info("Flow {} path message: values={}", flowId, values);
            values = new Values(message, flowId);
            outputCollector.emit(StreamType.PATH.toString(), tuple, values);
        } else if (data instanceof FlowCacheSyncRequest) {
            logger.info("FlowCacheSyncRequest: values={}", values);
            values = new Values(message, null);
            outputCollector.emit(StreamType.CACHE_SYNC.toString(), tuple, values);
        } else {
            logger.debug("Skip undefined CommandMessage: {}={}", Utils.CORRELATION_ID, message.getCorrelationId());
        }
    /*
 * (crimi) This was commented out since the parsing of the message is handled in tryMessage.
 * Due to refactoring the kafka topics, it appears more messages are coming to the splitter than
 * originally desinged for.
 *
 * TODO: Fix the cause of excess messages coming to the splitter.
 */
    // 
    // } catch (IOException exception) {
    // String message = String.format("Could not deserialize message: %s", request);
    // logger.error("{}", message, exception);
    // 
    // ErrorMessage errorMessage = new ErrorMessage(
    // new ErrorData(ErrorType.REQUEST_INVALID, message, exception.getMessage()),
    // System.currentTimeMillis(), Utils.SYSTEM_CORRELATION_ID, Destination.NORTHBOUND);
    // 
    // values = new Values(errorMessage, ErrorType.INTERNAL_ERROR);
    // outputCollector.emit(StreamType.ERROR.toString(), tuple, values);
    } finally {
        logger.debug("Splitter message ack: component={}, stream={}, tuple={}, values={}", tuple.getSourceComponent(), tuple.getSourceStreamId(), tuple, values);
        outputCollector.ack(tuple);
    }
}
Also used : FlowsGetRequest(org.openkilda.messaging.command.flow.FlowsGetRequest) FlowInfoData(org.openkilda.messaging.info.flow.FlowInfoData) FlowUpdateRequest(org.openkilda.messaging.command.flow.FlowUpdateRequest) InfoMessage(org.openkilda.messaging.info.InfoMessage) Message(org.openkilda.messaging.Message) CommandMessage(org.openkilda.messaging.command.CommandMessage) FlowDeleteRequest(org.openkilda.messaging.command.flow.FlowDeleteRequest) Values(org.apache.storm.tuple.Values) FlowCreateRequest(org.openkilda.messaging.command.flow.FlowCreateRequest) FlowGetRequest(org.openkilda.messaging.command.flow.FlowGetRequest) FlowRestoreRequest(org.openkilda.messaging.command.flow.FlowRestoreRequest) CommandMessage(org.openkilda.messaging.command.CommandMessage) InfoMessage(org.openkilda.messaging.info.InfoMessage) InfoData(org.openkilda.messaging.info.InfoData) FlowInfoData(org.openkilda.messaging.info.flow.FlowInfoData) FlowStatusRequest(org.openkilda.messaging.command.flow.FlowStatusRequest) FlowRerouteRequest(org.openkilda.messaging.command.flow.FlowRerouteRequest) CommandData(org.openkilda.messaging.command.CommandData) FlowPathRequest(org.openkilda.messaging.command.flow.FlowPathRequest) FlowCacheSyncRequest(org.openkilda.messaging.command.flow.FlowCacheSyncRequest)

Example 4 with FlowRerouteRequest

use of org.openkilda.messaging.command.flow.FlowRerouteRequest in project open-kilda by telstra.

the class CacheTopologyTest method flowShouldBeReroutedWhenIslDies.

@Ignore
@Test
public void flowShouldBeReroutedWhenIslDies() throws Exception {
    final String destSwitchId = "destSwitch";
    final String flowId = "flowId";
    sendData(sw);
    SwitchInfoData destSwitch = new SwitchInfoData(destSwitchId, SwitchState.ACTIVATED, StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY);
    sendData(destSwitch);
    List<PathNode> path = ImmutableList.of(new PathNode(sw.getSwitchId(), 0, 0), new PathNode(destSwitch.getSwitchId(), 0, 1));
    IslInfoData isl = new IslInfoData(0L, path, 0L, IslChangeType.DISCOVERED, 0L);
    sendData(isl);
    FlowInfoData flowData = buildFlowInfoData(flowId, sw.getSwitchId(), destSwitchId, path);
    sendData(flowData);
    // mark isl as failed
    flowConsumer.clear();
    isl.setState(IslChangeType.FAILED);
    sendData(isl);
    // we are expecting that flow should be rerouted
    ConsumerRecord<String, String> record = flowConsumer.pollMessage();
    assertNotNull(record);
    CommandMessage message = objectMapper.readValue(record.value(), CommandMessage.class);
    assertNotNull(message);
    FlowRerouteRequest command = (FlowRerouteRequest) message.getData();
    assertTrue(command.getPayload().getFlowId().equals(flowId));
}
Also used : FlowInfoData(org.openkilda.messaging.info.flow.FlowInfoData) FlowRerouteRequest(org.openkilda.messaging.command.flow.FlowRerouteRequest) IslInfoData(org.openkilda.messaging.info.event.IslInfoData) SwitchInfoData(org.openkilda.messaging.info.event.SwitchInfoData) PathNode(org.openkilda.messaging.info.event.PathNode) CommandMessage(org.openkilda.messaging.command.CommandMessage) AbstractStormTest(org.openkilda.wfm.AbstractStormTest)

Example 5 with FlowRerouteRequest

use of org.openkilda.messaging.command.flow.FlowRerouteRequest in project open-kilda by telstra.

the class CacheTopologyTest method flowShouldBeReroutedWhenSwitchGoesDown.

@Test
public void flowShouldBeReroutedWhenSwitchGoesDown() throws Exception {
    sendData(sw);
    SwitchInfoData dstSwitch = new SwitchInfoData();
    dstSwitch.setState(SwitchState.ACTIVATED);
    dstSwitch.setSwitchId("dstSwitch");
    List<PathNode> path = ImmutableList.of(new PathNode(sw.getSwitchId(), 0, 0), new PathNode(dstSwitch.getSwitchId(), 0, 1));
    // create inactive flow
    firstFlow.getLeft().setFlowPath(new PathInfoData(0L, path));
    firstFlow.getRight().setFlowPath(new PathInfoData(0L, Collections.emptyList()));
    firstFlow.getLeft().setState(FlowState.DOWN);
    sendFlowUpdate(firstFlow);
    // create active flow
    secondFlow.getLeft().setFlowPath(new PathInfoData(0L, path));
    secondFlow.getRight().setFlowPath(new PathInfoData(0L, Collections.emptyList()));
    secondFlow.getLeft().setState(FlowState.UP);
    sendFlowUpdate(secondFlow);
    flowConsumer.clear();
    sw.setState(SwitchState.REMOVED);
    sendData(sw);
    // active flow should be rerouted
    ConsumerRecord<String, String> record = flowConsumer.pollMessage();
    assertNotNull(record);
    CommandMessage message = objectMapper.readValue(record.value(), CommandMessage.class);
    assertNotNull(message);
    FlowRerouteRequest command = (FlowRerouteRequest) message.getData();
    assertTrue(command.getPayload().getFlowId().equals(secondFlowId));
}
Also used : PathInfoData(org.openkilda.messaging.info.event.PathInfoData) FlowRerouteRequest(org.openkilda.messaging.command.flow.FlowRerouteRequest) SwitchInfoData(org.openkilda.messaging.info.event.SwitchInfoData) PathNode(org.openkilda.messaging.info.event.PathNode) CommandMessage(org.openkilda.messaging.command.CommandMessage) AbstractStormTest(org.openkilda.wfm.AbstractStormTest)

Aggregations

FlowRerouteRequest (org.openkilda.messaging.command.flow.FlowRerouteRequest)49 Test (org.junit.Test)27 Flow (org.openkilda.model.Flow)23 FlowSegmentRequest (org.openkilda.floodlight.api.request.FlowSegmentRequest)14 Values (org.apache.storm.tuple.Values)10 YFlowRerouteRequest (org.openkilda.messaging.command.yflow.YFlowRerouteRequest)9 CommandMessage (org.openkilda.messaging.command.CommandMessage)8 IslEndpoint (org.openkilda.model.IslEndpoint)8 CommandContext (org.openkilda.wfm.CommandContext)7 FlowPath (org.openkilda.model.FlowPath)6 FlowThrottlingData (org.openkilda.wfm.topology.reroute.model.FlowThrottlingData)5 RerouteResultInfoData (org.openkilda.messaging.info.reroute.RerouteResultInfoData)4 GetPathsResult (org.openkilda.pce.GetPathsResult)4 FlowPathRepository (org.openkilda.persistence.repositories.FlowPathRepository)4 HashSet (java.util.HashSet)3 RerouteQueue (org.openkilda.wfm.topology.reroute.model.RerouteQueue)3 ArrayList (java.util.ArrayList)2 Collection (java.util.Collection)2 Ignore (org.junit.Ignore)2 FlowErrorResponse (org.openkilda.floodlight.flow.response.FlowErrorResponse)2