Search in sources :

Example 26 with InfoMessage

use of org.openkilda.messaging.info.InfoMessage in project open-kilda by telstra.

the class StatsTopologyTest method meterConfigStatsTest.

@Test
public void meterConfigStatsTest() throws Exception {
    final String switchId = "00:00:00:00:00:00:00:01";
    final List<MeterConfigReply> stats = Collections.singletonList(new MeterConfigReply(2, Arrays.asList(1L, 2L, 3L)));
    InfoMessage message = new InfoMessage(new MeterConfigStatsData(switchId, stats), timestamp, CORRELATION_ID, Destination.WFM_STATS);
    // mock kafka spout
    MockedSources sources = new MockedSources();
    sources.addMockData(StatsComponentType.STATS_OFS_KAFKA_SPOUT.toString(), new Values(MAPPER.writeValueAsString(message)));
    completeTopologyParam.setMockedSources(sources);
    // execute topology
    Testing.withTrackedCluster(clusterParam, (cluster) -> {
        StatsTopology topology = new TestingTargetTopology(new TestingKafkaBolt());
        StormTopology stormTopology = topology.createTopology();
        // verify results
        Map result = Testing.completeTopology(cluster, stormTopology, completeTopologyParam);
        ArrayList<FixedTuple> tuples = (ArrayList<FixedTuple>) result.get(StatsComponentType.METER_CFG_STATS_METRIC_GEN.name());
        assertThat(tuples.size(), is(3));
        tuples.stream().map(this::readFromJson).forEach(datapoint -> {
            assertThat(datapoint.getTags().get("switchid"), is(switchId.replaceAll(":", "")));
            assertThat(datapoint.getTime(), is(timestamp));
            assertThat(datapoint.getMetric(), is("pen.switch.meters"));
        });
    });
}
Also used : MeterConfigStatsData(org.openkilda.messaging.info.stats.MeterConfigStatsData) StormTopology(org.apache.storm.generated.StormTopology) Values(org.apache.storm.tuple.Values) TestingKafkaBolt(org.openkilda.wfm.topology.TestingKafkaBolt) MeterConfigReply(org.openkilda.messaging.info.stats.MeterConfigReply) FixedTuple(org.apache.storm.testing.FixedTuple) MockedSources(org.apache.storm.testing.MockedSources) InfoMessage(org.openkilda.messaging.info.InfoMessage) StableAbstractStormTest(org.openkilda.wfm.StableAbstractStormTest) Test(org.junit.Test)

Example 27 with InfoMessage

use of org.openkilda.messaging.info.InfoMessage in project open-kilda by telstra.

the class RecordHandler method doDumpRulesRequest.

private void doDumpRulesRequest(final CommandMessage message) {
    DumpRulesRequest request = (DumpRulesRequest) message.getData();
    final String switchId = request.getSwitchId();
    logger.debug("Loading installed rules for switch {}", switchId);
    OFFlowStatsReply reply = context.getSwitchManager().dumpFlowTable(DatapathId.of(switchId));
    List<FlowEntry> flows = reply.getEntries().stream().map(OFFlowStatsConverter::toFlowEntry).collect(Collectors.toList());
    SwitchFlowEntries response = SwitchFlowEntries.builder().switchId(switchId).flowEntries(flows).build();
    InfoMessage infoMessage = new InfoMessage(response, message.getTimestamp(), message.getCorrelationId());
    context.getKafkaProducer().postMessage(TOPO_ENG_TOPIC, infoMessage);
}
Also used : DumpRulesRequest(org.openkilda.messaging.command.switches.DumpRulesRequest) SwitchFlowEntries(org.openkilda.messaging.info.rule.SwitchFlowEntries) InfoMessage(org.openkilda.messaging.info.InfoMessage) OFFlowStatsReply(org.projectfloodlight.openflow.protocol.OFFlowStatsReply) FlowEntry(org.openkilda.messaging.info.rule.FlowEntry)

Example 28 with InfoMessage

use of org.openkilda.messaging.info.InfoMessage in project open-kilda by telstra.

the class PathVerificationService method handlePacketIn.

private IListener.Command handlePacketIn(IOFSwitch sw, OFPacketIn pkt, FloodlightContext context) {
    long time = System.currentTimeMillis();
    logger.debug("packet_in {} received from {}", pkt.getXid(), sw.getId());
    VerificationPacket verificationPacket = null;
    Ethernet eth = IFloodlightProviderService.bcStore.get(context, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
    try {
        verificationPacket = deserialize(eth);
    } catch (Exception exception) {
        logger.error("Deserialization failure: {}, exception: {}", exception.getMessage(), exception);
        return Command.CONTINUE;
    }
    try {
        OFPort inPort = pkt.getVersion().compareTo(OFVersion.OF_12) < 0 ? pkt.getInPort() : pkt.getMatch().get(MatchField.IN_PORT);
        ByteBuffer portBB = ByteBuffer.wrap(verificationPacket.getPortId().getValue());
        portBB.position(1);
        OFPort remotePort = OFPort.of(portBB.getShort());
        long timestamp = 0;
        int pathOrdinal = 10;
        IOFSwitch remoteSwitch = null;
        boolean signed = false;
        for (LLDPTLV lldptlv : verificationPacket.getOptionalTLVList()) {
            if (lldptlv.getType() == 127 && lldptlv.getLength() == 12 && lldptlv.getValue()[0] == 0x0 && lldptlv.getValue()[1] == 0x26 && lldptlv.getValue()[2] == (byte) 0xe1 && lldptlv.getValue()[3] == 0x0) {
                ByteBuffer dpidBB = ByteBuffer.wrap(lldptlv.getValue());
                remoteSwitch = switchService.getSwitch(DatapathId.of(dpidBB.getLong(4)));
            } else if (lldptlv.getType() == 127 && lldptlv.getLength() == 12 && lldptlv.getValue()[0] == 0x0 && lldptlv.getValue()[1] == 0x26 && lldptlv.getValue()[2] == (byte) 0xe1 && lldptlv.getValue()[3] == 0x01) {
                ByteBuffer tsBB = ByteBuffer.wrap(lldptlv.getValue());
                /* skip OpenFlow OUI (4 bytes above) */
                long swLatency = sw.getLatency().getValue();
                timestamp = tsBB.getLong(4);
                /* include the RX switch latency to "subtract" it */
                timestamp = timestamp + swLatency;
            } else if (lldptlv.getType() == 127 && lldptlv.getLength() == 8 && lldptlv.getValue()[0] == 0x0 && lldptlv.getValue()[1] == 0x26 && lldptlv.getValue()[2] == (byte) 0xe1 && lldptlv.getValue()[3] == 0x02) {
                ByteBuffer typeBB = ByteBuffer.wrap(lldptlv.getValue());
                pathOrdinal = typeBB.getInt(4);
            } else if (lldptlv.getType() == 127 && lldptlv.getValue()[0] == 0x0 && lldptlv.getValue()[1] == 0x26 && lldptlv.getValue()[2] == (byte) 0xe1 && lldptlv.getValue()[3] == 0x03) {
                ByteBuffer bb = ByteBuffer.wrap(lldptlv.getValue());
                bb.position(4);
                byte[] tokenArray = new byte[lldptlv.getLength() - 4];
                bb.get(tokenArray, 0, tokenArray.length);
                String token = new String(tokenArray);
                try {
                    DecodedJWT jwt = verifier.verify(token);
                    signed = true;
                } catch (JWTVerificationException e) {
                    logger.error("Packet verification failed", e);
                    return Command.STOP;
                }
            }
        }
        if (remoteSwitch == null) {
            return Command.STOP;
        }
        if (!signed) {
            logger.warn("verification packet without sign");
            return Command.STOP;
        }
        U64 latency = (timestamp != 0 && (time - timestamp) > 0) ? U64.of(time - timestamp) : U64.ZERO;
        logger.debug("link discovered: {}-{} ===( {} ms )===> {}-{}", remoteSwitch.getId(), remotePort, latency.getValue(), sw.getId(), inPort);
        // this verification packet was sent from remote switch/port to received switch/port
        // so the link direction is from remote switch/port to received switch/port
        List<PathNode> nodes = Arrays.asList(new PathNode(remoteSwitch.getId().toString(), remotePort.getPortNumber(), 0, latency.getValue()), new PathNode(sw.getId().toString(), inPort.getPortNumber(), 1));
        OFPortDesc port = sw.getPort(inPort);
        long speed = Integer.MAX_VALUE;
        if (port.getVersion().compareTo(OFVersion.OF_13) > 0) {
            for (OFPortDescProp prop : port.getProperties()) {
                if (prop.getType() == 0x0) {
                    speed = ((OFPortDescPropEthernet) prop).getCurrSpeed();
                }
            }
        } else {
            speed = port.getCurrSpeed();
        }
        IslInfoData path = new IslInfoData(latency.getValue(), nodes, speed, IslChangeType.DISCOVERED, getAvailableBandwidth(speed));
        Message message = new InfoMessage(path, System.currentTimeMillis(), "system", null);
        final String json = MAPPER.writeValueAsString(message);
        logger.debug("about to send {}", json);
        producer.send(new ProducerRecord<>(TOPIC, json));
        logger.debug("packet_in processed for {}-{}", sw.getId(), inPort);
    } catch (JsonProcessingException exception) {
        logger.error("could not create json for path packet_in: {}", exception.getMessage(), exception);
    } catch (UnsupportedOperationException exception) {
        logger.error("could not parse packet_in message: {}", exception.getMessage(), exception);
    } catch (Exception exception) {
        logger.error("unknown error during packet_in message processing: {}", exception.getMessage(), exception);
        throw exception;
    }
    return Command.STOP;
}
Also used : IOFSwitch(net.floodlightcontroller.core.IOFSwitch) InfoMessage(org.openkilda.messaging.info.InfoMessage) OFMessage(org.projectfloodlight.openflow.protocol.OFMessage) Message(org.openkilda.messaging.Message) OFPortDescProp(org.projectfloodlight.openflow.protocol.OFPortDescProp) PathNode(org.openkilda.messaging.info.event.PathNode) ByteBuffer(java.nio.ByteBuffer) UnsupportedEncodingException(java.io.UnsupportedEncodingException) JWTVerificationException(com.auth0.jwt.exceptions.JWTVerificationException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) FloodlightModuleException(net.floodlightcontroller.core.module.FloodlightModuleException) JWTVerificationException(com.auth0.jwt.exceptions.JWTVerificationException) U64(org.projectfloodlight.openflow.types.U64) OFPortDesc(org.projectfloodlight.openflow.protocol.OFPortDesc) InfoMessage(org.openkilda.messaging.info.InfoMessage) OFPortDescPropEthernet(org.projectfloodlight.openflow.protocol.OFPortDescPropEthernet) Ethernet(net.floodlightcontroller.packet.Ethernet) OFPort(org.projectfloodlight.openflow.types.OFPort) IslInfoData(org.openkilda.messaging.info.event.IslInfoData) DecodedJWT(com.auth0.jwt.interfaces.DecodedJWT) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) LLDPTLV(net.floodlightcontroller.packet.LLDPTLV)

Example 29 with InfoMessage

use of org.openkilda.messaging.info.InfoMessage in project open-kilda by telstra.

the class KafkaMessageConsumer method receive.

/**
 * Receives messages from WorkFlowManager queue.
 *
 * @param record the message object instance
 */
@KafkaListener(topics = "kilda-test")
public void receive(final String record) {
    logger.debug("message received: {}", record);
    try {
        Message message = MAPPER.readValue(record, Message.class);
        if (message.getDestination() == null || Destination.TOPOLOGY_ENGINE.equals(message.getDestination())) {
            if (message instanceof CommandMessage) {
                CommandData data = ((CommandMessage) message).getData();
                if (data instanceof FlowCreateRequest) {
                    FlowPayload payload = ((FlowCreateRequest) data).getPayload();
                    logger.debug("FlowCreateRequest: {}", payload);
                    Set<CommandMessage> commands = flowService.createFlow(payload, message.getCorrelationId());
                    for (CommandMessage response : commands) {
                        kafkaMessageProducer.send(topic, response);
                    }
                    logger.debug("Response send, {}={}", CORRELATION_ID, message.getCorrelationId());
                } else if (data instanceof FlowDeleteRequest) {
                    FlowIdStatusPayload payload = ((FlowDeleteRequest) data).getPayload();
                    logger.debug("FlowDeleteRequest: {}", payload);
                    Set<CommandMessage> commands = flowService.deleteFlow(payload, message.getCorrelationId());
                    for (CommandMessage response : commands) {
                        kafkaMessageProducer.send(topic, response);
                    }
                    logger.debug("Response send, {}={}", CORRELATION_ID, message.getCorrelationId());
                } else if (data instanceof FlowUpdateRequest) {
                    FlowPayload payload = ((FlowUpdateRequest) data).getPayload();
                    logger.debug("FlowUpdateRequest: {}", payload);
                    Set<CommandMessage> commands = flowService.updateFlow(payload, message.getCorrelationId());
                    for (CommandMessage response : commands) {
                        kafkaMessageProducer.send(topic, response);
                    }
                    logger.debug("Response send, {}={}", CORRELATION_ID, message.getCorrelationId());
                } else if (data instanceof FlowGetRequest) {
                    FlowIdStatusPayload payload = ((FlowGetRequest) data).getPayload();
                    logger.debug("FlowGetRequest: {}", payload);
                    InfoMessage response = flowService.getFlow(payload, message.getCorrelationId());
                    kafkaMessageProducer.send(topic, response);
                    logger.debug("Response send, {}={}", CORRELATION_ID, message.getCorrelationId());
                } else if (data instanceof FlowsGetRequest) {
                    FlowIdStatusPayload payload = ((FlowsGetRequest) data).getPayload();
                    logger.debug("FlowsGetRequest: {}", payload);
                    InfoMessage response = flowService.getFlows(payload, message.getCorrelationId());
                    kafkaMessageProducer.send(topic, response);
                    logger.debug("Response send, {}={}", CORRELATION_ID, message.getCorrelationId());
                } else if (data instanceof FlowPathRequest) {
                    FlowIdStatusPayload payload = ((FlowPathRequest) data).getPayload();
                    logger.debug("FlowPathRequest: {}", payload);
                    InfoMessage response = flowService.pathFlow(payload, message.getCorrelationId());
                    kafkaMessageProducer.send(topic, response);
                    logger.debug("Response send, {}={}", CORRELATION_ID, message.getCorrelationId());
                } else {
                    logger.error("Unexpected command message data type: {}", data);
                }
            } else if (message instanceof InfoMessage) {
                InfoData data = ((InfoMessage) message).getData();
                if (data instanceof SwitchInfoData) {
                    SwitchInfoData payload = (SwitchInfoData) data;
                    switch(payload.getState()) {
                        case ADDED:
                            switchService.add(payload);
                            break;
                        case ACTIVATED:
                            switchService.activate(payload);
                            break;
                        case DEACTIVATED:
                            switchService.deactivate(payload);
                            break;
                        case REMOVED:
                            switchService.remove(payload);
                            break;
                        case CHANGED:
                        default:
                            break;
                    }
                } else if (data instanceof IslInfoData) {
                    IslInfoData payload = (IslInfoData) data;
                    islService.discoverLink(payload);
                } else {
                    logger.debug("Unexpected info message data type: {}", data);
                }
            }
        } else {
            logger.debug("Skip message: {}", message);
        }
    } catch (IOException exception) {
        logger.error("Could not deserialize message: {}", record, exception);
    }
}
Also used : FlowsGetRequest(org.openkilda.messaging.command.flow.FlowsGetRequest) Set(java.util.Set) FlowUpdateRequest(org.openkilda.messaging.command.flow.FlowUpdateRequest) InfoMessage(org.openkilda.messaging.info.InfoMessage) Message(org.openkilda.messaging.Message) CommandMessage(org.openkilda.messaging.command.CommandMessage) FlowIdStatusPayload(org.openkilda.messaging.payload.flow.FlowIdStatusPayload) FlowDeleteRequest(org.openkilda.messaging.command.flow.FlowDeleteRequest) FlowCreateRequest(org.openkilda.messaging.command.flow.FlowCreateRequest) FlowGetRequest(org.openkilda.messaging.command.flow.FlowGetRequest) IOException(java.io.IOException) CommandMessage(org.openkilda.messaging.command.CommandMessage) FlowPayload(org.openkilda.messaging.payload.flow.FlowPayload) InfoMessage(org.openkilda.messaging.info.InfoMessage) IslInfoData(org.openkilda.messaging.info.event.IslInfoData) SwitchInfoData(org.openkilda.messaging.info.event.SwitchInfoData) InfoData(org.openkilda.messaging.info.InfoData) IslInfoData(org.openkilda.messaging.info.event.IslInfoData) CommandData(org.openkilda.messaging.command.CommandData) SwitchInfoData(org.openkilda.messaging.info.event.SwitchInfoData) FlowPathRequest(org.openkilda.messaging.command.flow.FlowPathRequest) KafkaListener(org.springframework.kafka.annotation.KafkaListener)

Example 30 with InfoMessage

use of org.openkilda.messaging.info.InfoMessage in project open-kilda by telstra.

the class BasicService method validateInfoMessage.

/**
 * Validates info message.
 *
 * @param correlationId  request correlation id
 * @param commandMessage request command message
 * @param message        response info message
 * @return parsed response InfoData
 */
default InfoData validateInfoMessage(final CommandMessage commandMessage, final Message message, final String correlationId) {
    InfoData data;
    if (message != null) {
        if (message instanceof ErrorMessage) {
            ErrorData error = ((ErrorMessage) message).getData();
            logger.error("Response message is error: {}={}, command={}, error={}", CORRELATION_ID, correlationId, commandMessage, error);
            throw new MessageException(error.getErrorType(), message.getTimestamp());
        } else if (message instanceof InfoMessage) {
            InfoMessage info = (InfoMessage) message;
            data = info.getData();
            if (data == null) {
                logger.error("Response message data is empty: {}={}, command={}, info={}", CORRELATION_ID, correlationId, commandMessage, info);
                throw new MessageException(INTERNAL_ERROR, message.getTimestamp());
            }
        } else {
            logger.error("Response message type is unexpected: {}:{}, command={}, message={}", CORRELATION_ID, correlationId, commandMessage, message);
            throw new MessageException(INTERNAL_ERROR, message.getTimestamp());
        }
    } else {
        logger.error("Response message is empty: {}={}, command={}", CORRELATION_ID, correlationId, commandMessage);
        throw new MessageException(INTERNAL_ERROR, System.currentTimeMillis());
    }
    return data;
}
Also used : MessageException(org.openkilda.messaging.error.MessageException) InfoData(org.openkilda.messaging.info.InfoData) InfoMessage(org.openkilda.messaging.info.InfoMessage) ErrorMessage(org.openkilda.messaging.error.ErrorMessage) ErrorData(org.openkilda.messaging.error.ErrorData)

Aggregations

InfoMessage (org.openkilda.messaging.info.InfoMessage)87 Test (org.junit.Test)34 Values (org.apache.storm.tuple.Values)27 CommandMessage (org.openkilda.messaging.command.CommandMessage)21 Flow (org.openkilda.messaging.model.Flow)21 Message (org.openkilda.messaging.Message)20 ErrorMessage (org.openkilda.messaging.error.ErrorMessage)19 AbstractStormTest (org.openkilda.wfm.AbstractStormTest)19 RemoveFlow (org.openkilda.messaging.command.flow.RemoveFlow)13 InstallOneSwitchFlow (org.openkilda.messaging.command.flow.InstallOneSwitchFlow)12 FlowIdStatusPayload (org.openkilda.messaging.payload.flow.FlowIdStatusPayload)12 IOException (java.io.IOException)9 SwitchInfoData (org.openkilda.messaging.info.event.SwitchInfoData)9 ErrorData (org.openkilda.messaging.error.ErrorData)8 InfoData (org.openkilda.messaging.info.InfoData)8 PortInfoData (org.openkilda.messaging.info.event.PortInfoData)8 FlowResponse (org.openkilda.messaging.info.flow.FlowResponse)8 FlowStatusResponse (org.openkilda.messaging.info.flow.FlowStatusResponse)8 NetworkInfoData (org.openkilda.messaging.info.discovery.NetworkInfoData)7 IslInfoData (org.openkilda.messaging.info.event.IslInfoData)7