Search in sources :

Example 1 with FlowState

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);
}
Also used : StreamType(org.openkilda.wfm.topology.flow.StreamType) ComponentType(org.openkilda.wfm.topology.flow.ComponentType) FlowState(org.openkilda.messaging.payload.flow.FlowState) InfoMessage(org.openkilda.messaging.info.InfoMessage) CommandMessage(org.openkilda.messaging.command.CommandMessage) Message(org.openkilda.messaging.Message) ErrorMessage(org.openkilda.messaging.error.ErrorMessage) CacheException(org.openkilda.messaging.error.CacheException) InfoMessage(org.openkilda.messaging.info.InfoMessage) Values(org.apache.storm.tuple.Values) IOException(java.io.IOException) ErrorMessage(org.openkilda.messaging.error.ErrorMessage) CommandMessage(org.openkilda.messaging.command.CommandMessage)

Example 2 with FlowState

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);
    }
}
Also used : FlowState(org.openkilda.messaging.payload.flow.FlowState) Message(org.openkilda.messaging.Message) CommandMessage(org.openkilda.messaging.command.CommandMessage) ErrorMessage(org.openkilda.messaging.error.ErrorMessage) RemoveFlow(org.openkilda.messaging.command.flow.RemoveFlow) Values(org.apache.storm.tuple.Values) BaseInstallFlow(org.openkilda.messaging.command.flow.BaseInstallFlow) IOException(java.io.IOException) CommandData(org.openkilda.messaging.command.CommandData) ErrorMessage(org.openkilda.messaging.error.ErrorMessage) CommandMessage(org.openkilda.messaging.command.CommandMessage)

Example 3 with FlowState

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);
}
Also used : FlowState(org.openkilda.messaging.payload.flow.FlowState) FlowIdStatusPayload(org.openkilda.messaging.payload.flow.FlowIdStatusPayload) InfoMessage(org.openkilda.messaging.info.InfoMessage) Values(org.apache.storm.tuple.Values) Flow(org.openkilda.messaging.model.Flow)

Example 4 with FlowState

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;
}
Also used : FlowInfoData(org.openkilda.messaging.info.flow.FlowInfoData) FlowState(org.openkilda.messaging.payload.flow.FlowState) FlowStatusResponse(org.openkilda.messaging.info.flow.FlowStatusResponse) InfoMessage(org.openkilda.messaging.info.InfoMessage) Message(org.openkilda.messaging.Message) CommandMessage(org.openkilda.messaging.command.CommandMessage) FlowIdStatusPayload(org.openkilda.messaging.payload.flow.FlowIdStatusPayload) ArrayList(java.util.ArrayList) BatchResults(org.openkilda.northbound.service.BatchResults) InfoMessage(org.openkilda.messaging.info.InfoMessage)

Example 5 with FlowState

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());
}
Also used : FlowState(org.openkilda.messaging.payload.flow.FlowState) FlowIdStatusPayload(org.openkilda.messaging.payload.flow.FlowIdStatusPayload) Then(cucumber.api.java.en.Then)

Aggregations

FlowState (org.openkilda.messaging.payload.flow.FlowState)5 Values (org.apache.storm.tuple.Values)3 Message (org.openkilda.messaging.Message)3 CommandMessage (org.openkilda.messaging.command.CommandMessage)3 InfoMessage (org.openkilda.messaging.info.InfoMessage)3 FlowIdStatusPayload (org.openkilda.messaging.payload.flow.FlowIdStatusPayload)3 IOException (java.io.IOException)2 ErrorMessage (org.openkilda.messaging.error.ErrorMessage)2 Then (cucumber.api.java.en.Then)1 ArrayList (java.util.ArrayList)1 CommandData (org.openkilda.messaging.command.CommandData)1 BaseInstallFlow (org.openkilda.messaging.command.flow.BaseInstallFlow)1 RemoveFlow (org.openkilda.messaging.command.flow.RemoveFlow)1 CacheException (org.openkilda.messaging.error.CacheException)1 FlowInfoData (org.openkilda.messaging.info.flow.FlowInfoData)1 FlowStatusResponse (org.openkilda.messaging.info.flow.FlowStatusResponse)1 Flow (org.openkilda.messaging.model.Flow)1 BatchResults (org.openkilda.northbound.service.BatchResults)1 ComponentType (org.openkilda.wfm.topology.flow.ComponentType)1 StreamType (org.openkilda.wfm.topology.flow.StreamType)1