use of org.openkilda.messaging.payload.flow.FlowState in project open-kilda by telstra.
the class CrudBolt method execute.
/**
* {@inheritDoc}
*/
@Override
public void execute(Tuple tuple) {
if (CtrlAction.boltHandlerEntrance(this, tuple))
return;
logger.trace("Flow Cache before: {}", flowCache);
ComponentType componentId = ComponentType.valueOf(tuple.getSourceComponent());
StreamType streamId = StreamType.valueOf(tuple.getSourceStreamId());
String flowId = tuple.getStringByField(Utils.FLOW_ID);
String correlationId = Utils.DEFAULT_CORRELATION_ID;
try {
logger.debug("Request tuple={}", tuple);
switch(componentId) {
case SPLITTER_BOLT:
Message msg = (Message) tuple.getValueByField(AbstractTopology.MESSAGE_FIELD);
correlationId = msg.getCorrelationId();
CommandMessage cmsg = (msg instanceof CommandMessage) ? (CommandMessage) msg : null;
InfoMessage imsg = (msg instanceof InfoMessage) ? (InfoMessage) msg : null;
logger.info("Flow request: {}={}, {}={}, component={}, stream={}", Utils.CORRELATION_ID, correlationId, Utils.FLOW_ID, flowId, componentId, streamId);
switch(streamId) {
case CREATE:
handleCreateRequest(cmsg, tuple);
break;
case UPDATE:
handleUpdateRequest(cmsg, tuple);
break;
case DELETE:
handleDeleteRequest(flowId, cmsg, tuple);
break;
case PUSH:
handlePushRequest(flowId, imsg, tuple);
break;
case UNPUSH:
handleUnpushRequest(flowId, imsg, tuple);
break;
case PATH:
handlePathRequest(flowId, cmsg, tuple);
break;
case RESTORE:
handleRestoreRequest(cmsg, tuple);
break;
case REROUTE:
handleRerouteRequest(cmsg, tuple);
break;
case STATUS:
handleStatusRequest(flowId, cmsg, tuple);
break;
case CACHE_SYNC:
handleCacheSyncRequest(cmsg, tuple);
break;
case READ:
if (flowId != null) {
handleReadRequest(flowId, cmsg, tuple);
} else {
handleDumpRequest(cmsg, tuple);
}
break;
default:
logger.debug("Unexpected stream: component={}, stream={}", componentId, streamId);
break;
}
break;
case SPEAKER_BOLT:
case TRANSACTION_BOLT:
FlowState newStatus = (FlowState) tuple.getValueByField(FlowTopology.STATUS_FIELD);
logger.info("Flow {} status {}: component={}, stream={}", flowId, newStatus, componentId, streamId);
switch(streamId) {
case STATUS:
handleStateRequest(flowId, newStatus, tuple);
break;
default:
logger.debug("Unexpected stream: component={}, stream={}", componentId, streamId);
break;
}
break;
case TOPOLOGY_ENGINE_BOLT:
ErrorMessage errorMessage = (ErrorMessage) tuple.getValueByField(AbstractTopology.MESSAGE_FIELD);
logger.info("Flow {} error: component={}, stream={}", flowId, componentId, streamId);
switch(streamId) {
case STATUS:
handleErrorRequest(flowId, errorMessage, tuple);
break;
default:
logger.debug("Unexpected stream: component={}, stream={}", componentId, streamId);
break;
}
break;
default:
logger.debug("Unexpected component: {}", componentId);
break;
}
} catch (CacheException exception) {
String logMessage = format("%s: %s", exception.getErrorMessage(), exception.getErrorDescription());
logger.error("{}, {}={}, {}={}, component={}, stream={}", logMessage, Utils.CORRELATION_ID, correlationId, Utils.FLOW_ID, flowId, componentId, streamId, exception);
ErrorMessage errorMessage = buildErrorMessage(correlationId, exception.getErrorType(), logMessage, componentId.toString().toLowerCase());
Values error = new Values(errorMessage, exception.getErrorType());
outputCollector.emit(StreamType.ERROR.toString(), tuple, error);
} catch (IOException exception) {
logger.error("Could not deserialize message {}", tuple, exception);
} finally {
logger.debug("Command message ack: component={}, stream={}, tuple={}", tuple.getSourceComponent(), tuple.getSourceStreamId(), tuple);
outputCollector.ack(tuple);
}
logger.trace("Flow Cache after: {}", flowCache);
}
use of org.openkilda.messaging.payload.flow.FlowState in project open-kilda by telstra.
the class SpeakerBolt method execute.
/**
* {@inheritDoc}
*/
@Override
public void execute(Tuple tuple) {
String request = tuple.getString(0);
Values values = null;
try {
Message message = MAPPER.readValue(request, Message.class);
if (!Destination.WFM_TRANSACTION.equals(message.getDestination())) {
return;
}
logger.debug("Request tuple={}", tuple);
if (message instanceof CommandMessage) {
CommandData data = ((CommandMessage) message).getData();
if (data instanceof BaseInstallFlow) {
Long transactionId = ((BaseInstallFlow) data).getTransactionId();
String switchId = ((BaseInstallFlow) data).getSwitchId();
String flowId = ((BaseInstallFlow) data).getId();
logger.debug("Flow install message: {}={}, switch-id={}, {}={}, {}={}, message={}", Utils.CORRELATION_ID, message.getCorrelationId(), switchId, Utils.FLOW_ID, flowId, Utils.TRANSACTION_ID, transactionId, request);
message.setDestination(Destination.TOPOLOGY_ENGINE);
values = new Values(MAPPER.writeValueAsString(message), switchId, flowId, transactionId);
// FIXME(surabujin): looks like TE ignore this messages
outputCollector.emit(StreamType.CREATE.toString(), tuple, values);
} else if (data instanceof RemoveFlow) {
Long transactionId = ((RemoveFlow) data).getTransactionId();
String switchId = ((RemoveFlow) data).getSwitchId();
String flowId = ((RemoveFlow) data).getId();
logger.debug("Flow remove message: {}={}, switch-id={}, {}={}, {}={}, message={}", Utils.CORRELATION_ID, message.getCorrelationId(), switchId, Utils.FLOW_ID, flowId, Utils.TRANSACTION_ID, transactionId, request);
message.setDestination(Destination.TOPOLOGY_ENGINE);
values = new Values(MAPPER.writeValueAsString(message), switchId, flowId, transactionId);
outputCollector.emit(StreamType.DELETE.toString(), tuple, values);
} else {
logger.debug("Skip undefined command message: {}={}, message={}", Utils.CORRELATION_ID, message.getCorrelationId(), request);
}
} else if (message instanceof ErrorMessage) {
String flowId = ((ErrorMessage) message).getData().getErrorDescription();
FlowState status = FlowState.DOWN;
// TODO: Should add debug message if receiving ErrorMessage.
if (flowId != null) {
logger.error("Flow error message: {}={}, {}={}, message={}", Utils.CORRELATION_ID, message.getCorrelationId(), Utils.FLOW_ID, flowId, request);
values = new Values(flowId, status);
outputCollector.emit(StreamType.STATUS.toString(), tuple, values);
} else {
logger.debug("Skip error message without flow-id: {}={}, message={}", Utils.CORRELATION_ID, message.getCorrelationId(), request);
}
} else {
// TODO: should this be a warn or error? Probably, after refactored / specific
// topics
logger.debug("Skip undefined message: {}={}, message={}", Utils.CORRELATION_ID, message.getCorrelationId(), request);
}
} catch (IOException exception) {
logger.error("\n\nCould not deserialize message={}", request, exception);
} finally {
logger.debug("Speaker message ack: component={}, stream={}, tuple={}, values={}", tuple.getSourceComponent(), tuple.getSourceStreamId(), tuple, values);
outputCollector.ack(tuple);
}
}
use of org.openkilda.messaging.payload.flow.FlowState in project open-kilda by telstra.
the class CrudBolt method handleStatusRequest.
private void handleStatusRequest(String flowId, CommandMessage message, Tuple tuple) throws IOException {
ImmutablePair<Flow, Flow> flow = flowCache.getFlow(flowId);
FlowState status = flow.getLeft().getState();
logger.info("Status flow: {}={}", flowId, status);
Values northbound = new Values(new InfoMessage(new FlowStatusResponse(new FlowIdStatusPayload(flowId, status)), message.getTimestamp(), message.getCorrelationId(), Destination.NORTHBOUND));
outputCollector.emit(StreamType.RESPONSE.toString(), tuple, northbound);
}
use of org.openkilda.messaging.payload.flow.FlowState in project open-kilda by telstra.
the class FlowServiceImpl method flowPushUnpush.
/**
* There are only minor differences between push and unpush .. this utility function helps
*/
private BatchResults flowPushUnpush(List<FlowInfoData> externalFlows, String correlationId, FlowOperation op) {
LOGGER.debug("Flow {}: {}={}", op, CORRELATION_ID, correlationId);
LOGGER.debug("Size of list: {}", externalFlows.size());
// First, send them all, then wait for all the responses.
// Send the command to both Flow Topology and to TE
messageConsumer.clear();
// used for error reporting, if needed
ArrayList<InfoMessage> flowRequests = new ArrayList<>();
// used for error reporting, if needed
ArrayList<InfoMessage> teRequests = new ArrayList<>();
for (int i = 0; i < externalFlows.size(); i++) {
FlowInfoData data = externalFlows.get(i);
// <-- this is what determines PUSH / UNPUSH
data.setOperation(op);
String flowCorrelation = correlationId + "-FLOW-" + i;
InfoMessage flowRequest = new InfoMessage(data, System.currentTimeMillis(), flowCorrelation, Destination.WFM);
flowRequests.add(flowRequest);
messageProducer.send(topic, flowRequest);
String teCorrelation = correlationId + "-TE-" + i;
InfoMessage teRequest = new InfoMessage(data, System.currentTimeMillis(), teCorrelation, Destination.TOPOLOGY_ENGINE);
teRequests.add(teRequest);
messageProducer.send(topoEngTopic, teRequest);
}
int flow_success = 0;
int flow_failure = 0;
int te_success = 0;
int te_failure = 0;
List<String> msgs = new ArrayList<>();
msgs.add("Total Flows Received: " + externalFlows.size());
for (int i = 0; i < externalFlows.size(); i++) {
String flowCorrelation = correlationId + "-FLOW-" + i;
String teCorrelation = correlationId + "-TE-" + i;
FlowState expectedState = (op == FlowOperation.PUSH) ? FlowState.UP : FlowState.DOWN;
try {
Message flowMessage = (Message) messageConsumer.poll(flowCorrelation);
FlowStatusResponse response = (FlowStatusResponse) validateInfoMessage(flowRequests.get(i), flowMessage, correlationId);
FlowIdStatusPayload status = response.getPayload();
if (status.getStatus() == expectedState) {
flow_success++;
} else {
msgs.add("FAILURE (FlowTopo): Flow " + status.getId() + " NOT in " + expectedState + " state: state = " + status.getStatus());
flow_failure++;
}
} catch (Exception e) {
msgs.add("EXCEPTION in Flow Topology Response: " + e.getMessage());
flow_failure++;
}
try {
// TODO: this code block is mostly the same as the previous: consolidate.
Message teMessage = (Message) messageConsumer.poll(teCorrelation);
FlowStatusResponse response = (FlowStatusResponse) validateInfoMessage(flowRequests.get(i), teMessage, correlationId);
FlowIdStatusPayload status = response.getPayload();
if (status.getStatus() == expectedState) {
te_success++;
} else {
msgs.add("FAILURE (TE): Flow " + status.getId() + " NOT in " + expectedState + " state: state = " + status.getStatus());
te_failure++;
}
} catch (Exception e) {
msgs.add("EXCEPTION in Topology Engine Response: " + e.getMessage());
te_failure++;
}
}
BatchResults result = new BatchResults(flow_failure + te_failure, flow_success + te_success, msgs.stream().toArray(String[]::new));
LOGGER.debug("Returned: ", result);
return result;
}
use of org.openkilda.messaging.payload.flow.FlowState in project open-kilda by telstra.
the class NorthboundRunTest method flowState.
@Then("^flow (\\w+) in (\\w+) state$")
public void flowState(String flowId, String state) throws Throwable {
String flowName = FlowUtils.getFlowName(flowId);
FlowState flowState = FlowState.valueOf(state);
FlowIdStatusPayload payload = FlowUtils.waitFlowStatus(flowName, flowState);
assertNotNull(payload);
assertEquals(flowName, payload.getId());
assertEquals(flowState, payload.getStatus());
}
Aggregations