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);
}
}
}
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;
}
}
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);
}
}
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));
}
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));
}
Aggregations