Search in sources :

Example 6 with Flow

use of org.openkilda.messaging.model.Flow in project open-kilda by telstra.

the class CrudBolt method handleDeleteRequest.

private void handleDeleteRequest(String flowId, CommandMessage message, Tuple tuple) throws IOException {
    ImmutablePair<Flow, Flow> flow = flowCache.deleteFlow(flowId);
    logger.info("Deleted flow: {}", flow);
    FlowInfoData data = new FlowInfoData(flowId, flow, FlowOperation.DELETE, message.getCorrelationId());
    InfoMessage infoMessage = new InfoMessage(data, System.currentTimeMillis(), message.getCorrelationId());
    Values topology = new Values(MAPPER.writeValueAsString(infoMessage));
    outputCollector.emit(StreamType.DELETE.toString(), tuple, topology);
    Values northbound = new Values(new InfoMessage(new FlowResponse(buildFlowResponse(flow)), message.getTimestamp(), message.getCorrelationId(), Destination.NORTHBOUND));
    outputCollector.emit(StreamType.RESPONSE.toString(), tuple, northbound);
}
Also used : InfoMessage(org.openkilda.messaging.info.InfoMessage) Values(org.apache.storm.tuple.Values) Flow(org.openkilda.messaging.model.Flow)

Example 7 with Flow

use of org.openkilda.messaging.model.Flow 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 8 with Flow

use of org.openkilda.messaging.model.Flow in project open-kilda by telstra.

the class CrudBolt method handleCacheSyncRequest.

private void handleCacheSyncRequest(CommandMessage message, Tuple tuple) throws IOException {
    logger.info("CACHE SYNCE: {}", message);
    // NB: This is going to be a "bulky" operation - get all flows from DB, and synchronize
    // with the cache.
    List<String> droppedFlows = new ArrayList<>();
    List<String> addedFlows = new ArrayList<>();
    List<String> modifiedFlows = new ArrayList<>();
    List<String> unchangedFlows = new ArrayList<>();
    List<FlowInfo> flowInfos = pathComputer.getFlowInfo();
    // Instead of determining left/right .. store based on flowid_& cookie
    HashMap<String, FlowInfo> flowToInfo = new HashMap<>();
    for (FlowInfo fi : flowInfos) {
        flowToInfo.put(fi.getFlowId() + fi.getCookie(), fi);
    }
    // We first look at comparing what is in the DB to what is in the Cache
    for (FlowInfo fi : flowInfos) {
        String flowid = fi.getFlowId();
        if (flowCache.cacheContainsFlow(flowid)) {
            // TODO: better, more holistic comparison
            // TODO: if the flow is modified, then just leverage drop / add primitives.
            // TODO: Ensure that the DB is always the source of truth - cache and db ops part of transaction.
            // Need to compare both sides
            ImmutablePair<Flow, Flow> fc = flowCache.getFlow(flowid);
            int count = modifiedFlows.size();
            if (fi.getCookie() != fc.left.getCookie() && fi.getCookie() != fc.right.getCookie())
                modifiedFlows.add("cookie: " + flowid + ":" + fi.getCookie() + ":" + fc.left.getCookie() + ":" + fc.right.getCookie());
            if (fi.getMeterId() != fc.left.getMeterId() && fi.getMeterId() != fc.right.getMeterId())
                modifiedFlows.add("meter: " + flowid + ":" + fi.getMeterId() + ":" + fc.left.getMeterId() + ":" + fc.right.getMeterId());
            if (fi.getTransitVlanId() != fc.left.getTransitVlan() && fi.getTransitVlanId() != fc.right.getTransitVlan())
                modifiedFlows.add("transit: " + flowid + ":" + fi.getTransitVlanId() + ":" + fc.left.getTransitVlan() + ":" + fc.right.getTransitVlan());
            if (!fi.getSrcSwitchId().equals(fc.left.getSourceSwitch()) && !fi.getSrcSwitchId().equals(fc.right.getSourceSwitch()))
                modifiedFlows.add("switch: " + flowid + "|" + fi.getSrcSwitchId() + "|" + fc.left.getSourceSwitch() + "|" + fc.right.getSourceSwitch());
            if (count == modifiedFlows.size())
                unchangedFlows.add(flowid);
        } else {
            // TODO: need to get the flow from the DB and add it properly
            addedFlows.add(flowid);
        }
    }
    // Now we see if the cache holds things not in the DB
    for (ImmutablePair<Flow, Flow> flow : flowCache.dumpFlows()) {
        String key = flow.left.getFlowId() + flow.left.getCookie();
        // compare the left .. if it is in, then check the right .. o/w remove it (no need to check right
        if (!flowToInfo.containsKey(key)) {
            /* (carmine) - This code is to drop the flow from the cache since it isn't in the DB
 *  But - the user can just as easily call delete in the NB API .. which should do the right thing.
 *  So, for now, just add the flow id.
 */
            // String removedFlow = flowCache.removeFlow(flow.left.getFlowId()).toString();
            // String asJson = MAPPER.writeValueAsString(removedFlow);
            // droppedFlows.add(asJson);
            droppedFlows.add(flow.left.getFlowId());
        } else {
            key = flow.right.getFlowId() + flow.right.getCookie();
            if (!flowToInfo.containsKey(key)) {
                // (carmine) - same comment..
                // String removedFlow = flowCache.removeFlow(flow.left.getFlowId()).toString();
                // String asJson = MAPPER.writeValueAsString(removedFlow);
                // droppedFlows.add(asJson);
                droppedFlows.add(flow.right.getFlowId());
            }
        }
    }
    FlowCacheSyncResults results = new FlowCacheSyncResults(droppedFlows.toArray(new String[0]), addedFlows.toArray(new String[0]), modifiedFlows.toArray(new String[0]), unchangedFlows.toArray(new String[0]));
    Values northbound = new Values(new InfoMessage(new FlowCacheSyncResponse(results), message.getTimestamp(), message.getCorrelationId(), Destination.NORTHBOUND));
    outputCollector.emit(StreamType.RESPONSE.toString(), tuple, northbound);
}
Also used : Values(org.apache.storm.tuple.Values) Flow(org.openkilda.messaging.model.Flow) FlowInfo(org.openkilda.pce.provider.FlowInfo) InfoMessage(org.openkilda.messaging.info.InfoMessage) FlowCacheSyncResults(org.openkilda.messaging.payload.flow.FlowCacheSyncResults)

Example 9 with Flow

use of org.openkilda.messaging.model.Flow in project open-kilda by telstra.

the class CacheTopologyTest method buildFlowInfoData.

private FlowInfoData buildFlowInfoData(String flowId, String srcSwitch, String dstSwitch, List<PathNode> path) {
    Flow flow = new Flow();
    flow.setFlowId(flowId);
    flow.setSourceSwitch(srcSwitch);
    flow.setDestinationSwitch(dstSwitch);
    flow.setState(FlowState.UP);
    PathInfoData pathInfoData = new PathInfoData(0L, path);
    flow.setFlowPath(pathInfoData);
    ImmutablePair<Flow, Flow> immutablePair = new ImmutablePair<>(flow, flow);
    return new FlowInfoData(flowId, immutablePair, FlowOperation.CREATE, UUID.randomUUID().toString());
}
Also used : PathInfoData(org.openkilda.messaging.info.event.PathInfoData) FlowInfoData(org.openkilda.messaging.info.flow.FlowInfoData) ImmutablePair(org.openkilda.messaging.model.ImmutablePair) Flow(org.openkilda.messaging.model.Flow)

Example 10 with Flow

use of org.openkilda.messaging.model.Flow in project open-kilda by telstra.

the class FlowTopologyTest method dumpFlowsTopologyEngineBoltTest.

@Test
@Ignore
public void dumpFlowsTopologyEngineBoltTest() throws Exception {
    ConsumerRecord<String, String> nbRecord;
    String flowId = UUID.randomUUID().toString();
    List<Flow> payload = dumpFlowCommand(flowId);
    nbRecord = nbConsumer.pollMessage();
    assertNotNull(nbRecord);
    assertNotNull(nbRecord.value());
    InfoMessage response = objectMapper.readValue(nbRecord.value(), InfoMessage.class);
    assertNotNull(response);
    FlowsResponse responseData = (FlowsResponse) response.getData();
    assertNotNull(responseData);
    assertEquals(payload, responseData.getPayload());
}
Also used : InfoMessage(org.openkilda.messaging.info.InfoMessage) FlowsResponse(org.openkilda.messaging.info.flow.FlowsResponse) RemoveFlow(org.openkilda.messaging.command.flow.RemoveFlow) Flow(org.openkilda.messaging.model.Flow) InstallOneSwitchFlow(org.openkilda.messaging.command.flow.InstallOneSwitchFlow) Ignore(org.junit.Ignore) AbstractStormTest(org.openkilda.wfm.AbstractStormTest) Test(org.junit.Test)

Aggregations

Flow (org.openkilda.messaging.model.Flow)54 InfoMessage (org.openkilda.messaging.info.InfoMessage)23 Values (org.apache.storm.tuple.Values)14 PathInfoData (org.openkilda.messaging.info.event.PathInfoData)14 InstallOneSwitchFlow (org.openkilda.messaging.command.flow.InstallOneSwitchFlow)13 RemoveFlow (org.openkilda.messaging.command.flow.RemoveFlow)13 Test (org.junit.Test)12 CommandMessage (org.openkilda.messaging.command.CommandMessage)8 ImmutablePair (org.openkilda.messaging.model.ImmutablePair)8 AbstractStormTest (org.openkilda.wfm.AbstractStormTest)8 FlowResponse (org.openkilda.messaging.info.flow.FlowResponse)6 Then (cucumber.api.java.en.Then)5 FlowIdStatusPayload (org.openkilda.messaging.payload.flow.FlowIdStatusPayload)5 UnroutablePathException (org.openkilda.pce.provider.UnroutablePathException)5 Driver (org.neo4j.driver.v1.Driver)4 MessageException (org.openkilda.messaging.error.MessageException)4 FlowPayload (org.openkilda.messaging.payload.flow.FlowPayload)4 And (cucumber.api.java.en.And)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3