From b46470c3ffc0e8ed3fbc578191d165f00b97c8ce Mon Sep 17 00:00:00 2001 From: dkakollu Date: Wed, 28 Dec 2022 12:56:00 +0000 Subject: [PATCH 1/9] Issue-4964 Add information about LACP connection status model updates --- .../025-add-lacp-partner-class.yaml | 34 +++ docker/db-migration/migrations/root.yaml | 3 + .../messaging/info/event/LacpInfoData.java | 39 +++ .../messaging/info/event/LacpPartner.java | 41 +++ .../messaging/info/event/LacpState.java | 41 +++ .../ConnectedDevicesTopology.java | 33 ++- .../ConnectedDevicesTopologyConfig.java | 5 + .../connecteddevices/bolts/PacketBolt.java | 7 +- .../connecteddevices/bolts/RouterBolt.java | 5 +- .../service/PacketService.java | 93 ++++++- .../service/PacketServiceTest.java | 46 +++- .../openkilda/floodlight/KafkaChannel.java | 4 + .../floodlight/service/lacp/LacpService.java | 106 +++++--- .../floodlightrouter/ComponentType.java | 2 + .../FloodlightRouterTopology.java | 6 + .../openkilda/config/KafkaTopicsConfig.java | 8 + .../java/org/openkilda/model/LacpPartner.java | 256 ++++++++++++++++++ .../repositories/LacpPartnerRepository.java | 30 ++ .../repositories/RepositoryAreaBinding.java | 1 + .../repositories/RepositoryFactory.java | 2 + .../repositories/RepositoryFactoryProxy.java | 5 + .../hibernate/HibernateRepositoryFactory.java | 6 + .../ferma/frames/LacpPartnerFrame.java | 185 +++++++++++++ .../FermaLacpPartnerRepository.java | 93 +++++++ .../repositories/FermaRepositoryFactory.java | 6 + .../FermaLacpPartnerRepositoryTest.java | 117 ++++++++ 26 files changed, 1104 insertions(+), 70 deletions(-) create mode 100644 docker/db-migration/migrations/025-add-lacp-partner-class.yaml create mode 100644 src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpInfoData.java create mode 100644 src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpPartner.java create mode 100644 src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpState.java create mode 100644 src-java/kilda-model/src/main/java/org/openkilda/model/LacpPartner.java create mode 100644 src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/LacpPartnerRepository.java create mode 100644 src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/frames/LacpPartnerFrame.java create mode 100644 src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/repositories/FermaLacpPartnerRepository.java create mode 100644 src-java/kilda-persistence-tinkerpop/src/test/java/org/openkilda/persistence/ferma/repositories/FermaLacpPartnerRepositoryTest.java diff --git a/docker/db-migration/migrations/025-add-lacp-partner-class.yaml b/docker/db-migration/migrations/025-add-lacp-partner-class.yaml new file mode 100644 index 00000000000..195cf92716c --- /dev/null +++ b/docker/db-migration/migrations/025-add-lacp-partner-class.yaml @@ -0,0 +1,34 @@ +databaseChangeLog: + - changeSet: + id: tag + author: dkakollu + changes: + - tagDatabase: + tag: 024-add-lacp-partner-class + + - changeSet: + id: add-lacp-partner-class + author: dkakollu + changes: + - sql: "CREATE CLASS lacp_partner IF NOT EXISTS EXTENDS V" + - sql: "CREATE PROPERTY lacp_partner.switch_id IF NOT EXISTS STRING" + - sql: "CREATE PROPERTY lacp_partner.logical_port_number IF NOT EXISTS INTEGER" + - sql: "CREATE PROPERTY lacp_partner.system_priority IF NOT EXISTS INTEGER" + - sql: "CREATE PROPERTY llacp_partner.system_id IF NOT EXISTS STRING" + - sql: "CREATE PROPERTY llacp_partner.key IF NOT EXISTS INTEGER" + - sql: "CREATE PROPERTY lacp_partner.port_priority IF NOT EXISTS INTEGER" + - sql: "CREATE PROPERTY lacp_partner.port_number IF NOT EXISTS INTEGER" + - sql: "CREATE PROPERTY lacp_partner.state_active IF NOT EXISTS BOOLEAN" + - sql: "CREATE PROPERTY llacp_partner.state_short_timeout IF NOT EXISTS BOOLEAN" + - sql: "CREATE PROPERTY lacp_partner.state_aggregatable IF NOT EXISTS BOOLEAN" + - sql: "CREATE PROPERTY lacp_partner.state_synchronised IF NOT EXISTS BOOLEAN" + - sql: "CREATE PROPERTY lacp_partner.state_collecting IF NOT EXISTS BOOLEAN" + - sql: "CREATE PROPERTY lacp_partner.state_distributing IF NOT EXISTS BOOLEAN" + - sql: "CREATE PROPERTY lacp_partner.state_defaulted IF NOT EXISTS BOOLEAN" + - sql: "CREATE PROPERTY lacp_partner.state_expired IF NOT EXISTS BOOLEAN" + - sql: "CREATE INDEX lacp_partner.switch_id IF NOT EXISTS NOTUNIQUE_HASH_INDEX" + - sql: "CREATE INDEX lacp_partner.logical_port_number IF NOT EXISTS NOTUNIQUE_HASH_INDEX" + + rollback: + - sql: "DELETE VERTEX lacp_partner" + - sql: "DROP CLASS llacp_partner IF EXISTS" diff --git a/docker/db-migration/migrations/root.yaml b/docker/db-migration/migrations/root.yaml index 279a88b027b..73169497682 100644 --- a/docker/db-migration/migrations/root.yaml +++ b/docker/db-migration/migrations/root.yaml @@ -81,3 +81,6 @@ databaseChangeLog: - include: relativeToChangelogFile: true file: 023-add-lacp-reply-into-lag-class.yaml + - include: + relativeToChangelogFile: true + file: 025-add-lacp-partner-class.yaml diff --git a/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpInfoData.java b/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpInfoData.java new file mode 100644 index 00000000000..4dfd3aa0750 --- /dev/null +++ b/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpInfoData.java @@ -0,0 +1,39 @@ +/* Copyright 2017 Telstra Open Source + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openkilda.messaging.info.event; + +import org.openkilda.messaging.info.InfoData; +import org.openkilda.model.SwitchId; + +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + + + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) +public class LacpInfoData extends InfoData { + SwitchId switchId; + int logicalPortNumber; + LacpPartner actor; +} diff --git a/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpPartner.java b/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpPartner.java new file mode 100644 index 00000000000..3b68a3e44f8 --- /dev/null +++ b/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpPartner.java @@ -0,0 +1,41 @@ +/* Copyright 2021 Telstra Open Source + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openkilda.messaging.info.event; + +import org.openkilda.model.MacAddress; + +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) +public class LacpPartner implements Serializable { + int systemPriority; + MacAddress systemId; + int key; + int portPriority; + int portNumber; + LacpState state; +} diff --git a/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpState.java b/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpState.java new file mode 100644 index 00000000000..08d0c5bb6a3 --- /dev/null +++ b/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpState.java @@ -0,0 +1,41 @@ +/* Copyright 2021 Telstra Open Source + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openkilda.messaging.info.event; + +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) +public class LacpState implements Serializable { + boolean active; + boolean shortTimeout; + boolean aggregatable; + boolean synchronised; + boolean collecting; + boolean distributing; + boolean defaulted; + boolean expired; +} diff --git a/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/ConnectedDevicesTopology.java b/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/ConnectedDevicesTopology.java index 414d09d8786..edea3d1a209 100644 --- a/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/ConnectedDevicesTopology.java +++ b/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/ConnectedDevicesTopology.java @@ -31,6 +31,7 @@ public class ConnectedDevicesTopology extends AbstractTopology { public static final String CONNECTED_DEVICES_SPOUT_ID = "connected-devices-spout"; + public static final String LACP_SPOUT_ID = "lacp-spout"; public static final String ROUTER_BOLT_ID = "router-bolt"; public static final String PACKET_BOLT_ID = "packet-bolt"; @@ -38,16 +39,30 @@ public ConnectedDevicesTopology(LaunchEnvironment env) { super(env, "connecteddevices-topology", ConnectedDevicesTopologyConfig.class); } + /** + * Main method to run topology. + */ + public static void main(String[] args) { + try { + LaunchEnvironment env = new LaunchEnvironment(args); + (new ConnectedDevicesTopology(env)).setup(); + } catch (Exception e) { + System.exit(handleLaunchException(e)); + } + } + /** * Creating topology. */ public StormTopology createTopology() { TopologyBuilder builder = new TopologyBuilder(); - PersistenceManager persistenceManager = new PersistenceManager(configurationProvider); createZkSpout(builder); createSpout(builder); + createLacpSpout(builder); + + PersistenceManager persistenceManager = new PersistenceManager(configurationProvider); createRouterBolt(builder, persistenceManager); createPacketBolt(builder, persistenceManager); @@ -80,6 +95,10 @@ private void createSpout(TopologyBuilder builder) { declareKafkaSpout(builder, topologyConfig.getKafkaTopoConnectedDevicesTopic(), CONNECTED_DEVICES_SPOUT_ID); } + private void createLacpSpout(TopologyBuilder builder) { + declareKafkaSpout(builder, topologyConfig.getKafkaLacpTopic(), LACP_SPOUT_ID); + } + private void createZkBolt(TopologyBuilder builder) { ZooKeeperBolt zooKeeperBolt = new ZooKeeperBolt(getConfig().getBlueGreenMode(), getZkTopoName(), getZookeeperConfig(), getBoltInstancesCount(ROUTER_BOLT_ID)); @@ -91,16 +110,4 @@ private void createZkBolt(TopologyBuilder builder) { protected String getZkTopoName() { return "connecteddevices"; } - - /** - * Main method to run topology. - */ - public static void main(String[] args) { - try { - LaunchEnvironment env = new LaunchEnvironment(args); - (new ConnectedDevicesTopology(env)).setup(); - } catch (Exception e) { - System.exit(handleLaunchException(e)); - } - } } diff --git a/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/ConnectedDevicesTopologyConfig.java b/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/ConnectedDevicesTopologyConfig.java index 0cc298b2c90..758bd380553 100644 --- a/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/ConnectedDevicesTopologyConfig.java +++ b/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/ConnectedDevicesTopologyConfig.java @@ -25,4 +25,9 @@ public interface ConnectedDevicesTopologyConfig extends AbstractTopologyConfig { default String getKafkaTopoConnectedDevicesTopic() { return getKafkaTopics().getTopoConnectedDevicesTopic(); } + + default String getKafkaLacpTopic() { + return getKafkaTopics().getLacpTopic(); + } + } diff --git a/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/bolts/PacketBolt.java b/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/bolts/PacketBolt.java index 6c804c92d7e..1b0fd95ebe2 100644 --- a/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/bolts/PacketBolt.java +++ b/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/bolts/PacketBolt.java @@ -17,8 +17,9 @@ import static org.openkilda.wfm.topology.utils.KafkaRecordTranslator.FIELD_ID_PAYLOAD; +import org.openkilda.messaging.info.InfoData; import org.openkilda.messaging.info.event.ArpInfoData; -import org.openkilda.messaging.info.event.ConnectedDevicePacketBase; +import org.openkilda.messaging.info.event.LacpInfoData; import org.openkilda.messaging.info.event.LldpInfoData; import org.openkilda.persistence.PersistenceManager; import org.openkilda.wfm.AbstractBolt; @@ -43,12 +44,14 @@ protected void init() { @Override protected void handleInput(Tuple input) throws PipelineException { - ConnectedDevicePacketBase data = pullValue(input, FIELD_ID_PAYLOAD, ConnectedDevicePacketBase.class); + InfoData data = pullValue(input, FIELD_ID_PAYLOAD, InfoData.class); if (data instanceof LldpInfoData) { packetService.handleLldpData((LldpInfoData) data); } else if (data instanceof ArpInfoData) { packetService.handleArpData((ArpInfoData) data); + } else if (data instanceof LacpInfoData) { + packetService.handleLacpData((LacpInfoData) data); } else { unhandledInput(input); } diff --git a/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/bolts/RouterBolt.java b/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/bolts/RouterBolt.java index 03a3b7cfc9b..92695d65df5 100644 --- a/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/bolts/RouterBolt.java +++ b/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/bolts/RouterBolt.java @@ -22,6 +22,7 @@ import org.openkilda.messaging.info.InfoData; import org.openkilda.messaging.info.InfoMessage; import org.openkilda.messaging.info.event.ArpInfoData; +import org.openkilda.messaging.info.event.LacpInfoData; import org.openkilda.messaging.info.event.LldpInfoData; import org.openkilda.persistence.PersistenceManager; import org.openkilda.wfm.AbstractBolt; @@ -57,8 +58,8 @@ protected void handleInput(Tuple input) throws PipelineException { emitWithContext(PACKET_STREAM_ID, input, new Values(createMessageKey((LldpInfoData) data), data)); } else if (data instanceof ArpInfoData) { emitWithContext(PACKET_STREAM_ID, input, new Values(createMessageKey((ArpInfoData) data), data)); - } else { - unhandledInput(input); + } else if (data instanceof LacpInfoData) { + emitWithContext(PACKET_STREAM_ID, input, new Values(createMessageKey((LacpInfoData) data), data)); } } else { unhandledInput(input); diff --git a/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/service/PacketService.java b/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/service/PacketService.java index b0ddf4ca831..f4bf892f2bf 100644 --- a/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/service/PacketService.java +++ b/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/service/PacketService.java @@ -30,16 +30,20 @@ import static org.openkilda.model.cookie.Cookie.LLDP_POST_INGRESS_VXLAN_COOKIE; import static org.openkilda.model.cookie.Cookie.LLDP_TRANSIT_COOKIE; +import org.openkilda.messaging.info.InfoData; import org.openkilda.messaging.info.event.ArpInfoData; import org.openkilda.messaging.info.event.ConnectedDevicePacketBase; +import org.openkilda.messaging.info.event.LacpInfoData; import org.openkilda.messaging.info.event.LldpInfoData; import org.openkilda.model.Flow; +import org.openkilda.model.LacpPartner; import org.openkilda.model.Switch; import org.openkilda.model.SwitchConnectedDevice; import org.openkilda.model.SwitchId; import org.openkilda.model.TransitVlan; import org.openkilda.persistence.PersistenceManager; import org.openkilda.persistence.repositories.FlowRepository; +import org.openkilda.persistence.repositories.LacpPartnerRepository; import org.openkilda.persistence.repositories.SwitchConnectedDeviceRepository; import org.openkilda.persistence.repositories.SwitchRepository; import org.openkilda.persistence.repositories.TransitVlanRepository; @@ -62,6 +66,8 @@ public class PacketService { private final TransitVlanRepository transitVlanRepository; private final FlowRepository flowRepository; + private LacpPartnerRepository lacpPartnerRepository; + public PacketService(PersistenceManager persistenceManager) { transactionManager = persistenceManager.getTransactionManager(); switchRepository = persistenceManager.getRepositoryFactory().createSwitchRepository(); @@ -69,6 +75,34 @@ public PacketService(PersistenceManager persistenceManager) { .createSwitchConnectedDeviceRepository(); transitVlanRepository = persistenceManager.getRepositoryFactory().createTransitVlanRepository(); flowRepository = persistenceManager.getRepositoryFactory().createFlowRepository(); + lacpPartnerRepository = persistenceManager.getRepositoryFactory().createLacpPartnerRepository(); + } + + /** + * This key is needed to balance load on Packet Bolt. If you see that some packet bolts have high load, and + * some have low load, try to extend this key. Maximum extension is equal to + * SwitchConnectedDeviceFrame.UNIQUE_INDEX_PROPERTY + */ + public static String createMessageKey(LldpInfoData data) { + return String.format("%s_%s_lldp", data.getSwitchId(), data.getPortNumber()); + } + + /** + * This key is needed to balance load on Packet Bolt. If you see that some packet bolts have high load, and + * some have low load, try to extend this key. Maximum extension is equal to + * SwitchConnectedDeviceFrame.UNIQUE_INDEX_PROPERTY + */ + public static String createMessageKey(ArpInfoData data) { + return String.format("%s_%s_arp", data.getSwitchId(), data.getPortNumber()); + } + + /** + * This key is needed to balance load on Packet Bolt. If you see that some packet bolts have high load, and + * some have low load, try to extend this key. Maximum extension is equal to + * SwitchConnectedDeviceFrame.UNIQUE_INDEX_PROPERTY + */ + public static String createMessageKey(LacpInfoData data) { + return String.format("%s_%s_arp", data.getSwitchId(), data.getLogicalPortNumber()); } /** @@ -124,21 +158,48 @@ public void handleArpData(ArpInfoData data) { } /** - * This key is needed to balance load on Packet Bolt. If you see that some packet bolts have high load, and - * some have low load, try to extend this key. Maximum extension is equal to - * SwitchConnectedDeviceFrame.UNIQUE_INDEX_PROPERTY - */ - public static String createMessageKey(LldpInfoData data) { - return String.format("%s_%s_lldp", data.getSwitchId(), data.getPortNumber()); - } - - /** - * This key is needed to balance load on Packet Bolt. If you see that some packet bolts have high load, and - * some have low load, try to extend this key. Maximum extension is equal to - * SwitchConnectedDeviceFrame.UNIQUE_INDEX_PROPERTY + * Handle lacp info data. */ - public static String createMessageKey(ArpInfoData data) { - return String.format("%s_%s_arp", data.getSwitchId(), data.getPortNumber()); + public void handleLacpData(LacpInfoData data) { + transactionManager.doInTransaction(() -> { + Optional lacpPartnerOptional = lacpPartnerRepository.findBySwitchIdAndLogicalPortNumber( + data.getSwitchId(), data.getLogicalPortNumber()); + org.openkilda.messaging.info.event.LacpPartner actor = data.getActor(); + if (lacpPartnerOptional.isPresent()) { + lacpPartnerOptional.get().setSystemPriority(actor.getSystemPriority()); + lacpPartnerOptional.get().setSystemId(actor.getSystemId()); + lacpPartnerOptional.get().setKey(actor.getKey()); + lacpPartnerOptional.get().setPortPriority(actor.getPortPriority()); + lacpPartnerOptional.get().setPortNumber(actor.getPortNumber()); + lacpPartnerOptional.get().setStateActive(actor.getState().isActive()); + lacpPartnerOptional.get().setStateShortTimeout(actor.getState().isActive()); + lacpPartnerOptional.get().setStateAggregatable(actor.getState().isActive()); + lacpPartnerOptional.get().setStateSynchronised(actor.getState().isActive()); + lacpPartnerOptional.get().setStateCollecting(actor.getState().isActive()); + lacpPartnerOptional.get().setStateDistributing(actor.getState().isActive()); + lacpPartnerOptional.get().setStateDefaulted(actor.getState().isActive()); + lacpPartnerOptional.get().setStateExpired(actor.getState().isActive()); + } else { + LacpPartner partner = LacpPartner.builder() + .switchId(data.getSwitchId()) + .logicalPortNumber(data.getLogicalPortNumber()) + .systemPriority(actor.getSystemPriority()) + .systemId(actor.getSystemId()) + .key(actor.getKey()) + .portPriority(actor.getPortPriority()) + .portNumber(actor.getPortNumber()) + .stateActive(actor.getState().isActive()) + .stateShortTimeout(actor.getState().isActive()) + .stateAggregatable(actor.getState().isActive()) + .stateSynchronised(actor.getState().isActive()) + .stateCollecting(actor.getState().isActive()) + .stateDistributing(actor.getState().isActive()) + .stateDefaulted(actor.getState().isActive()) + .stateExpired(actor.getState().isActive()) + .build(); + lacpPartnerRepository.add(partner); + } + }); } private FlowRelatedData findFlowRelatedData(ConnectedDevicePacketBase data) { @@ -429,11 +490,13 @@ private SwitchConnectedDevice getOrCreateArpDevice(ArpInfoData data, int vlan) { } - private String getPacketName(ConnectedDevicePacketBase data) { + private String getPacketName(InfoData data) { if (data instanceof LldpInfoData) { return "LLDP"; } else if (data instanceof ArpInfoData) { return "ARP"; + } else if (data instanceof LacpInfoData) { + return "LACP"; } else { return "unknown"; } diff --git a/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/test/java/org/openkilda/wfm/topology/connecteddevices/service/PacketServiceTest.java b/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/test/java/org/openkilda/wfm/topology/connecteddevices/service/PacketServiceTest.java index c6bab499f08..9fc5ba0850d 100644 --- a/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/test/java/org/openkilda/wfm/topology/connecteddevices/service/PacketServiceTest.java +++ b/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/test/java/org/openkilda/wfm/topology/connecteddevices/service/PacketServiceTest.java @@ -23,8 +23,12 @@ import static org.openkilda.model.cookie.Cookie.LLDP_INPUT_PRE_DROP_COOKIE; import org.openkilda.messaging.info.event.ArpInfoData; +import org.openkilda.messaging.info.event.LacpInfoData; +import org.openkilda.messaging.info.event.LacpPartner; +import org.openkilda.messaging.info.event.LacpState; import org.openkilda.messaging.info.event.LldpInfoData; import org.openkilda.model.Flow; +import org.openkilda.model.MacAddress; import org.openkilda.model.PathId; import org.openkilda.model.Switch; import org.openkilda.model.SwitchConnectedDevice; @@ -32,6 +36,7 @@ import org.openkilda.model.TransitVlan; import org.openkilda.persistence.inmemory.InMemoryGraphBasedTest; import org.openkilda.persistence.repositories.FlowRepository; +import org.openkilda.persistence.repositories.LacpPartnerRepository; import org.openkilda.persistence.repositories.SwitchConnectedDeviceRepository; import org.openkilda.persistence.repositories.SwitchRepository; import org.openkilda.persistence.repositories.TransitVlanRepository; @@ -82,10 +87,13 @@ public class PacketServiceTest extends InMemoryGraphBasedTest { public static final int TTL_1 = 120; public static final int TTL_2 = 240; + public static final int LOGICAL_PORT_NUMBER_123 = 123; + public static final int LOGICAL_PORT_NUMBER_456 = 456; private static SwitchConnectedDeviceRepository switchConnectedDeviceRepository; private static SwitchRepository switchRepository; private static FlowRepository flowRepository; private static TransitVlanRepository transitVlanRepository; + private static LacpPartnerRepository lacpPartnerRepository; private static PacketService packetService; @BeforeClass @@ -95,6 +103,7 @@ public static void setUpOnce() { switchRepository = persistenceManager.getRepositoryFactory().createSwitchRepository(); flowRepository = persistenceManager.getRepositoryFactory().createFlowRepository(); transitVlanRepository = persistenceManager.getRepositoryFactory().createTransitVlanRepository(); + lacpPartnerRepository = persistenceManager.getRepositoryFactory().createLacpPartnerRepository(); packetService = new PacketService(persistenceManager); } @@ -121,6 +130,23 @@ public void testHandleArpDataSameTimeOnCreate() { assertEquals(devices.iterator().next().getTimeFirstSeen(), devices.iterator().next().getTimeLastSeen()); } + @Test + public void testLacpPartnerCreate() { + packetService.handleLacpData(createLacpInfoData()); + Collection devices = lacpPartnerRepository.findAll(); + assertEquals(1, devices.size()); + } + + @Test + public void testLacpPartnerUpdateAndCreate() { + packetService.handleLacpData(createLacpInfoData()); + LacpInfoData lacpInfoData = createLacpInfoData(); + lacpInfoData.setLogicalPortNumber(LOGICAL_PORT_NUMBER_456); + packetService.handleLacpData(lacpInfoData); + Collection devices = lacpPartnerRepository.findAll(); + assertEquals(2, devices.size()); + } + @Test public void testHandleLldpDataDifferentTimeOnUpdate() throws InterruptedException { // create @@ -285,7 +311,7 @@ public void testHandleArpDataDifferentIpAddress() { } private Object[][] getOneSwitchOnePortFlowParameters() { - return new Object[][] { + return new Object[][]{ // inVlan, srcVlan, dstVlan, vlansInPacket, sourceSwitch {VLAN_0, VLAN_0, VLAN_2, newArrayList(VLAN_2), true}, {VLAN_1, VLAN_0, VLAN_2, newArrayList(VLAN_2, VLAN_1), true}, @@ -309,7 +335,7 @@ public void findFlowRelatedDataForOneSwitchOnePortFlowTest( } private Object[][] getOneSwitchFlowParameters() { - return new Object[][] { + return new Object[][]{ // inVlan, srcVlan, dstVlan, vlansInPacket, sourceSwitch {VLAN_0, VLAN_0, VLAN_0, newArrayList(), true}, {VLAN_1, VLAN_0, VLAN_0, newArrayList(VLAN_1), true}, @@ -338,7 +364,7 @@ public void findFlowRelatedDataForOneSwitchFlowTest( } private Object[][] getVlanFlowParameters() { - return new Object[][] { + return new Object[][]{ // inVlan, srcVlan, dstVlan, transitVlan, vlansInPacket, sourceSwitch {VLAN_0, VLAN_0, VLAN_3, VLAN_2, newArrayList(VLAN_2), true}, {VLAN_1, VLAN_0, VLAN_3, VLAN_2, newArrayList(VLAN_2, VLAN_1), true}, @@ -363,7 +389,7 @@ public void findFlowRelatedDataForVlanFlowTest( } private Object[][] getInOutVlanCombinationForVxlanParameters() { - return new Object[][] { + return new Object[][]{ // inVlan, srcVlan, dstVlan, vlansInPacket, sourceSwitch {VLAN_0, VLAN_0, VLAN_0, newArrayList(), true}, {VLAN_0, VLAN_0, VLAN_2, newArrayList(), true}, @@ -510,4 +536,16 @@ private ArpInfoData createArpInfoData() { return new ArpInfoData(SWITCH_ID_1, PORT_NUMBER_1, newArrayList(VLAN_1), ARP_INPUT_PRE_DROP_COOKIE, MAC_ADDRESS_1, IP_ADDRESS_1); } + + private LacpInfoData createLacpInfoData() { + LacpState state = LacpState.builder() + .active(Boolean.TRUE).shortTimeout(Boolean.TRUE).aggregatable(Boolean.TRUE) + .synchronised(Boolean.TRUE).collecting(Boolean.TRUE).distributing(Boolean.TRUE) + .defaulted(Boolean.TRUE).expired(Boolean.FALSE).build(); + LacpPartner partner = LacpPartner.builder().systemPriority(1).systemId(new MacAddress("00:00:00:00:00:01")) + .key(1).portPriority(1).portNumber(11).state(state).build(); + LacpInfoData lacpInfoData = LacpInfoData.builder().switchId(SWITCH_ID_1) + .logicalPortNumber(LOGICAL_PORT_NUMBER_123).actor(partner).build(); + return lacpInfoData; + } } diff --git a/src-java/floodlight-service/floodlight-modules/src/main/java/org/openkilda/floodlight/KafkaChannel.java b/src-java/floodlight-service/floodlight-modules/src/main/java/org/openkilda/floodlight/KafkaChannel.java index af3b3985aa1..83844e38ccf 100644 --- a/src-java/floodlight-service/floodlight-modules/src/main/java/org/openkilda/floodlight/KafkaChannel.java +++ b/src-java/floodlight-service/floodlight-modules/src/main/java/org/openkilda/floodlight/KafkaChannel.java @@ -144,6 +144,10 @@ public String getNetworkControlResponseTopic() { return formatTopicWithRegion(topics.getNetworkControlResponseRegionTopic()); } + public String getLacpTopic() { + return formatTopicWithRegion(topics.getLacpTopic()); + } + private String formatTopicWithRegion(String topic) { String region = config.getFloodlightRegion(); if (region == null || region.isEmpty()) { diff --git a/src-java/floodlight-service/floodlight-modules/src/main/java/org/openkilda/floodlight/service/lacp/LacpService.java b/src-java/floodlight-service/floodlight-modules/src/main/java/org/openkilda/floodlight/service/lacp/LacpService.java index 8f51ef64306..d1263541604 100644 --- a/src-java/floodlight-service/floodlight-modules/src/main/java/org/openkilda/floodlight/service/lacp/LacpService.java +++ b/src-java/floodlight-service/floodlight-modules/src/main/java/org/openkilda/floodlight/service/lacp/LacpService.java @@ -22,12 +22,18 @@ import org.openkilda.floodlight.command.CommandContext; import org.openkilda.floodlight.model.OfInput; import org.openkilda.floodlight.service.IService; +import org.openkilda.floodlight.service.kafka.IKafkaProducerService; import org.openkilda.floodlight.service.kafka.KafkaUtilityService; import org.openkilda.floodlight.service.of.IInputTranslator; import org.openkilda.floodlight.service.of.InputService; import org.openkilda.floodlight.shared.packet.Lacp; import org.openkilda.floodlight.shared.packet.Lacp.ActorPartnerInfo; import org.openkilda.floodlight.shared.packet.SlowProtocols; +import org.openkilda.floodlight.utils.CorrelationContext; +import org.openkilda.messaging.info.InfoMessage; +import org.openkilda.messaging.info.event.LacpInfoData; +import org.openkilda.messaging.info.event.LacpPartner; +import org.openkilda.messaging.info.event.LacpState; import org.openkilda.model.SwitchId; import org.openkilda.model.cookie.Cookie; import org.openkilda.model.cookie.CookieBase.CookieType; @@ -57,11 +63,6 @@ public class LacpService implements IService, IInputTranslator { private static final Logger logger = LoggerFactory.getLogger(LacpService.class); - private IOFSwitchService switchService; - private MacAddress systemId; - private int systemPriority; - private int portPriority; - static { try { logger.info("Force loading of {}", Class.forName(SlowProtocols.class.getName())); @@ -70,6 +71,28 @@ public class LacpService implements IService, IInputTranslator { } } + private IOFSwitchService switchService; + private MacAddress systemId; + private int systemPriority; + private int portPriority; + private IKafkaProducerService producerService; + private String topic; + private String region; + + private static OFPort getInPort(OFPacketIn packetIn) { + if (packetIn.getVersion().compareTo(OFVersion.OF_12) < 0) { + return packetIn.getInPort(); + } + + if (packetIn.getMatch().supports(MatchField.IN_PHY_PORT)) { + OFPort inPort = packetIn.getMatch().get(MatchField.IN_PHY_PORT); + if (inPort != null) { + return inPort; + } + } + return packetIn.getMatch().get(MatchField.IN_PORT); + } + @Override public Command makeCommand(CommandContext context, OfInput input) { return new Command(context) { @@ -92,8 +115,8 @@ Lacp deserializeLacp(Ethernet eth, SwitchId switchId, long cookie) { return (Lacp) slowProtocol.getPayload(); } else { if (logger.isTraceEnabled()) { - logger.trace("Got unknown slow protocol packet {} on switch {}", - slowProtocol.getSubtype(), switchId); + logger.trace("Got unknown slow protocol packet {} on switch {}", slowProtocol.getSubtype(), + switchId); } return null; } @@ -119,8 +142,8 @@ private void handlePacketIn(OfInput input) { if (cookie.getType() == CookieType.LACP_REPLY_INPUT) { if (logger.isDebugEnabled()) { - logger.debug("Receive LACP packet from {} OF-xid:{}, cookie: {}", - input.getDpId(), input.getMessage().getXid(), cookie); + logger.debug("Receive LACP packet from {} OF-xid:{}, cookie: {}", input.getDpId(), + input.getMessage().getXid(), cookie); } handleLacp(input, switchId, cookie.getValue(), getInPort((OFPacketIn) input.getMessage())); } @@ -137,6 +160,33 @@ private void handleLacp(OfInput input, SwitchId switchId, long cookie, OFPort in } Lacp lacpReply = modifyLacpRequest(lacpRequest); sendLacpReply(DatapathId.of(switchId.getId()), inPort, lacpReply); + + LacpInfoData lacpInfoData = getLacpInfoData(lacpRequest, switchId, inPort.getPortNumber()); + + InfoMessage message = new InfoMessage(lacpInfoData, System.currentTimeMillis(), CorrelationContext.getId(), + region); + + producerService.sendMessageAndTrackWithZk(topic, switchId.toString(), message); + } + + private LacpInfoData getLacpInfoData(final Lacp lacpRequest, final SwitchId switchId, final int logicalPortNumber) { + + ActorPartnerInfo actor = lacpRequest.getActor(); + Lacp.State state = actor.getState(); + + LacpState actorState = LacpState.builder() + .active(state.isActive()).shortTimeout(state.isShortTimeout()).aggregatable(state.isAggregatable()) + .synchronised(state.isSynchronised()).collecting(state.isCollecting()) + .distributing(state.isDistributing()).defaulted(state.isDefaulted()).expired(state.isExpired()).build(); + + org.openkilda.model.MacAddress macAddressActor = + new org.openkilda.model.MacAddress(actor.getSystemId().toString()); + + LacpPartner lacpActor = LacpPartner.builder().systemPriority(actor.getSystemPriority()) + .systemId(macAddressActor).key(actor.getKey()).portPriority(actor.getPortPriority()) + .portNumber(actor.getPortNumber()).state(actorState).build(); + + return LacpInfoData.builder().switchId(switchId).logicalPortNumber(logicalPortNumber).actor(lacpActor).build(); } @VisibleForTesting @@ -160,18 +210,15 @@ OFPacketOut generateLacpPacket(IOFSwitch sw, Lacp lacp, OFPort outPort) { slowProtocols.setSubtype(SlowProtocols.LACP_SUBTYPE); slowProtocols.setPayload(lacp); - Ethernet l2 = new Ethernet().setSourceMACAddress(new SwitchId(sw.getId().getLong()).toMacAddress()) - .setDestinationMACAddress(org.openkilda.model.MacAddress.SLOW_PROTOCOLS.getAddress()) - .setEtherType(EthType.SLOW_PROTOCOLS); + Ethernet l2 = new Ethernet().setSourceMACAddress( + new SwitchId(sw.getId().getLong()).toMacAddress()).setDestinationMACAddress( + org.openkilda.model.MacAddress.SLOW_PROTOCOLS.getAddress()).setEtherType(EthType.SLOW_PROTOCOLS); l2.setPayload(slowProtocols); byte[] data = l2.serialize(); - OFPacketOut.Builder pob = sw.getOFFactory().buildPacketOut() - .setBufferId(OFBufferId.NO_BUFFER) - .setActions( - Lists.newArrayList( - sw.getOFFactory().actions().buildOutput().setPort(outPort).build())) - .setData(data); + OFPacketOut.Builder pob = sw.getOFFactory().buildPacketOut().setBufferId(OFBufferId.NO_BUFFER).setActions( + Lists.newArrayList(sw.getOFFactory().actions().buildOutput().setPort(outPort).build())).setData( + data); OFMessageUtils.setInPort(pob, OFPort.CONTROLLER); return pob.build(); @@ -198,8 +245,8 @@ private void sendLacpReply(DatapathId dpId, OFPort port, Lacp lacpReply) { } if (!result) { - logger.error("Failed to send PACKET_OUT(LACP reply packet) via {}-{}. Packet {}", - sw.getId(), port.getPortNumber(), lacpReply); + logger.error("Failed to send PACKET_OUT(LACP reply packet) via {}-{}. Packet {}", sw.getId(), + port.getPortNumber(), lacpReply); } } else { logger.error("Couldn't find switch {} to send LACP reply", switchId); @@ -209,20 +256,6 @@ private void sendLacpReply(DatapathId dpId, OFPort port, Lacp lacpReply) { } } - private static OFPort getInPort(OFPacketIn packetIn) { - if (packetIn.getVersion().compareTo(OFVersion.OF_12) < 0) { - return packetIn.getInPort(); - } - - if (packetIn.getMatch().supports(MatchField.IN_PHY_PORT)) { - OFPort inPort = packetIn.getMatch().get(MatchField.IN_PHY_PORT); - if (inPort != null) { - return inPort; - } - } - return packetIn.getMatch().get(MatchField.IN_PORT); - } - @Override public void setup(FloodlightModuleContext context) { logger.info("Stating {}", LacpService.class.getCanonicalName()); @@ -238,5 +271,10 @@ public void setup(FloodlightModuleContext context) { InputService inputService = context.getServiceImpl(InputService.class); inputService.addTranslator(OFType.PACKET_IN, this); + + + region = kafkaChannel.getRegion(); + producerService = context.getServiceImpl(IKafkaProducerService.class); + topic = kafkaChannel.getLacpTopic(); } } diff --git a/src-java/floodlightrouter-topology/floodlightrouter-storm-topology/src/main/java/org/openkilda/wfm/topology/floodlightrouter/ComponentType.java b/src-java/floodlightrouter-topology/floodlightrouter-storm-topology/src/main/java/org/openkilda/wfm/topology/floodlightrouter/ComponentType.java index 87fd4a05c9c..c5c8a91eaa4 100644 --- a/src-java/floodlightrouter-topology/floodlightrouter-storm-topology/src/main/java/org/openkilda/wfm/topology/floodlightrouter/ComponentType.java +++ b/src-java/floodlightrouter-topology/floodlightrouter-storm-topology/src/main/java/org/openkilda/wfm/topology/floodlightrouter/ComponentType.java @@ -25,6 +25,7 @@ public final class ComponentType { public static final String KILDA_STATS_REPLY_BOLT = "KILDA_STATS_REPLY_BOLT"; public static final String KILDA_ISL_LATENCY_REPLY_BOLT = "KILDA_ISL_LATENCY_REPLY_BOLT"; public static final String KILDA_CONNECTED_DEVICES_REPLY_BOLT = "KILDA_CONNECTED_DEVICES_REPLY_BOLT"; + public static final String KILDA_LACP_REPLY_BOLT = "KILDA_LACP_REPLY_BOLT"; public static final String KILDA_NB_WORKER_REPLY_BOLT = "KILDA_NB_WORKER_REPLY_BOLT"; public static final String KILDA_TOPO_DISCO_REPLY_BOLT = "KILDA_TOPO_DISCO_REPLY_BOLT"; public static final String KILDA_TOPO_DISCO_BOLT = "KILDA_TOPO_DISCO_BOLT"; @@ -47,6 +48,7 @@ public final class ComponentType { public static final String KILDA_STATS_KAFKA_SPOUT = "KILDA_STATS_KAFKA_SPOUT"; public static final String KILDA_ISL_LATENCY_KAFKA_SPOUT = "KILDA_ISL_LATENCY_KAFKA_SPOUT"; public static final String KILDA_CONNECTED_DEVICES_KAFKA_SPOUT = "KILDA_CONNECTED_DEVICES_KAFKA_SPOUT"; + public static final String KILDA_LACP_KAFKA_SPOUT = "KILDA_LACP_KAFKA_SPOUT"; public static final String KILDA_SWITCH_MANAGER_KAFKA_SPOUT = "KILDA_SWITCH_MANAGER_KAFKA_SPOUT"; public static final String SPEAKER_DISCO_KAFKA_SPOUT = "SPEAKER_DISCO_KAFKA_SPOUT"; public static final String KILDA_TOPO_DISCO_KAFKA_SPOUT = "KILDA_TOPO_DISCO_KAFKA_SPOUT"; diff --git a/src-java/floodlightrouter-topology/floodlightrouter-storm-topology/src/main/java/org/openkilda/wfm/topology/floodlightrouter/FloodlightRouterTopology.java b/src-java/floodlightrouter-topology/floodlightrouter-storm-topology/src/main/java/org/openkilda/wfm/topology/floodlightrouter/FloodlightRouterTopology.java index 9aec333ec20..16cd23f2531 100644 --- a/src-java/floodlightrouter-topology/floodlightrouter-storm-topology/src/main/java/org/openkilda/wfm/topology/floodlightrouter/FloodlightRouterTopology.java +++ b/src-java/floodlightrouter-topology/floodlightrouter-storm-topology/src/main/java/org/openkilda/wfm/topology/floodlightrouter/FloodlightRouterTopology.java @@ -229,6 +229,12 @@ private void speakerToConnectedDevices(TopologyBuilder topology, TopologyOutput topology, kafkaTopics.getTopoConnectedDevicesRegionTopic(), kafkaTopics.getTopoConnectedDevicesTopic(), ComponentType.KILDA_CONNECTED_DEVICES_KAFKA_SPOUT, ComponentType.KILDA_CONNECTED_DEVICES_REPLY_BOLT, output.getKafkaGenericOutput()); + + declareSpeakerToControllerProxy( + topology, kafkaTopics.getLacpRegionTopic(), kafkaTopics.getLacpTopic(), + ComponentType.KILDA_LACP_KAFKA_SPOUT, ComponentType.KILDA_LACP_REPLY_BOLT, + output.getKafkaGenericOutput()); + } private void speakerToSwitchManager(TopologyBuilder topology, TopologyOutput output) { diff --git a/src-java/kilda-configuration/src/main/java/org/openkilda/config/KafkaTopicsConfig.java b/src-java/kilda-configuration/src/main/java/org/openkilda/config/KafkaTopicsConfig.java index 0a64d20b952..d92b8d01bd2 100644 --- a/src-java/kilda-configuration/src/main/java/org/openkilda/config/KafkaTopicsConfig.java +++ b/src-java/kilda-configuration/src/main/java/org/openkilda/config/KafkaTopicsConfig.java @@ -263,4 +263,12 @@ public interface KafkaTopicsConfig { @Key("stats.notify.priv") @Default("kilda.stats.notify.priv") String getFlowStatsNotifyTopic(); + + @Key("topo.lacp.storm") + @Default("kilda.lacp.storm.priv") + String getLacpTopic(); + + @Key("topo.floodlight.lacp.region") + @Default("kilda.floodlight.lacp.priv") + String getLacpRegionTopic(); } diff --git a/src-java/kilda-model/src/main/java/org/openkilda/model/LacpPartner.java b/src-java/kilda-model/src/main/java/org/openkilda/model/LacpPartner.java new file mode 100644 index 00000000000..2cdf878395d --- /dev/null +++ b/src-java/kilda-model/src/main/java/org/openkilda/model/LacpPartner.java @@ -0,0 +1,256 @@ +/* Copyright 2021 Telstra Open Source + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openkilda.model; + +import com.esotericsoftware.kryo.DefaultSerializer; +import com.esotericsoftware.kryo.serializers.BeanSerializer; +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Delegate; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +import java.io.Serializable; +import java.util.Objects; + +/** + * Represents a physical port. + */ +@DefaultSerializer(BeanSerializer.class) +@ToString +public class LacpPartner implements CompositeDataEntity { + @Getter + @Setter + @Delegate + @JsonIgnore + private LacpPartnerData data; + + /** + * No args constructor for deserialization purpose. + */ + private LacpPartner() { + data = new LacpPartnerDataImpl(); + } + + @Builder + public LacpPartner(@NonNull SwitchId switchId, @NonNull int logicalPortNumber, int systemPriority, + MacAddress systemId, int key, int portPriority, int portNumber, boolean stateActive, + boolean stateShortTimeout, boolean stateAggregatable, boolean stateSynchronised, + boolean stateCollecting, boolean stateDistributing, boolean stateDefaulted, + boolean stateExpired) { + data = LacpPartnerDataImpl.builder() + .switchId(switchId) + .logicalPortNumber(logicalPortNumber) + .systemPriority(systemPriority) + .systemId(systemId) + .key(key) + .portPriority(portPriority) + .portNumber(portNumber) + .stateActive(stateActive) + .stateShortTimeout(stateShortTimeout) + .stateAggregatable(stateAggregatable) + .stateSynchronised(stateSynchronised) + .stateCollecting(stateCollecting) + .stateDistributing(stateDistributing) + .stateDefaulted(stateDefaulted) + .stateExpired(stateExpired) + .build(); + } + + public LacpPartner(@NonNull LacpPartner.LacpPartnerData data) { + this.data = data; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + LacpPartner that = (LacpPartner) o; + return new EqualsBuilder() + .append(getSwitchId(), that.getSwitchId()) + .append(getLogicalPortNumber(), that.getLogicalPortNumber()) + .append(getSystemPriority(), that.getSystemPriority()) + .append(getSystemId(), that.getSystemId()) + .append(getKey(), that.getKey()) + .append(getPortPriority(), that.getPortPriority()) + .append(getPortNumber(), that.getPortNumber()) + .append(isStateActive(), that.isStateActive()) + .append(isStateShortTimeout(), that.isStateShortTimeout()) + .append(isStateAggregatable(), that.isStateAggregatable()) + .append(isStateSynchronised(), that.isStateSynchronised()) + .append(isStateCollecting(), that.isStateCollecting()) + .append(isStateDistributing(), that.isStateDistributing()) + .append(isStateDefaulted(), that.isStateDefaulted()) + .append(isStateExpired(), that.isStateExpired()) + .isEquals(); + } + + @Override + public int hashCode() { + return Objects.hash(getSwitchId(), getLogicalPortNumber(), getSystemPriority(), getSystemId(), + getKey(), getPortPriority(), getPortNumber(), isStateActive(), isStateShortTimeout(), + isStateAggregatable(), isStateSynchronised(), isStateCollecting(), isStateDistributing(), + isStateDefaulted(), isStateExpired()); + } + + /** + * Defines persistable data of the PhysicalPort. + */ + public interface LacpPartnerData { + SwitchId getSwitchId(); + + void setSwitchId(SwitchId switchId); + + public int getLogicalPortNumber(); + + public void setLogicalPortNumber(int logicalPortNumber); + + int getSystemPriority(); + + void setSystemPriority(int systemPriority); + + MacAddress getSystemId(); + + void setSystemId(MacAddress systemId); + + int getKey(); + + void setKey(int key); + + int getPortPriority(); + + void setPortPriority(int portPriority); + + int getPortNumber(); + + void setPortNumber(int portNumber); + + boolean isStateActive(); + + void setStateActive(boolean stateActive); + + boolean isStateShortTimeout(); + + void setStateShortTimeout(boolean stateShortTimeout); + + boolean isStateAggregatable(); + + void setStateAggregatable(boolean stateAggregatable); + + boolean isStateSynchronised(); + + void setStateSynchronised(boolean stateSynchronised); + + boolean isStateCollecting(); + + void setStateCollecting(boolean stateCollecting); + + boolean isStateDistributing(); + + void setStateDistributing(boolean stateDistributing); + + boolean isStateDefaulted(); + + void setStateDefaulted(boolean stateDefaulted); + + boolean isStateExpired(); + + void setStateExpired(boolean stateExpired); + } + + /** + * A cloner for LacpPartner entity. + */ + @Mapper + public interface LacpPartnerCloner { + LacpPartner.LacpPartnerCloner INSTANCE = Mappers.getMapper(LacpPartner.LacpPartnerCloner.class); + + /** + * Performs copy of entity data. + */ + default void copy(LacpPartnerData source, @MappingTarget LacpPartnerData target) { + if (source == null) { + return; + } + target.setSwitchId(source.getSwitchId()); + target.setLogicalPortNumber(source.getLogicalPortNumber()); + target.setSystemPriority(source.getSystemPriority()); + target.setSystemId(source.getSystemId()); + target.setKey(source.getKey()); + target.setPortPriority(source.getPortPriority()); + target.setPortNumber(source.getPortNumber()); + target.setStateActive(source.isStateActive()); + target.setStateShortTimeout(source.isStateShortTimeout()); + target.setStateAggregatable(source.isStateAggregatable()); + target.setStateSynchronised(source.isStateSynchronised()); + target.setStateCollecting(source.isStateCollecting()); + target.setStateDistributing(source.isStateDistributing()); + target.setStateDefaulted(source.isStateDefaulted()); + target.setStateExpired(source.isStateExpired()); + } + + /** + * Performs deep copy of entity data. + */ + default LacpPartnerData deepCopy(LacpPartnerData source) { + LacpPartnerData result = new LacpPartnerDataImpl(); + copy(source, result); + return result; + } + } + + /** + * POJO implementation of PhysicalPortData. + */ + + @Data + @Builder + @NoArgsConstructor + @AllArgsConstructor + static final class LacpPartnerDataImpl implements LacpPartnerData, Serializable { + private static final long serialVersionUID = 1L; + @NonNull SwitchId switchId; + + @NonNull int logicalPortNumber; + + int systemPriority; + MacAddress systemId; + int key; + int portPriority; + int portNumber; + boolean stateActive; + boolean stateShortTimeout; + boolean stateAggregatable; + boolean stateSynchronised; + boolean stateCollecting; + boolean stateDistributing; + boolean stateDefaulted; + boolean stateExpired; + } +} diff --git a/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/LacpPartnerRepository.java b/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/LacpPartnerRepository.java new file mode 100644 index 00000000000..5d02bbb24d5 --- /dev/null +++ b/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/LacpPartnerRepository.java @@ -0,0 +1,30 @@ +/* Copyright 2021 Telstra Open Source + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openkilda.persistence.repositories; + +import org.openkilda.model.LacpPartner; +import org.openkilda.model.SwitchId; + +import java.util.Collection; +import java.util.Optional; + +public interface LacpPartnerRepository extends Repository { + Collection findAll(); + + Collection findBySwitchId(SwitchId switchId); + + Optional findBySwitchIdAndLogicalPortNumber(SwitchId switchId, int portNumber); +} diff --git a/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/RepositoryAreaBinding.java b/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/RepositoryAreaBinding.java index 8219b5178b7..7f863df7548 100644 --- a/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/RepositoryAreaBinding.java +++ b/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/RepositoryAreaBinding.java @@ -60,6 +60,7 @@ private RepositoryAreaBinding() { binding.put(FlowStatsRepository.class, PersistenceArea.COMMON); binding.put(YFlowRepository.class, PersistenceArea.COMMON); binding.put(PortRepository.class, PersistenceArea.COMMON); + binding.put(LacpPartnerRepository.class, PersistenceArea.COMMON); // history binding.put(FlowEventActionRepository.class, PersistenceArea.HISTORY); diff --git a/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/RepositoryFactory.java b/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/RepositoryFactory.java index 398db441a56..78208454b47 100644 --- a/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/RepositoryFactory.java +++ b/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/RepositoryFactory.java @@ -87,4 +87,6 @@ public interface RepositoryFactory { YFlowRepository createYFlowRepository(); PortRepository createPortRepository(); + + LacpPartnerRepository createLacpPartnerRepository(); } diff --git a/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/RepositoryFactoryProxy.java b/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/RepositoryFactoryProxy.java index 8dc6845426f..a5459f1e931 100644 --- a/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/RepositoryFactoryProxy.java +++ b/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/RepositoryFactoryProxy.java @@ -190,6 +190,11 @@ public PortRepository createPortRepository() { return resolve(PortRepository.class).createPortRepository(); } + @Override + public LacpPartnerRepository createLacpPartnerRepository() { + return resolve(LacpPartnerRepository.class).createLacpPartnerRepository(); + } + private RepositoryFactory resolve(Class repositoryClass) { PersistenceArea area = RepositoryAreaBinding.INSTANCE.lookup(repositoryClass); PersistenceImplementation implementation = manager.getImplementation(area); diff --git a/src-java/kilda-persistence-hibernate/src/main/java/org/openkilda/persistence/hibernate/HibernateRepositoryFactory.java b/src-java/kilda-persistence-hibernate/src/main/java/org/openkilda/persistence/hibernate/HibernateRepositoryFactory.java index 93d7e1cf9a1..e607201f65d 100644 --- a/src-java/kilda-persistence-hibernate/src/main/java/org/openkilda/persistence/hibernate/HibernateRepositoryFactory.java +++ b/src-java/kilda-persistence-hibernate/src/main/java/org/openkilda/persistence/hibernate/HibernateRepositoryFactory.java @@ -32,6 +32,7 @@ import org.openkilda.persistence.repositories.IslRepository; import org.openkilda.persistence.repositories.KildaConfigurationRepository; import org.openkilda.persistence.repositories.KildaFeatureTogglesRepository; +import org.openkilda.persistence.repositories.LacpPartnerRepository; import org.openkilda.persistence.repositories.LagLogicalPortRepository; import org.openkilda.persistence.repositories.LinkPropsRepository; import org.openkilda.persistence.repositories.MirrorGroupRepository; @@ -210,6 +211,11 @@ public PortRepository createPortRepository() { throw new IllegalStateException("Repository not implemented on hibernate layer"); } + @Override + public LacpPartnerRepository createLacpPartnerRepository() { + throw new IllegalStateException("Repository not implemented on hibernate layer"); + } + @Override public LagLogicalPortRepository createLagLogicalPortRepository() { throw new IllegalStateException("Repository not implemented on hibernate layer"); diff --git a/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/frames/LacpPartnerFrame.java b/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/frames/LacpPartnerFrame.java new file mode 100644 index 00000000000..b93de998ebd --- /dev/null +++ b/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/frames/LacpPartnerFrame.java @@ -0,0 +1,185 @@ +/* Copyright 2021 Telstra Open Source + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openkilda.persistence.ferma.frames; + + +import org.openkilda.model.LacpPartner.LacpPartnerData; +import org.openkilda.model.MacAddress; +import org.openkilda.model.SwitchId; +import org.openkilda.persistence.ferma.frames.converters.Convert; +import org.openkilda.persistence.ferma.frames.converters.MacAddressConverter; +import org.openkilda.persistence.ferma.frames.converters.SwitchIdConverter; + +import com.syncleus.ferma.FramedGraph; +import com.syncleus.ferma.annotations.Property; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; +import java.util.Optional; + +@Slf4j +public abstract class LacpPartnerFrame extends KildaBaseVertexFrame implements LacpPartnerData { + public static final String FRAME_LABEL = "lacp_partner"; + public static final String SWITCH_ID_PROPERTY = "switch_id"; + public static final String LOGICAL_PORT_NUMBER_PROPERTY = "logical_port_number"; + public static final String SYSTEM_PRIORITY_PROPERTY = "system_priority"; + public static final String SYSTEM_ID_PROPERTY = "system_id"; + public static final String KEY_PROPERTY = "key"; + public static final String PORT_PRIORITY_PROPERTY = "port_priority"; + public static final String PORT_NUMBER_PROPERTY = "port_number"; + public static final String STATE_ACTIVE_PROPERTY = "state_active"; + public static final String STATE_SHORT_TIMEOUT_PROPERTY = "state_short_timeout"; + public static final String STATE_AGGREGATABLE_PROPERTY = "state_aggregatable"; + public static final String STATE_SYNCHRONISED_PROPERTY = "state_synchronised"; + public static final String STATE_COLLECTING_PROPERTY = "state_collecting"; + public static final String STATE_DISTRIBUTING_PROPERTY = "state_distributing"; + public static final String STATE_DEFAULTED_PROPERTY = "state_defaulted"; + public static final String STATE_EXPIRED_PROPERTY = "state_expired"; + + public static Optional load(FramedGraph graph, String switchId, int logicalPortNumber) { + List lacpPartnerFrames = graph.traverse(input -> input.V() + .hasLabel(FRAME_LABEL) + .has(SWITCH_ID_PROPERTY, switchId) + .has(LOGICAL_PORT_NUMBER_PROPERTY, logicalPortNumber)) + .toListExplicit(LacpPartnerFrame.class); + return lacpPartnerFrames.isEmpty() ? Optional.empty() : Optional.of(lacpPartnerFrames.get(0)); + } + + @Override + @Property(SWITCH_ID_PROPERTY) + @Convert(SwitchIdConverter.class) + public abstract SwitchId getSwitchId(); + + @Override + @Property(SWITCH_ID_PROPERTY) + @Convert(SwitchIdConverter.class) + public abstract void setSwitchId(@NonNull SwitchId switchId); + + @Override + @Property(LOGICAL_PORT_NUMBER_PROPERTY) + public abstract int getLogicalPortNumber(); + + @Override + @Property(LOGICAL_PORT_NUMBER_PROPERTY) + public abstract void setLogicalPortNumber(int logicalPortNumber); + + @Override + @Property(SYSTEM_PRIORITY_PROPERTY) + public abstract int getSystemPriority(); + + @Override + @Property(SYSTEM_PRIORITY_PROPERTY) + public abstract void setSystemPriority(int systemPriority); + + @Override + @Property(SYSTEM_ID_PROPERTY) + @Convert(MacAddressConverter.class) + public abstract MacAddress getSystemId(); + + @Override + @Property(SYSTEM_ID_PROPERTY) + @Convert(MacAddressConverter.class) + public abstract void setSystemId(MacAddress systemId); + + @Override + @Property(KEY_PROPERTY) + public abstract int getKey(); + + @Override + @Property(KEY_PROPERTY) + public abstract void setKey(int key); + + @Override + @Property(PORT_PRIORITY_PROPERTY) + public abstract int getPortPriority(); + + @Override + @Property(PORT_PRIORITY_PROPERTY) + public abstract void setPortPriority(int portPriority); + + @Override + @Property(PORT_NUMBER_PROPERTY) + public abstract int getPortNumber(); + + @Override + @Property(PORT_NUMBER_PROPERTY) + public abstract void setPortNumber(int portNumber); + + @Override + @Property(STATE_ACTIVE_PROPERTY) + public abstract boolean isStateActive(); + + @Override + @Property(STATE_ACTIVE_PROPERTY) + public abstract void setStateActive(boolean stateActive); + + @Override + @Property(STATE_SHORT_TIMEOUT_PROPERTY) + public abstract boolean isStateShortTimeout(); + + @Override + @Property(STATE_SHORT_TIMEOUT_PROPERTY) + public abstract void setStateShortTimeout(boolean stateShortTimeout); + + @Override + @Property(STATE_AGGREGATABLE_PROPERTY) + public abstract boolean isStateAggregatable(); + + @Override + @Property(STATE_AGGREGATABLE_PROPERTY) + public abstract void setStateAggregatable(boolean stateAggregatable); + + @Override + @Property(STATE_SYNCHRONISED_PROPERTY) + public abstract boolean isStateSynchronised(); + + @Override + @Property(STATE_SYNCHRONISED_PROPERTY) + public abstract void setStateSynchronised(boolean stateSynchronised); + + @Override + @Property(STATE_COLLECTING_PROPERTY) + public abstract boolean isStateCollecting(); + + @Override + @Property(STATE_COLLECTING_PROPERTY) + public abstract void setStateCollecting(boolean stateCollecting); + + @Override + @Property(STATE_DISTRIBUTING_PROPERTY) + public abstract boolean isStateDistributing(); + + @Override + @Property(STATE_DISTRIBUTING_PROPERTY) + public abstract void setStateDistributing(boolean stateDistributing); + + @Override + @Property(STATE_DEFAULTED_PROPERTY) + public abstract boolean isStateDefaulted(); + + @Override + @Property(STATE_DEFAULTED_PROPERTY) + public abstract void setStateDefaulted(boolean stateDefaulted); + + @Override + @Property(STATE_EXPIRED_PROPERTY) + public abstract boolean isStateExpired(); + + @Override + @Property(STATE_EXPIRED_PROPERTY) + public abstract void setStateExpired(boolean stateExpired); +} diff --git a/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/repositories/FermaLacpPartnerRepository.java b/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/repositories/FermaLacpPartnerRepository.java new file mode 100644 index 00000000000..0e82f8b5df5 --- /dev/null +++ b/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/repositories/FermaLacpPartnerRepository.java @@ -0,0 +1,93 @@ +/* Copyright 2022 Telstra Open Source + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openkilda.persistence.ferma.repositories; + +import org.openkilda.model.LacpPartner; +import org.openkilda.model.LacpPartner.LacpPartnerData; +import org.openkilda.model.SwitchId; +import org.openkilda.persistence.ferma.FermaPersistentImplementation; +import org.openkilda.persistence.ferma.frames.KildaBaseVertexFrame; +import org.openkilda.persistence.ferma.frames.LacpPartnerFrame; +import org.openkilda.persistence.ferma.frames.converters.SwitchIdConverter; +import org.openkilda.persistence.repositories.LacpPartnerRepository; +import org.openkilda.persistence.repositories.PortRepository; + +import lombok.extern.slf4j.Slf4j; + +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * Ferma implementation of {@link PortRepository}. + */ +@Slf4j +public class FermaLacpPartnerRepository extends FermaGenericRepository + implements LacpPartnerRepository { + public FermaLacpPartnerRepository(FermaPersistentImplementation implementation) { + super(implementation); + } + + @Override + protected LacpPartnerFrame doAdd(LacpPartnerData data) { + LacpPartnerFrame frame = KildaBaseVertexFrame.addNewFramedVertex(framedGraph(), + LacpPartnerFrame.FRAME_LABEL, LacpPartnerFrame.class); + + LacpPartner.LacpPartnerCloner.INSTANCE.copy(data, frame); + return frame; + } + + @Override + protected void doRemove(LacpPartnerFrame frame) { + frame.remove(); + } + + @Override + protected LacpPartnerData doDetach(LacpPartner entity, LacpPartnerFrame frame) { + return LacpPartner.LacpPartnerCloner.INSTANCE.deepCopy(frame); + } + + @Override + public Collection findAll() { + return framedGraph().traverse(g -> g.V() + .hasLabel(LacpPartnerFrame.FRAME_LABEL)) + .toListExplicit(LacpPartnerFrame.class).stream() + .map(LacpPartner::new) + .collect(Collectors.toList()); + } + + @Override + public Collection findBySwitchId(SwitchId switchId) { + return framedGraph().traverse(g -> g.V() + .hasLabel(LacpPartnerFrame.FRAME_LABEL) + .has(LacpPartnerFrame.SWITCH_ID_PROPERTY, SwitchIdConverter.INSTANCE.toGraphProperty(switchId))) + .toListExplicit(LacpPartnerFrame.class).stream() + .map(LacpPartner::new) + .collect(Collectors.toList()); + } + + @Override + public Optional findBySwitchIdAndLogicalPortNumber(SwitchId switchId, int logicalPortNumber) { + List lacpPartnerFrames = framedGraph().traverse(g -> g.V() + .hasLabel(LacpPartnerFrame.FRAME_LABEL) + .has(LacpPartnerFrame.SWITCH_ID_PROPERTY, SwitchIdConverter.INSTANCE.toGraphProperty(switchId)) + .has(LacpPartnerFrame.LOGICAL_PORT_NUMBER_PROPERTY, logicalPortNumber)) + .toListExplicit(LacpPartnerFrame.class); + return lacpPartnerFrames.isEmpty() ? Optional.empty() : Optional.of(lacpPartnerFrames.get(0)) + .map(LacpPartner::new); + } +} diff --git a/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/repositories/FermaRepositoryFactory.java b/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/repositories/FermaRepositoryFactory.java index 3a63f0cdb21..b1f7dedf90c 100644 --- a/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/repositories/FermaRepositoryFactory.java +++ b/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/repositories/FermaRepositoryFactory.java @@ -30,6 +30,7 @@ import org.openkilda.persistence.repositories.IslRepository; import org.openkilda.persistence.repositories.KildaConfigurationRepository; import org.openkilda.persistence.repositories.KildaFeatureTogglesRepository; +import org.openkilda.persistence.repositories.LacpPartnerRepository; import org.openkilda.persistence.repositories.LagLogicalPortRepository; import org.openkilda.persistence.repositories.LinkPropsRepository; import org.openkilda.persistence.repositories.MirrorGroupRepository; @@ -227,6 +228,11 @@ public PortRepository createPortRepository() { return new FermaPortRepository(implementation); } + @Override + public LacpPartnerRepository createLacpPartnerRepository() { + return new FermaLacpPartnerRepository(implementation); + } + @Override public YFlowRepository createYFlowRepository() { return new FermaYFlowRepository(implementation); diff --git a/src-java/kilda-persistence-tinkerpop/src/test/java/org/openkilda/persistence/ferma/repositories/FermaLacpPartnerRepositoryTest.java b/src-java/kilda-persistence-tinkerpop/src/test/java/org/openkilda/persistence/ferma/repositories/FermaLacpPartnerRepositoryTest.java new file mode 100644 index 00000000000..5c4f0e37dc3 --- /dev/null +++ b/src-java/kilda-persistence-tinkerpop/src/test/java/org/openkilda/persistence/ferma/repositories/FermaLacpPartnerRepositoryTest.java @@ -0,0 +1,117 @@ +/* Copyright 2021 Telstra Open Source + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openkilda.persistence.ferma.repositories; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.openkilda.model.LacpPartner; +import org.openkilda.model.MacAddress; +import org.openkilda.model.SwitchId; +import org.openkilda.persistence.inmemory.InMemoryGraphBasedTest; +import org.openkilda.persistence.repositories.LacpPartnerRepository; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.Collection; +import java.util.Optional; + +public class FermaLacpPartnerRepositoryTest extends InMemoryGraphBasedTest { + public static final SwitchId TEST_SWITCH_ID_1 = new SwitchId(1); + public static final SwitchId TEST_SWITCH_ID_2 = new SwitchId(2); + public static final int LOGICAL_PORT_NUMBER_1 = 1; + public static final int LOGICAL_PORT_NUMBER_2 = 2; + + private static LacpPartnerRepository lacpPartnerRepository; + + @BeforeClass + public static void setUp() { + lacpPartnerRepository = repositoryFactory.createLacpPartnerRepository(); + } + + @Before + public void init() { + lacpPartnerRepository.add(buildLacpPartner(TEST_SWITCH_ID_1, LOGICAL_PORT_NUMBER_1)); + lacpPartnerRepository.add(buildLacpPartner(TEST_SWITCH_ID_1, LOGICAL_PORT_NUMBER_2)); + lacpPartnerRepository.add(buildLacpPartner(TEST_SWITCH_ID_2, LOGICAL_PORT_NUMBER_1)); + } + + @Test + public void fildAllReturnsAllLacpPartnersSuccess() { + Collection lacpPartners = lacpPartnerRepository.findAll(); + assertEquals(3, lacpPartners.size()); + } + + @Test + public void fildBySwitchIdReturnsSwitchLacpPartnersSuccess() { + Collection lacpPartnersBySwitch1 = lacpPartnerRepository.findBySwitchId(TEST_SWITCH_ID_1); + assertEquals(2, lacpPartnersBySwitch1.size()); + + Collection lacpPartnersBySwitch2 = lacpPartnerRepository.findBySwitchId(TEST_SWITCH_ID_2); + assertEquals(1, lacpPartnersBySwitch2.size()); + } + + @Test + public void fildBySwitchIdAndLogicalPortNumberReturnsLacpPartnersSuccess() { + Optional lacpPartner = lacpPartnerRepository.findBySwitchIdAndLogicalPortNumber(TEST_SWITCH_ID_1, + LOGICAL_PORT_NUMBER_1); + assertTrue(lacpPartner.isPresent()); + + lacpPartner = lacpPartnerRepository.findBySwitchIdAndLogicalPortNumber(TEST_SWITCH_ID_1, LOGICAL_PORT_NUMBER_2); + assertTrue(lacpPartner.isPresent()); + + lacpPartner = lacpPartnerRepository.findBySwitchIdAndLogicalPortNumber(TEST_SWITCH_ID_2, LOGICAL_PORT_NUMBER_1); + assertTrue(lacpPartner.isPresent()); + } + + @Test + public void deleteLacpPartner() { + Optional lacpPartner = lacpPartnerRepository.findBySwitchIdAndLogicalPortNumber(TEST_SWITCH_ID_2, + LOGICAL_PORT_NUMBER_1); + assertTrue(lacpPartner.isPresent()); + + Optional finalLacpPartner = lacpPartner; + transactionManager.doInTransaction(() -> lacpPartnerRepository.remove(finalLacpPartner.get())); + + assertEquals(2, lacpPartnerRepository.findAll().size()); + + lacpPartner = lacpPartnerRepository.findBySwitchIdAndLogicalPortNumber(TEST_SWITCH_ID_2, LOGICAL_PORT_NUMBER_1); + assertFalse(lacpPartner.isPresent()); + } + + private LacpPartner buildLacpPartner(SwitchId switchId, int logicalPortNumber) { + return LacpPartner.builder() + .switchId(switchId) + .logicalPortNumber(logicalPortNumber) + .systemPriority(1) + .systemId(new MacAddress("00:00:00:00:00:01")) + .key(1) + .portPriority(123) + .portNumber(11) + .stateActive(Boolean.TRUE) + .stateShortTimeout(Boolean.TRUE) + .stateAggregatable(Boolean.TRUE) + .stateSynchronised(Boolean.TRUE) + .stateCollecting(Boolean.TRUE) + .stateDistributing(Boolean.TRUE) + .stateDefaulted(Boolean.TRUE) + .stateExpired(Boolean.FALSE) + .build(); + } +} From 564e7e14f08527a2745c8ae3e43e7d32971e46b0 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 28 Dec 2022 19:27:12 +0000 Subject: [PATCH 2/9] Lacp status model, migration script typo fix --- .../025-add-lacp-partner-class.yaml | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/docker/db-migration/migrations/025-add-lacp-partner-class.yaml b/docker/db-migration/migrations/025-add-lacp-partner-class.yaml index 195cf92716c..12d0939d601 100644 --- a/docker/db-migration/migrations/025-add-lacp-partner-class.yaml +++ b/docker/db-migration/migrations/025-add-lacp-partner-class.yaml @@ -11,24 +11,24 @@ databaseChangeLog: author: dkakollu changes: - sql: "CREATE CLASS lacp_partner IF NOT EXISTS EXTENDS V" - - sql: "CREATE PROPERTY lacp_partner.switch_id IF NOT EXISTS STRING" + - sql: "CREATE PROPERTY lacp_partner.switch_id IF NOT EXISTS STRING" - sql: "CREATE PROPERTY lacp_partner.logical_port_number IF NOT EXISTS INTEGER" - sql: "CREATE PROPERTY lacp_partner.system_priority IF NOT EXISTS INTEGER" - - sql: "CREATE PROPERTY llacp_partner.system_id IF NOT EXISTS STRING" - - sql: "CREATE PROPERTY llacp_partner.key IF NOT EXISTS INTEGER" + - sql: "CREATE PROPERTY lacp_partner.system_id IF NOT EXISTS STRING" + - sql: "CREATE PROPERTY lacp_partner.key IF NOT EXISTS INTEGER" - sql: "CREATE PROPERTY lacp_partner.port_priority IF NOT EXISTS INTEGER" - - sql: "CREATE PROPERTY lacp_partner.port_number IF NOT EXISTS INTEGER" - - sql: "CREATE PROPERTY lacp_partner.state_active IF NOT EXISTS BOOLEAN" - - sql: "CREATE PROPERTY llacp_partner.state_short_timeout IF NOT EXISTS BOOLEAN" - - sql: "CREATE PROPERTY lacp_partner.state_aggregatable IF NOT EXISTS BOOLEAN" - - sql: "CREATE PROPERTY lacp_partner.state_synchronised IF NOT EXISTS BOOLEAN" - - sql: "CREATE PROPERTY lacp_partner.state_collecting IF NOT EXISTS BOOLEAN" - - sql: "CREATE PROPERTY lacp_partner.state_distributing IF NOT EXISTS BOOLEAN" - - sql: "CREATE PROPERTY lacp_partner.state_defaulted IF NOT EXISTS BOOLEAN" - - sql: "CREATE PROPERTY lacp_partner.state_expired IF NOT EXISTS BOOLEAN" - - sql: "CREATE INDEX lacp_partner.switch_id IF NOT EXISTS NOTUNIQUE_HASH_INDEX" + - sql: "CREATE PROPERTY lacp_partner.port_number IF NOT EXISTS INTEGER" + - sql: "CREATE PROPERTY lacp_partner.state_active IF NOT EXISTS BOOLEAN" + - sql: "CREATE PROPERTY lacp_partner.state_short_timeout IF NOT EXISTS BOOLEAN" + - sql: "CREATE PROPERTY lacp_partner.state_aggregatable IF NOT EXISTS BOOLEAN" + - sql: "CREATE PROPERTY lacp_partner.state_synchronised IF NOT EXISTS BOOLEAN" + - sql: "CREATE PROPERTY lacp_partner.state_collecting IF NOT EXISTS BOOLEAN" + - sql: "CREATE PROPERTY lacp_partner.state_distributing IF NOT EXISTS BOOLEAN" + - sql: "CREATE PROPERTY lacp_partner.state_defaulted IF NOT EXISTS BOOLEAN" + - sql: "CREATE PROPERTY lacp_partner.state_expired IF NOT EXISTS BOOLEAN" + - sql: "CREATE INDEX lacp_partner.switch_id IF NOT EXISTS NOTUNIQUE_HASH_INDEX" - sql: "CREATE INDEX lacp_partner.logical_port_number IF NOT EXISTS NOTUNIQUE_HASH_INDEX" - + rollback: - sql: "DELETE VERTEX lacp_partner" - - sql: "DROP CLASS llacp_partner IF EXISTS" + - sql: "DROP CLASS lacp_partner IF EXISTS" From 4e135a780a2a3d2ce38574c0999817dda0507dbd Mon Sep 17 00:00:00 2001 From: DURGA KAKOLLU Date: Wed, 4 Jan 2023 22:51:53 +0000 Subject: [PATCH 3/9] Issue-4964 LACP connection status API updates --- .../java/org/openkilda/model/LacpPartner.java | 4 +- .../request/GetSwitchLacpStatusRequest.java | 30 ++++++++++++ .../nbtopology/response/LacpStatusDto.java | 46 ++++++++++++++++++ .../response/SwitchLacpStatusResponse.java | 34 +++++++++++++ .../wfm/share/mappers/LacpStatusMapper.java | 30 ++++++++++++ .../nbworker/bolts/SwitchOperationsBolt.java | 17 +++++++ .../services/SwitchOperationsService.java | 48 +++++++++++++------ .../dto/v2/switches/LacpStatusResponse.java | 47 ++++++++++++++++++ .../controller/v2/SwitchControllerV2.java | 17 ++++++- .../converter/LacpStatusMapper.java | 27 +++++++++++ .../northbound/service/SwitchService.java | 5 +- .../service/impl/SwitchServiceImpl.java | 22 +++++++++ 12 files changed, 307 insertions(+), 20 deletions(-) create mode 100644 src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/request/GetSwitchLacpStatusRequest.java create mode 100644 src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/response/LacpStatusDto.java create mode 100644 src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/response/SwitchLacpStatusResponse.java create mode 100644 src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/share/mappers/LacpStatusMapper.java create mode 100644 src-java/northbound-service/northbound-api/src/main/java/org/openkilda/northbound/dto/v2/switches/LacpStatusResponse.java create mode 100644 src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/converter/LacpStatusMapper.java diff --git a/src-java/kilda-model/src/main/java/org/openkilda/model/LacpPartner.java b/src-java/kilda-model/src/main/java/org/openkilda/model/LacpPartner.java index 2cdf878395d..6017a2569f7 100644 --- a/src-java/kilda-model/src/main/java/org/openkilda/model/LacpPartner.java +++ b/src-java/kilda-model/src/main/java/org/openkilda/model/LacpPartner.java @@ -55,7 +55,7 @@ private LacpPartner() { } @Builder - public LacpPartner(@NonNull SwitchId switchId, @NonNull int logicalPortNumber, int systemPriority, + public LacpPartner(@NonNull SwitchId switchId, int logicalPortNumber, int systemPriority, MacAddress systemId, int key, int portPriority, int portNumber, boolean stateActive, boolean stateShortTimeout, boolean stateAggregatable, boolean stateSynchronised, boolean stateCollecting, boolean stateDistributing, boolean stateDefaulted, @@ -237,7 +237,7 @@ static final class LacpPartnerDataImpl implements LacpPartnerData, Serializable private static final long serialVersionUID = 1L; @NonNull SwitchId switchId; - @NonNull int logicalPortNumber; + int logicalPortNumber; int systemPriority; MacAddress systemId; diff --git a/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/request/GetSwitchLacpStatusRequest.java b/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/request/GetSwitchLacpStatusRequest.java new file mode 100644 index 00000000000..7f2b5fed1ad --- /dev/null +++ b/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/request/GetSwitchLacpStatusRequest.java @@ -0,0 +1,30 @@ +/* Copyright 2022 Telstra Open Source + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openkilda.messaging.nbtopology.request; + +import org.openkilda.model.SwitchId; + +import com.fasterxml.jackson.databind.PropertyNamingStrategy.SnakeCaseStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import lombok.EqualsAndHashCode; +import lombok.Value; + +@Value +@EqualsAndHashCode(callSuper = false) +@JsonNaming(value = SnakeCaseStrategy.class) +public class GetSwitchLacpStatusRequest extends SwitchesBaseRequest { + SwitchId switchId; +} diff --git a/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/response/LacpStatusDto.java b/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/response/LacpStatusDto.java new file mode 100644 index 00000000000..4df9f136598 --- /dev/null +++ b/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/response/LacpStatusDto.java @@ -0,0 +1,46 @@ +/* Copyright 2022 Telstra Open Source + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openkilda.messaging.nbtopology.response; + +import org.openkilda.model.MacAddress; +import org.openkilda.model.SwitchId; + +import com.fasterxml.jackson.databind.PropertyNamingStrategy.SnakeCaseStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import lombok.Value; + +import java.io.Serializable; + +@Value +@JsonNaming(value = SnakeCaseStrategy.class) +public class LacpStatusDto implements Serializable { + private static final long serialVersionUID = 1L; + SwitchId switchId; + int logicalPortNumber; + int systemPriority; + MacAddress systemId; + int key; + int portPriority; + int portNumber; + boolean stateActive; + boolean stateShortTimeout; + boolean stateAggregatable; + boolean stateSynchronised; + boolean stateCollecting; + boolean stateDistributing; + boolean stateDefaulted; + boolean stateExpired; +} diff --git a/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/response/SwitchLacpStatusResponse.java b/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/response/SwitchLacpStatusResponse.java new file mode 100644 index 00000000000..e7d68d77872 --- /dev/null +++ b/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/response/SwitchLacpStatusResponse.java @@ -0,0 +1,34 @@ +/* Copyright 2022 Telstra Open Source + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openkilda.messaging.nbtopology.response; + +import org.openkilda.messaging.info.InfoData; + +import com.fasterxml.jackson.databind.PropertyNamingStrategy.SnakeCaseStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = false) +@JsonNaming(value = SnakeCaseStrategy.class) +public class SwitchLacpStatusResponse extends InfoData { + private LacpStatusDto data; +} diff --git a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/share/mappers/LacpStatusMapper.java b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/share/mappers/LacpStatusMapper.java new file mode 100644 index 00000000000..9f16c84c6c5 --- /dev/null +++ b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/share/mappers/LacpStatusMapper.java @@ -0,0 +1,30 @@ +/* Copyright 2022 Telstra Open Source + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openkilda.wfm.share.mappers; + +import org.openkilda.messaging.nbtopology.response.LacpStatusDto; +import org.openkilda.model.LacpPartner; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public abstract class LacpStatusMapper { + + public static final LacpStatusMapper INSTANCE = Mappers.getMapper(LacpStatusMapper.class); + + public abstract LacpStatusDto map(LacpPartner partner); +} diff --git a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/bolts/SwitchOperationsBolt.java b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/bolts/SwitchOperationsBolt.java index 475fa48985a..e68bb0ab33f 100644 --- a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/bolts/SwitchOperationsBolt.java +++ b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/bolts/SwitchOperationsBolt.java @@ -32,6 +32,7 @@ import org.openkilda.messaging.nbtopology.request.GetAllSwitchPropertiesRequest; import org.openkilda.messaging.nbtopology.request.GetPortPropertiesRequest; import org.openkilda.messaging.nbtopology.request.GetSwitchConnectedDevicesRequest; +import org.openkilda.messaging.nbtopology.request.GetSwitchLacpStatusRequest; import org.openkilda.messaging.nbtopology.request.GetSwitchLagPortsRequest; import org.openkilda.messaging.nbtopology.request.GetSwitchPropertiesRequest; import org.openkilda.messaging.nbtopology.request.GetSwitchRequest; @@ -45,6 +46,7 @@ import org.openkilda.messaging.nbtopology.response.SwitchConnectedDeviceDto; import org.openkilda.messaging.nbtopology.response.SwitchConnectedDevicesResponse; import org.openkilda.messaging.nbtopology.response.SwitchConnectionsResponse; +import org.openkilda.messaging.nbtopology.response.SwitchLacpStatusResponse; import org.openkilda.messaging.nbtopology.response.SwitchLagPortResponse; import org.openkilda.messaging.nbtopology.response.SwitchPortConnectedDevicesDto; import org.openkilda.messaging.nbtopology.response.SwitchPropertiesResponse; @@ -67,6 +69,7 @@ import org.openkilda.wfm.error.SwitchNotFoundException; import org.openkilda.wfm.error.SwitchPropertiesNotFoundException; import org.openkilda.wfm.share.mappers.ConnectedDeviceMapper; +import org.openkilda.wfm.share.mappers.LacpStatusMapper; import org.openkilda.wfm.share.mappers.LagPortMapper; import org.openkilda.wfm.share.mappers.PortMapper; import org.openkilda.wfm.share.metrics.TimedExecution; @@ -153,6 +156,8 @@ private List dispatchRequest(Tuple tuple, BaseRequest reques result = getSwitchProperties(); } else if (request instanceof GetSwitchLagPortsRequest) { result = getLagPorts((GetSwitchLagPortsRequest) request); + } else if (request instanceof GetSwitchLacpStatusRequest) { + result = getSwitchLacpStatus((GetSwitchLacpStatusRequest) request); } else { unhandledInput(tuple); } @@ -321,6 +326,18 @@ private List getLagPorts(GetSwitchLagPortsRequest request } } + private List getSwitchLacpStatus(GetSwitchLacpStatusRequest request) { + try { + return switchOperationsService.getSwitchLacpStatus(request.getSwitchId()).stream() + .map(LacpStatusMapper.INSTANCE::map) + .map(SwitchLacpStatusResponse::new) + .collect(Collectors.toList()); + } catch (SwitchNotFoundException e) { + throw new MessageException(ErrorType.NOT_FOUND, e.getMessage(), + "Could not get LAG ports for non existent switch"); + } + } + private GetSwitchResponse patchSwitch(SwitchPatchRequest request) { try { return new GetSwitchResponse( diff --git a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/services/SwitchOperationsService.java b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/services/SwitchOperationsService.java index d9f8885f51e..b1d6d3efb82 100644 --- a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/services/SwitchOperationsService.java +++ b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/services/SwitchOperationsService.java @@ -32,6 +32,7 @@ import org.openkilda.model.Isl; import org.openkilda.model.IslEndpoint; import org.openkilda.model.IslStatus; +import org.openkilda.model.LacpPartner; import org.openkilda.model.LagLogicalPort; import org.openkilda.model.PhysicalPort; import org.openkilda.model.PortProperties; @@ -47,6 +48,7 @@ import org.openkilda.persistence.repositories.FlowPathRepository; import org.openkilda.persistence.repositories.FlowRepository; import org.openkilda.persistence.repositories.IslRepository; +import org.openkilda.persistence.repositories.LacpPartnerRepository; import org.openkilda.persistence.repositories.LagLogicalPortRepository; import org.openkilda.persistence.repositories.PhysicalPortRepository; import org.openkilda.persistence.repositories.PortPropertiesRepository; @@ -95,6 +97,7 @@ public class SwitchOperationsService { private FlowPathRepository flowPathRepository; private PhysicalPortRepository physicalPortRepository; private PortRepository portRepository; + private LacpPartnerRepository lacpPartnerRepository; public SwitchOperationsService( RepositoryFactory repositoryFactory, TransactionManager transactionManager, @@ -115,6 +118,7 @@ public SwitchOperationsService( this.flowMirrorPathRepository = repositoryFactory.createFlowMirrorPathRepository(); this.physicalPortRepository = repositoryFactory.createPhysicalPortRepository(); this.portRepository = repositoryFactory.createPortRepository(); + this.lacpPartnerRepository = repositoryFactory.createLacpPartnerRepository(); this.carrier = carrier; } @@ -145,7 +149,7 @@ public List getAllSwitches() { /** * Update the "Under maintenance" flag for the switch. * - * @param switchId switch id. + * @param switchId switch id. * @param underMaintenance "Under maintenance" flag. * @return updated switch. * @throws SwitchNotFoundException if there is no switch with this switch id. @@ -190,8 +194,8 @@ public Switch updateSwitchUnderMaintenanceFlag(SwitchId switchId, boolean underM * Delete switch. * * @param switchId ID of switch to be deleted - * @param force if True all switch relationships will be deleted too. - * If False switch will be deleted only if it has no relations. + * @param force if True all switch relationships will be deleted too. + * If False switch will be deleted only if it has no relations. * @return True if switch was deleted, False otherwise * @throws SwitchNotFoundException if switch is not found */ @@ -225,7 +229,7 @@ public boolean deleteSwitch(SwitchId switchId, boolean force) throws SwitchNotFo /** * Check that switch is not in 'Active' state. * - * @throws SwitchNotFoundException if there is no such switch. + * @throws SwitchNotFoundException if there is no such switch. * @throws IllegalSwitchStateException if switch is in 'Active' state */ public void checkSwitchIsDeactivated(SwitchId switchId) @@ -326,9 +330,9 @@ public List getSwitchProperties() { /** * Update switch properties. * - * @param switchId target switch id + * @param switchId target switch id * @param switchPropertiesDto switch properties - * @throws IllegalSwitchPropertiesException if switch properties are incorrect + * @throws IllegalSwitchPropertiesException if switch properties are incorrect * @throws SwitchPropertiesNotFoundException if switch properties is not found by switch id */ public SwitchPropertiesDto updateSwitchProperties(SwitchId switchId, SwitchPropertiesDto switchPropertiesDto) { @@ -442,10 +446,10 @@ private void validateSwitchProperties(SwitchId switchId, SwitchProperties update if (!flowsWitchEnabledLldp.isEmpty()) { throw new IllegalSwitchPropertiesException( format("Illegal switch properties combination for switch %s. " - + "Detect Connected Devices feature is turn on for following flows [%s]. " - + "For correct work of this feature switch property 'multiTable' must be set to 'true' " - + "Please disable detecting of connected devices via LLDP for each flow before set " - + "'multiTable' property to 'false'", + + "Detect Connected Devices feature is turn on for following flows [%s]. " + + "For correct work of this feature switch property 'multiTable' must be set to 'true' " + + "Please disable detecting of connected devices via LLDP for each flow before set " + + "'multiTable' property to 'false'", switchId, String.join(", ", flowsWitchEnabledLldp))); } @@ -456,10 +460,10 @@ private void validateSwitchProperties(SwitchId switchId, SwitchProperties update if (!flowsWithEnabledArp.isEmpty()) { throw new IllegalSwitchPropertiesException( format("Illegal switch properties combination for switch %s. " - + "Detect Connected Devices feature via ARP is turn on for following flows [%s]. " - + "For correct work of this feature switch property 'multiTable' must be set to 'true' " - + "Please disable detecting of connected devices via ARP for each flow before set " - + "'multiTable' property to 'false'", + + "Detect Connected Devices feature via ARP is turn on for following flows [%s]. " + + "For correct work of this feature switch property 'multiTable' must be set to 'true' " + + "Please disable detecting of connected devices via ARP for each flow before set " + + "'multiTable' property to 'false'", switchId, String.join(", ", flowsWithEnabledArp))); } } @@ -534,7 +538,7 @@ private void validateSwitchProperties(SwitchId switchId, SwitchProperties update * Get port properties. * * @param switchId target switch id - * @param port port number + * @param port port number */ public PortProperties getPortProperties(SwitchId switchId, int port) throws SwitchNotFoundException { return portPropertiesRepository.getBySwitchIdAndPort(switchId, port) @@ -575,6 +579,20 @@ public Collection getSwitchLagPorts(SwitchId switchId) throws Sw }); } + /** + * Get switch LACP status. + * + * @param switchId target switch id + */ + public Collection getSwitchLacpStatus(SwitchId switchId) throws SwitchNotFoundException { + return transactionManager.doInTransaction(() -> { + if (!switchRepository.exists(switchId)) { + throw new SwitchNotFoundException(switchId); + } + return lacpPartnerRepository.findBySwitchId(switchId); + }); + } + /** * Find and return all {@code IslEndpoint} for all ISL detected for this switch. */ diff --git a/src-java/northbound-service/northbound-api/src/main/java/org/openkilda/northbound/dto/v2/switches/LacpStatusResponse.java b/src-java/northbound-service/northbound-api/src/main/java/org/openkilda/northbound/dto/v2/switches/LacpStatusResponse.java new file mode 100644 index 00000000000..5c4d0a6a1bb --- /dev/null +++ b/src-java/northbound-service/northbound-api/src/main/java/org/openkilda/northbound/dto/v2/switches/LacpStatusResponse.java @@ -0,0 +1,47 @@ +/* Copyright 2022 Telstra Open Source + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openkilda.northbound.dto.v2.switches; + +import org.openkilda.model.MacAddress; +import org.openkilda.model.SwitchId; + +import com.fasterxml.jackson.databind.PropertyNamingStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) +public class LacpStatusResponse { + SwitchId switchId; + int logicalPortNumber; + int systemPriority; + MacAddress systemId; + int key; + int portPriority; + int portNumber; + boolean stateActive; + boolean stateShortTimeout; + boolean stateAggregatable; + boolean stateSynchronised; + boolean stateCollecting; + boolean stateDistributing; + boolean stateDefaulted; + boolean stateExpired; +} diff --git a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/controller/v2/SwitchControllerV2.java b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/controller/v2/SwitchControllerV2.java index 00d7dc1aa24..6a397979452 100644 --- a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/controller/v2/SwitchControllerV2.java +++ b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/controller/v2/SwitchControllerV2.java @@ -19,6 +19,7 @@ import org.openkilda.messaging.error.MessageException; import org.openkilda.model.SwitchId; import org.openkilda.northbound.controller.BaseController; +import org.openkilda.northbound.dto.v2.switches.LacpStatusResponse; import org.openkilda.northbound.dto.v2.switches.LagPortRequest; import org.openkilda.northbound.dto.v2.switches.LagPortResponse; import org.openkilda.northbound.dto.v2.switches.PortHistoryResponse; @@ -82,10 +83,10 @@ public CompletableFuture> getPortHistory( @PathVariable("port") int port, @ApiParam(value = "default: the day before timeTo.") @RequestParam(value = "timeFrom", required = false) @DateTimeFormat(iso = ISO.DATE_TIME) - Optional optionalFrom, + Optional optionalFrom, @ApiParam(value = "default: now.") @RequestParam(value = "timeTo", required = false) @DateTimeFormat(iso = ISO.DATE_TIME) - Optional optionalTo) { + Optional optionalTo) { Instant timeTo = optionalTo.map(Date::toInstant).orElseGet(Instant::now); Instant timeFrom = optionalFrom.map(Date::toInstant).orElseGet(() -> timeTo.minus(1, ChronoUnit.DAYS)); @@ -215,6 +216,18 @@ public CompletableFuture> getLagPorts(@PathVariable("switc return switchService.getLagPorts(switchId); } + /** + * Get LACP status on Switch. + * + * @param switchId the switch + */ + @ApiOperation(value = "Read all LACP status on specific switch", response = LacpStatusResponse.class) + @GetMapping(value = "/{switch_id}/lacpstatus") + @ResponseStatus(HttpStatus.OK) + public CompletableFuture> getLacpStatus(@PathVariable("switch_id") SwitchId switchId) { + return switchService.getLacpStatus(switchId); + } + /** * Update LAG logical port. */ diff --git a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/converter/LacpStatusMapper.java b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/converter/LacpStatusMapper.java new file mode 100644 index 00000000000..9ffe1885922 --- /dev/null +++ b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/converter/LacpStatusMapper.java @@ -0,0 +1,27 @@ +/* Copyright 2022 Telstra Open Source + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openkilda.northbound.converter; + +import org.openkilda.messaging.nbtopology.response.LacpStatusDto; +import org.openkilda.northbound.dto.v2.switches.LacpStatusResponse; + +import org.mapstruct.Mapper; + +@Mapper(componentModel = "spring") +public interface LacpStatusMapper { + + LacpStatusResponse map(LacpStatusDto response); +} diff --git a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/SwitchService.java b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/SwitchService.java index 1d992675204..f6b0bbbf863 100644 --- a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/SwitchService.java +++ b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/SwitchService.java @@ -35,6 +35,7 @@ import org.openkilda.northbound.dto.v1.switches.SwitchSyncResult; import org.openkilda.northbound.dto.v1.switches.SwitchValidationResult; import org.openkilda.northbound.dto.v1.switches.UnderMaintenanceDto; +import org.openkilda.northbound.dto.v2.switches.LacpStatusResponse; import org.openkilda.northbound.dto.v2.switches.LagPortRequest; import org.openkilda.northbound.dto.v2.switches.LagPortResponse; import org.openkilda.northbound.dto.v2.switches.PortHistoryResponse; @@ -233,7 +234,7 @@ CompletableFuture updateSwitchUnderMaintenance(SwitchId switchId, * * @param switchId id of switch to delete * @param force True value means that all switch checks (switch is deactivated, there is no flow with this switch, - * switch has no ISLs) will be ignored. + * switch has no ISLs) will be ignored. * @return result of the operation wrapped into {@link DeleteSwitchResult}. True means no errors is occurred. */ CompletableFuture deleteSwitch(SwitchId switchId, boolean force); @@ -313,6 +314,8 @@ CompletableFuture updatePortProperties(SwitchId switchId CompletableFuture> getLagPorts(SwitchId switchId); + CompletableFuture> getLacpStatus(SwitchId switchId); + CompletableFuture updateLagPort( SwitchId switchId, int logicalPortNumber, LagPortRequest payload); diff --git a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/impl/SwitchServiceImpl.java b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/impl/SwitchServiceImpl.java index 67878bf75c8..6de9940f837 100644 --- a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/impl/SwitchServiceImpl.java +++ b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/impl/SwitchServiceImpl.java @@ -59,6 +59,7 @@ import org.openkilda.messaging.nbtopology.request.GetFlowsForSwitchRequest; import org.openkilda.messaging.nbtopology.request.GetPortPropertiesRequest; import org.openkilda.messaging.nbtopology.request.GetSwitchConnectedDevicesRequest; +import org.openkilda.messaging.nbtopology.request.GetSwitchLacpStatusRequest; import org.openkilda.messaging.nbtopology.request.GetSwitchLagPortsRequest; import org.openkilda.messaging.nbtopology.request.GetSwitchPropertiesRequest; import org.openkilda.messaging.nbtopology.request.GetSwitchRequest; @@ -71,6 +72,7 @@ import org.openkilda.messaging.nbtopology.request.UpdateSwitchUnderMaintenanceRequest; import org.openkilda.messaging.nbtopology.response.DeleteSwitchResponse; import org.openkilda.messaging.nbtopology.response.GetSwitchResponse; +import org.openkilda.messaging.nbtopology.response.SwitchLacpStatusResponse; import org.openkilda.messaging.nbtopology.response.SwitchLagPortResponse; import org.openkilda.messaging.nbtopology.response.SwitchPropertiesResponse; import org.openkilda.messaging.payload.flow.FlowPayload; @@ -85,6 +87,7 @@ import org.openkilda.model.SwitchId; import org.openkilda.northbound.converter.ConnectedDeviceMapper; import org.openkilda.northbound.converter.FlowMapper; +import org.openkilda.northbound.converter.LacpStatusMapper; import org.openkilda.northbound.converter.LagPortMapper; import org.openkilda.northbound.converter.PortPropertiesMapper; import org.openkilda.northbound.converter.SwitchMapper; @@ -98,6 +101,7 @@ import org.openkilda.northbound.dto.v1.switches.SwitchSyncResult; import org.openkilda.northbound.dto.v1.switches.SwitchValidationResult; import org.openkilda.northbound.dto.v1.switches.UnderMaintenanceDto; +import org.openkilda.northbound.dto.v2.switches.LacpStatusResponse; import org.openkilda.northbound.dto.v2.switches.LagPortRequest; import org.openkilda.northbound.dto.v2.switches.LagPortResponse; import org.openkilda.northbound.dto.v2.switches.PortHistoryResponse; @@ -145,6 +149,9 @@ public class SwitchServiceImpl extends BaseService implements SwitchService { @Autowired private LagPortMapper lagPortMapper; + @Autowired + private LacpStatusMapper lacpStatusMapper; + @Autowired private ConnectedDeviceMapper connectedDeviceMapper; @@ -680,6 +687,21 @@ public CompletableFuture> getLagPorts(SwitchId switchId) { .collect(Collectors.toList())); } + @Override + public CompletableFuture> getLacpStatus(SwitchId switchId) { + log.info("API request: Getting LACP status on switch {}", switchId); + + GetSwitchLacpStatusRequest data = new GetSwitchLacpStatusRequest(switchId); + CommandMessage request = new CommandMessage(data, System.currentTimeMillis(), RequestCorrelationId.getId()); + + return messagingChannel.sendAndGetChunked(nbworkerTopic, request) + .thenApply(result -> result.stream() + .map(SwitchLacpStatusResponse.class::cast) + .map(SwitchLacpStatusResponse::getData) + .map(lacpStatusMapper::map) + .collect(Collectors.toList())); + } + @Override public CompletableFuture updateLagPort( SwitchId switchId, int logicalPortNumber, LagPortRequest payload) { From cc2abfce04cc7d070664e3f9752fca5dbe2e7060 Mon Sep 17 00:00:00 2001 From: DURGA KAKOLLU Date: Thu, 5 Jan 2023 10:38:41 +0000 Subject: [PATCH 4/9] Issue-4964 LACP connection status API updates - Updated checkstyle issues --- .../services/SwitchOperationsService.java | 30 +++++++++---------- .../northbound/service/SwitchService.java | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/services/SwitchOperationsService.java b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/services/SwitchOperationsService.java index b1d6d3efb82..9518ccdc896 100644 --- a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/services/SwitchOperationsService.java +++ b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/services/SwitchOperationsService.java @@ -149,7 +149,7 @@ public List getAllSwitches() { /** * Update the "Under maintenance" flag for the switch. * - * @param switchId switch id. + * @param switchId switch id. * @param underMaintenance "Under maintenance" flag. * @return updated switch. * @throws SwitchNotFoundException if there is no switch with this switch id. @@ -194,8 +194,8 @@ public Switch updateSwitchUnderMaintenanceFlag(SwitchId switchId, boolean underM * Delete switch. * * @param switchId ID of switch to be deleted - * @param force if True all switch relationships will be deleted too. - * If False switch will be deleted only if it has no relations. + * @param force if True all switch relationships will be deleted too. + * If False switch will be deleted only if it has no relations. * @return True if switch was deleted, False otherwise * @throws SwitchNotFoundException if switch is not found */ @@ -229,7 +229,7 @@ public boolean deleteSwitch(SwitchId switchId, boolean force) throws SwitchNotFo /** * Check that switch is not in 'Active' state. * - * @throws SwitchNotFoundException if there is no such switch. + * @throws SwitchNotFoundException if there is no such switch. * @throws IllegalSwitchStateException if switch is in 'Active' state */ public void checkSwitchIsDeactivated(SwitchId switchId) @@ -330,9 +330,9 @@ public List getSwitchProperties() { /** * Update switch properties. * - * @param switchId target switch id + * @param switchId target switch id * @param switchPropertiesDto switch properties - * @throws IllegalSwitchPropertiesException if switch properties are incorrect + * @throws IllegalSwitchPropertiesException if switch properties are incorrect * @throws SwitchPropertiesNotFoundException if switch properties is not found by switch id */ public SwitchPropertiesDto updateSwitchProperties(SwitchId switchId, SwitchPropertiesDto switchPropertiesDto) { @@ -446,10 +446,10 @@ private void validateSwitchProperties(SwitchId switchId, SwitchProperties update if (!flowsWitchEnabledLldp.isEmpty()) { throw new IllegalSwitchPropertiesException( format("Illegal switch properties combination for switch %s. " - + "Detect Connected Devices feature is turn on for following flows [%s]. " - + "For correct work of this feature switch property 'multiTable' must be set to 'true' " - + "Please disable detecting of connected devices via LLDP for each flow before set " - + "'multiTable' property to 'false'", + + "Detect Connected Devices feature is turn on for following flows [%s]. " + + "For correct work of this feature switch property 'multiTable' must be set to 'true' " + + "Please disable detecting of connected devices via LLDP for each flow before set " + + "'multiTable' property to 'false'", switchId, String.join(", ", flowsWitchEnabledLldp))); } @@ -460,10 +460,10 @@ private void validateSwitchProperties(SwitchId switchId, SwitchProperties update if (!flowsWithEnabledArp.isEmpty()) { throw new IllegalSwitchPropertiesException( format("Illegal switch properties combination for switch %s. " - + "Detect Connected Devices feature via ARP is turn on for following flows [%s]. " - + "For correct work of this feature switch property 'multiTable' must be set to 'true' " - + "Please disable detecting of connected devices via ARP for each flow before set " - + "'multiTable' property to 'false'", + + "Detect Connected Devices feature via ARP is turn on for following flows [%s]. " + + "For correct work of this feature switch property 'multiTable' must be set to 'true' " + + "Please disable detecting of connected devices via ARP for each flow before set " + + "'multiTable' property to 'false'", switchId, String.join(", ", flowsWithEnabledArp))); } } @@ -538,7 +538,7 @@ private void validateSwitchProperties(SwitchId switchId, SwitchProperties update * Get port properties. * * @param switchId target switch id - * @param port port number + * @param port port number */ public PortProperties getPortProperties(SwitchId switchId, int port) throws SwitchNotFoundException { return portPropertiesRepository.getBySwitchIdAndPort(switchId, port) diff --git a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/SwitchService.java b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/SwitchService.java index f6b0bbbf863..ca570b77a23 100644 --- a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/SwitchService.java +++ b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/SwitchService.java @@ -234,7 +234,7 @@ CompletableFuture updateSwitchUnderMaintenance(SwitchId switchId, * * @param switchId id of switch to delete * @param force True value means that all switch checks (switch is deactivated, there is no flow with this switch, - * switch has no ISLs) will be ignored. + * switch has no ISLs) will be ignored. * @return result of the operation wrapped into {@link DeleteSwitchResult}. True means no errors is occurred. */ CompletableFuture deleteSwitch(SwitchId switchId, boolean force); From bb072f4ad67f3473f58d66485a777e65a43fc05e Mon Sep 17 00:00:00 2001 From: DURGA KAKOLLU Date: Tue, 10 Jan 2023 22:52:17 +0000 Subject: [PATCH 5/9] Issue-4964 Add NB API on LACP connection status --- .../025-add-lacp-partner-class.yaml | 4 +- .../repositories/LacpPartnerRepository.java | 2 +- .../request/GetLacpStatusRequest.java | 31 +++++++++++++ .../nbworker/bolts/SwitchOperationsBolt.java | 24 +++++++++- .../services/SwitchOperationsService.java | 46 +++++++++++++------ .../controller/v2/SwitchControllerV2.java | 16 +++++++ .../northbound/service/SwitchService.java | 2 + .../service/impl/SwitchServiceImpl.java | 16 +++++++ 8 files changed, 121 insertions(+), 20 deletions(-) create mode 100644 src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/request/GetLacpStatusRequest.java diff --git a/docker/db-migration/migrations/025-add-lacp-partner-class.yaml b/docker/db-migration/migrations/025-add-lacp-partner-class.yaml index 12d0939d601..fd3aaae5901 100644 --- a/docker/db-migration/migrations/025-add-lacp-partner-class.yaml +++ b/docker/db-migration/migrations/025-add-lacp-partner-class.yaml @@ -4,7 +4,7 @@ databaseChangeLog: author: dkakollu changes: - tagDatabase: - tag: 024-add-lacp-partner-class + tag: 025-add-lacp-partner-class - changeSet: id: add-lacp-partner-class @@ -28,7 +28,7 @@ databaseChangeLog: - sql: "CREATE PROPERTY lacp_partner.state_expired IF NOT EXISTS BOOLEAN" - sql: "CREATE INDEX lacp_partner.switch_id IF NOT EXISTS NOTUNIQUE_HASH_INDEX" - sql: "CREATE INDEX lacp_partner.logical_port_number IF NOT EXISTS NOTUNIQUE_HASH_INDEX" - + rollback: - sql: "DELETE VERTEX lacp_partner" - sql: "DROP CLASS lacp_partner IF EXISTS" diff --git a/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/LacpPartnerRepository.java b/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/LacpPartnerRepository.java index 5d02bbb24d5..4d45ac1d5ea 100644 --- a/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/LacpPartnerRepository.java +++ b/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/LacpPartnerRepository.java @@ -26,5 +26,5 @@ public interface LacpPartnerRepository extends Repository { Collection findBySwitchId(SwitchId switchId); - Optional findBySwitchIdAndLogicalPortNumber(SwitchId switchId, int portNumber); + Optional findBySwitchIdAndLogicalPortNumber(SwitchId switchId, int logicalPortNumber); } diff --git a/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/request/GetLacpStatusRequest.java b/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/request/GetLacpStatusRequest.java new file mode 100644 index 00000000000..7185059672b --- /dev/null +++ b/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/request/GetLacpStatusRequest.java @@ -0,0 +1,31 @@ +/* Copyright 2022 Telstra Open Source + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openkilda.messaging.nbtopology.request; + +import org.openkilda.model.SwitchId; + +import com.fasterxml.jackson.databind.PropertyNamingStrategy.SnakeCaseStrategy; +import com.fasterxml.jackson.databind.annotation.JsonNaming; +import lombok.EqualsAndHashCode; +import lombok.Value; + +@Value +@EqualsAndHashCode(callSuper = false) +@JsonNaming(value = SnakeCaseStrategy.class) +public class GetLacpStatusRequest extends SwitchesBaseRequest { + SwitchId switchId; + int logicalPortNumber; +} diff --git a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/bolts/SwitchOperationsBolt.java b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/bolts/SwitchOperationsBolt.java index e68bb0ab33f..4072ba9d1ba 100644 --- a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/bolts/SwitchOperationsBolt.java +++ b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/bolts/SwitchOperationsBolt.java @@ -30,6 +30,7 @@ import org.openkilda.messaging.nbtopology.request.BaseRequest; import org.openkilda.messaging.nbtopology.request.DeleteSwitchRequest; import org.openkilda.messaging.nbtopology.request.GetAllSwitchPropertiesRequest; +import org.openkilda.messaging.nbtopology.request.GetLacpStatusRequest; import org.openkilda.messaging.nbtopology.request.GetPortPropertiesRequest; import org.openkilda.messaging.nbtopology.request.GetSwitchConnectedDevicesRequest; import org.openkilda.messaging.nbtopology.request.GetSwitchLacpStatusRequest; @@ -95,6 +96,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -158,7 +160,9 @@ private List dispatchRequest(Tuple tuple, BaseRequest reques result = getLagPorts((GetSwitchLagPortsRequest) request); } else if (request instanceof GetSwitchLacpStatusRequest) { result = getSwitchLacpStatus((GetSwitchLacpStatusRequest) request); - } else { + } else if (request instanceof GetLacpStatusRequest) { + result = getLacpStatus((GetLacpStatusRequest) request); + } else { unhandledInput(tuple); } @@ -334,7 +338,23 @@ private List getSwitchLacpStatus(GetSwitchLacpStatusRe .collect(Collectors.toList()); } catch (SwitchNotFoundException e) { throw new MessageException(ErrorType.NOT_FOUND, e.getMessage(), - "Could not get LAG ports for non existent switch"); + "Could not get LACP Status for non existent switch"); + } + } + + private List getLacpStatus(GetLacpStatusRequest request) { + try { + Optional switchLacpStatusResponseOptional = switchOperationsService + .getLacpStatus(request.getSwitchId(), request.getLogicalPortNumber()) + .map(LacpStatusMapper.INSTANCE::map) + .map(SwitchLacpStatusResponse::new); + + return switchLacpStatusResponseOptional.isPresent() + ? Collections.singletonList(switchLacpStatusResponseOptional.get()) + : Collections.EMPTY_LIST; + } catch (SwitchNotFoundException e) { + throw new MessageException(ErrorType.NOT_FOUND, e.getMessage(), + "Could not get LACP Status for non existent switch"); } } diff --git a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/services/SwitchOperationsService.java b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/services/SwitchOperationsService.java index 9518ccdc896..73be8b46166 100644 --- a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/services/SwitchOperationsService.java +++ b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/services/SwitchOperationsService.java @@ -149,7 +149,7 @@ public List getAllSwitches() { /** * Update the "Under maintenance" flag for the switch. * - * @param switchId switch id. + * @param switchId switch id. * @param underMaintenance "Under maintenance" flag. * @return updated switch. * @throws SwitchNotFoundException if there is no switch with this switch id. @@ -194,8 +194,8 @@ public Switch updateSwitchUnderMaintenanceFlag(SwitchId switchId, boolean underM * Delete switch. * * @param switchId ID of switch to be deleted - * @param force if True all switch relationships will be deleted too. - * If False switch will be deleted only if it has no relations. + * @param force if True all switch relationships will be deleted too. + * If False switch will be deleted only if it has no relations. * @return True if switch was deleted, False otherwise * @throws SwitchNotFoundException if switch is not found */ @@ -229,7 +229,7 @@ public boolean deleteSwitch(SwitchId switchId, boolean force) throws SwitchNotFo /** * Check that switch is not in 'Active' state. * - * @throws SwitchNotFoundException if there is no such switch. + * @throws SwitchNotFoundException if there is no such switch. * @throws IllegalSwitchStateException if switch is in 'Active' state */ public void checkSwitchIsDeactivated(SwitchId switchId) @@ -330,9 +330,9 @@ public List getSwitchProperties() { /** * Update switch properties. * - * @param switchId target switch id + * @param switchId target switch id * @param switchPropertiesDto switch properties - * @throws IllegalSwitchPropertiesException if switch properties are incorrect + * @throws IllegalSwitchPropertiesException if switch properties are incorrect * @throws SwitchPropertiesNotFoundException if switch properties is not found by switch id */ public SwitchPropertiesDto updateSwitchProperties(SwitchId switchId, SwitchPropertiesDto switchPropertiesDto) { @@ -446,10 +446,10 @@ private void validateSwitchProperties(SwitchId switchId, SwitchProperties update if (!flowsWitchEnabledLldp.isEmpty()) { throw new IllegalSwitchPropertiesException( format("Illegal switch properties combination for switch %s. " - + "Detect Connected Devices feature is turn on for following flows [%s]. " - + "For correct work of this feature switch property 'multiTable' must be set to 'true' " - + "Please disable detecting of connected devices via LLDP for each flow before set " - + "'multiTable' property to 'false'", + + "Detect Connected Devices feature is turn on for following flows [%s]. " + + "For correct work of this feature switch property 'multiTable' must be set to 'true' " + + "Please disable detecting of connected devices via LLDP for each flow before set " + + "'multiTable' property to 'false'", switchId, String.join(", ", flowsWitchEnabledLldp))); } @@ -460,10 +460,10 @@ private void validateSwitchProperties(SwitchId switchId, SwitchProperties update if (!flowsWithEnabledArp.isEmpty()) { throw new IllegalSwitchPropertiesException( format("Illegal switch properties combination for switch %s. " - + "Detect Connected Devices feature via ARP is turn on for following flows [%s]. " - + "For correct work of this feature switch property 'multiTable' must be set to 'true' " - + "Please disable detecting of connected devices via ARP for each flow before set " - + "'multiTable' property to 'false'", + + "Detect Connected Devices feature via ARP is turn on for following flows [%s]. " + + "For correct work of this feature switch property 'multiTable' must be set to 'true' " + + "Please disable detecting of connected devices via ARP for each flow before set " + + "'multiTable' property to 'false'", switchId, String.join(", ", flowsWithEnabledArp))); } } @@ -538,7 +538,7 @@ private void validateSwitchProperties(SwitchId switchId, SwitchProperties update * Get port properties. * * @param switchId target switch id - * @param port port number + * @param port port number */ public PortProperties getPortProperties(SwitchId switchId, int port) throws SwitchNotFoundException { return portPropertiesRepository.getBySwitchIdAndPort(switchId, port) @@ -593,6 +593,22 @@ public Collection getSwitchLacpStatus(SwitchId switchId) throws Swi }); } + /** + * Get LACP status. + * + * @param switchId target switch id + * @param logicalPortNumber target logical port number + */ + public Optional getLacpStatus(SwitchId switchId, int logicalPortNumber) + throws SwitchNotFoundException { + return transactionManager.doInTransaction(() -> { + if (!switchRepository.exists(switchId)) { + throw new SwitchNotFoundException(switchId); + } + return lacpPartnerRepository.findBySwitchIdAndLogicalPortNumber(switchId, logicalPortNumber); + }); + } + /** * Find and return all {@code IslEndpoint} for all ISL detected for this switch. */ diff --git a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/controller/v2/SwitchControllerV2.java b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/controller/v2/SwitchControllerV2.java index 6a397979452..846294f9388 100644 --- a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/controller/v2/SwitchControllerV2.java +++ b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/controller/v2/SwitchControllerV2.java @@ -228,6 +228,22 @@ public CompletableFuture> getLacpStatus(@PathVariable(" return switchService.getLacpStatus(switchId); } + /** + * Get LACP status. + * + * @param switchId the switch + * @param logicalPortNumber the switch + * + */ + @ApiOperation(value = "Read all LACP status on specific switch", response = LacpStatusResponse.class) + @GetMapping(value = "/{switch_id}/lacp/{logical_port_number}") + @ResponseStatus(HttpStatus.OK) + public CompletableFuture> getLacpStatus(@PathVariable("switch_id") SwitchId switchId, + @PathVariable("logical_port_number") + int logicalPortNumber) { + return switchService.getLacpStatus(switchId, logicalPortNumber); + } + /** * Update LAG logical port. */ diff --git a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/SwitchService.java b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/SwitchService.java index ca570b77a23..5d3924c6bc5 100644 --- a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/SwitchService.java +++ b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/SwitchService.java @@ -316,6 +316,8 @@ CompletableFuture updatePortProperties(SwitchId switchId CompletableFuture> getLacpStatus(SwitchId switchId); + CompletableFuture> getLacpStatus(SwitchId switchId, int logicalPortNumber); + CompletableFuture updateLagPort( SwitchId switchId, int logicalPortNumber, LagPortRequest payload); diff --git a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/impl/SwitchServiceImpl.java b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/impl/SwitchServiceImpl.java index 6de9940f837..c738a643cb1 100644 --- a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/impl/SwitchServiceImpl.java +++ b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/impl/SwitchServiceImpl.java @@ -57,6 +57,7 @@ import org.openkilda.messaging.nbtopology.request.DeleteSwitchRequest; import org.openkilda.messaging.nbtopology.request.GetAllSwitchPropertiesRequest; import org.openkilda.messaging.nbtopology.request.GetFlowsForSwitchRequest; +import org.openkilda.messaging.nbtopology.request.GetLacpStatusRequest; import org.openkilda.messaging.nbtopology.request.GetPortPropertiesRequest; import org.openkilda.messaging.nbtopology.request.GetSwitchConnectedDevicesRequest; import org.openkilda.messaging.nbtopology.request.GetSwitchLacpStatusRequest; @@ -702,6 +703,21 @@ public CompletableFuture> getLacpStatus(SwitchId switch .collect(Collectors.toList())); } + @Override + public CompletableFuture> getLacpStatus(SwitchId switchId, int logicalPortNumber) { + log.info("API request: Getting LACP status on switch {}", switchId); + + GetLacpStatusRequest data = new GetLacpStatusRequest(switchId, logicalPortNumber); + CommandMessage request = new CommandMessage(data, System.currentTimeMillis(), RequestCorrelationId.getId()); + + return messagingChannel.sendAndGetChunked(nbworkerTopic, request) + .thenApply(result -> result.stream() + .map(SwitchLacpStatusResponse.class::cast) + .map(SwitchLacpStatusResponse::getData) + .map(lacpStatusMapper::map) + .collect(Collectors.toList())); + } + @Override public CompletableFuture updateLagPort( SwitchId switchId, int logicalPortNumber, LagPortRequest payload) { From 4a2c83a53757f962f95a715368b0f7ff485adc8d Mon Sep 17 00:00:00 2001 From: DURGA KAKOLLU Date: Thu, 26 Jan 2023 23:04:01 +0000 Subject: [PATCH 6/9] Issue-4964 Update NB API to get LACP connection status --- .../controller/v2/SwitchControllerV2.java | 4 ++-- .../northbound/service/SwitchService.java | 2 +- .../northbound/service/impl/SwitchServiceImpl.java | 14 ++++++-------- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/controller/v2/SwitchControllerV2.java b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/controller/v2/SwitchControllerV2.java index 846294f9388..99f3a41f176 100644 --- a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/controller/v2/SwitchControllerV2.java +++ b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/controller/v2/SwitchControllerV2.java @@ -235,10 +235,10 @@ public CompletableFuture> getLacpStatus(@PathVariable(" * @param logicalPortNumber the switch * */ - @ApiOperation(value = "Read all LACP status on specific switch", response = LacpStatusResponse.class) + @ApiOperation(value = "Read LACP status on specific port of the switch", response = LacpStatusResponse.class) @GetMapping(value = "/{switch_id}/lacp/{logical_port_number}") @ResponseStatus(HttpStatus.OK) - public CompletableFuture> getLacpStatus(@PathVariable("switch_id") SwitchId switchId, + public CompletableFuture getLacpStatus(@PathVariable("switch_id") SwitchId switchId, @PathVariable("logical_port_number") int logicalPortNumber) { return switchService.getLacpStatus(switchId, logicalPortNumber); diff --git a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/SwitchService.java b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/SwitchService.java index 5d3924c6bc5..5a24fdb4cb3 100644 --- a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/SwitchService.java +++ b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/SwitchService.java @@ -316,7 +316,7 @@ CompletableFuture updatePortProperties(SwitchId switchId CompletableFuture> getLacpStatus(SwitchId switchId); - CompletableFuture> getLacpStatus(SwitchId switchId, int logicalPortNumber); + CompletableFuture getLacpStatus(SwitchId switchId, int logicalPortNumber); CompletableFuture updateLagPort( SwitchId switchId, int logicalPortNumber, LagPortRequest payload); diff --git a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/impl/SwitchServiceImpl.java b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/impl/SwitchServiceImpl.java index c738a643cb1..86f1dbf0d4b 100644 --- a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/impl/SwitchServiceImpl.java +++ b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/service/impl/SwitchServiceImpl.java @@ -704,18 +704,16 @@ public CompletableFuture> getLacpStatus(SwitchId switch } @Override - public CompletableFuture> getLacpStatus(SwitchId switchId, int logicalPortNumber) { - log.info("API request: Getting LACP status on switch {}", switchId); + public CompletableFuture getLacpStatus(SwitchId switchId, int logicalPortNumber) { + log.info("API request: Read LACP status on specific port {} of the switch {}", logicalPortNumber, switchId); GetLacpStatusRequest data = new GetLacpStatusRequest(switchId, logicalPortNumber); CommandMessage request = new CommandMessage(data, System.currentTimeMillis(), RequestCorrelationId.getId()); - return messagingChannel.sendAndGetChunked(nbworkerTopic, request) - .thenApply(result -> result.stream() - .map(SwitchLacpStatusResponse.class::cast) - .map(SwitchLacpStatusResponse::getData) - .map(lacpStatusMapper::map) - .collect(Collectors.toList())); + return messagingChannel.sendAndGet(nbworkerTopic, request) + .thenApply(SwitchLacpStatusResponse.class::cast) + .thenApply(SwitchLacpStatusResponse::getData) + .thenApply(lacpStatusMapper::map); } @Override From ffeebda5f5aef6028a16e6fe8a769a9b4774b0ce Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 31 Jan 2023 23:21:11 +0000 Subject: [PATCH 7/9] #4964 LACP status - Updated based on review comments --- .../messaging/info/event/LacpInfoData.java | 2 +- .../messaging/info/event/LacpPartner.java | 2 +- .../messaging/info/event/LacpState.java | 2 +- .../ConnectedDevicesTopology.java | 25 ++++++++++--------- .../service/PacketService.java | 3 +-- .../java/org/openkilda/model/LacpPartner.java | 2 +- .../repositories/LacpPartnerRepository.java | 2 +- .../hibernate/HibernateRepositoryFactory.java | 2 +- .../ferma/frames/LacpPartnerFrame.java | 2 +- .../FermaLacpPartnerRepository.java | 7 +++++- .../FermaLacpPartnerRepositoryTest.java | 2 +- .../request/GetLacpStatusRequest.java | 2 +- .../request/GetSwitchLacpStatusRequest.java | 2 +- .../nbtopology/response/LacpStatusDto.java | 2 +- .../response/SwitchLacpStatusResponse.java | 2 +- .../wfm/share/mappers/LacpStatusMapper.java | 2 +- .../services/SwitchOperationsService.java | 6 ++--- .../dto/v2/switches/LacpStatusResponse.java | 2 +- .../controller/v2/SwitchControllerV2.java | 6 +++-- .../converter/LacpStatusMapper.java | 2 +- 20 files changed, 42 insertions(+), 35 deletions(-) diff --git a/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpInfoData.java b/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpInfoData.java index 4dfd3aa0750..e19872ce7fd 100644 --- a/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpInfoData.java +++ b/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpInfoData.java @@ -1,4 +1,4 @@ -/* Copyright 2017 Telstra Open Source +/* Copyright 2023 Telstra Open Source * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpPartner.java b/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpPartner.java index 3b68a3e44f8..b098a86f6b5 100644 --- a/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpPartner.java +++ b/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpPartner.java @@ -1,4 +1,4 @@ -/* Copyright 2021 Telstra Open Source +/* Copyright 2023 Telstra Open Source * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpState.java b/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpState.java index 08d0c5bb6a3..165ab96ec0f 100644 --- a/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpState.java +++ b/src-java/base-topology/base-messaging/src/main/java/org/openkilda/messaging/info/event/LacpState.java @@ -1,4 +1,4 @@ -/* Copyright 2021 Telstra Open Source +/* Copyright 2023 Telstra Open Source * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/ConnectedDevicesTopology.java b/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/ConnectedDevicesTopology.java index edea3d1a209..2c5e48efee0 100644 --- a/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/ConnectedDevicesTopology.java +++ b/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/ConnectedDevicesTopology.java @@ -39,18 +39,6 @@ public ConnectedDevicesTopology(LaunchEnvironment env) { super(env, "connecteddevices-topology", ConnectedDevicesTopologyConfig.class); } - /** - * Main method to run topology. - */ - public static void main(String[] args) { - try { - LaunchEnvironment env = new LaunchEnvironment(args); - (new ConnectedDevicesTopology(env)).setup(); - } catch (Exception e) { - System.exit(handleLaunchException(e)); - } - } - /** * Creating topology. */ @@ -81,6 +69,7 @@ private void createRouterBolt(TopologyBuilder builder, PersistenceManager persis RouterBolt routerBolt = new RouterBolt(persistenceManager, ZooKeeperSpout.SPOUT_ID); declareBolt(builder, routerBolt, ROUTER_BOLT_ID) .shuffleGrouping(CONNECTED_DEVICES_SPOUT_ID) + .shuffleGrouping(LACP_SPOUT_ID) .allGrouping(ZooKeeperSpout.SPOUT_ID); } @@ -110,4 +99,16 @@ private void createZkBolt(TopologyBuilder builder) { protected String getZkTopoName() { return "connecteddevices"; } + + /** + * Main method to run topology. + */ + public static void main(String[] args) { + try { + LaunchEnvironment env = new LaunchEnvironment(args); + (new ConnectedDevicesTopology(env)).setup(); + } catch (Exception e) { + System.exit(handleLaunchException(e)); + } + } } diff --git a/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/service/PacketService.java b/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/service/PacketService.java index f4bf892f2bf..758ba8c6876 100644 --- a/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/service/PacketService.java +++ b/src-java/connecteddevices-topology/connecteddevices-storm-topology/src/main/java/org/openkilda/wfm/topology/connecteddevices/service/PacketService.java @@ -99,10 +99,9 @@ public static String createMessageKey(ArpInfoData data) { /** * This key is needed to balance load on Packet Bolt. If you see that some packet bolts have high load, and * some have low load, try to extend this key. Maximum extension is equal to - * SwitchConnectedDeviceFrame.UNIQUE_INDEX_PROPERTY */ public static String createMessageKey(LacpInfoData data) { - return String.format("%s_%s_arp", data.getSwitchId(), data.getLogicalPortNumber()); + return String.format("%s_%s_lacp", data.getSwitchId(), data.getLogicalPortNumber()); } /** diff --git a/src-java/kilda-model/src/main/java/org/openkilda/model/LacpPartner.java b/src-java/kilda-model/src/main/java/org/openkilda/model/LacpPartner.java index 6017a2569f7..ac83a8e0d65 100644 --- a/src-java/kilda-model/src/main/java/org/openkilda/model/LacpPartner.java +++ b/src-java/kilda-model/src/main/java/org/openkilda/model/LacpPartner.java @@ -1,4 +1,4 @@ -/* Copyright 2021 Telstra Open Source +/* Copyright 2023 Telstra Open Source * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/LacpPartnerRepository.java b/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/LacpPartnerRepository.java index 4d45ac1d5ea..58e09e6fa4a 100644 --- a/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/LacpPartnerRepository.java +++ b/src-java/kilda-persistence-api/src/main/java/org/openkilda/persistence/repositories/LacpPartnerRepository.java @@ -1,4 +1,4 @@ -/* Copyright 2021 Telstra Open Source +/* Copyright 2023 Telstra Open Source * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src-java/kilda-persistence-hibernate/src/main/java/org/openkilda/persistence/hibernate/HibernateRepositoryFactory.java b/src-java/kilda-persistence-hibernate/src/main/java/org/openkilda/persistence/hibernate/HibernateRepositoryFactory.java index e607201f65d..9c040c73579 100644 --- a/src-java/kilda-persistence-hibernate/src/main/java/org/openkilda/persistence/hibernate/HibernateRepositoryFactory.java +++ b/src-java/kilda-persistence-hibernate/src/main/java/org/openkilda/persistence/hibernate/HibernateRepositoryFactory.java @@ -213,7 +213,7 @@ public PortRepository createPortRepository() { @Override public LacpPartnerRepository createLacpPartnerRepository() { - throw new IllegalStateException("Repository not implemented on hibernate layer"); + throw new IllegalStateException("The Repository is not implemented on hibernate layer"); } @Override diff --git a/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/frames/LacpPartnerFrame.java b/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/frames/LacpPartnerFrame.java index b93de998ebd..ca5ac4f547b 100644 --- a/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/frames/LacpPartnerFrame.java +++ b/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/frames/LacpPartnerFrame.java @@ -1,4 +1,4 @@ -/* Copyright 2021 Telstra Open Source +/* Copyright 2023 Telstra Open Source * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/repositories/FermaLacpPartnerRepository.java b/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/repositories/FermaLacpPartnerRepository.java index 0e82f8b5df5..55ff244baba 100644 --- a/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/repositories/FermaLacpPartnerRepository.java +++ b/src-java/kilda-persistence-tinkerpop/src/main/java/org/openkilda/persistence/ferma/repositories/FermaLacpPartnerRepository.java @@ -1,4 +1,4 @@ -/* Copyright 2022 Telstra Open Source +/* Copyright 2023 Telstra Open Source * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -87,6 +87,11 @@ public Optional findBySwitchIdAndLogicalPortNumber(SwitchId switchI .has(LacpPartnerFrame.SWITCH_ID_PROPERTY, SwitchIdConverter.INSTANCE.toGraphProperty(switchId)) .has(LacpPartnerFrame.LOGICAL_PORT_NUMBER_PROPERTY, logicalPortNumber)) .toListExplicit(LacpPartnerFrame.class); + if (lacpPartnerFrames.size() > 1) { + log.error(String.format("More then one LACP status fields for switch %s on port %s", + switchId, logicalPortNumber)); + } + return lacpPartnerFrames.isEmpty() ? Optional.empty() : Optional.of(lacpPartnerFrames.get(0)) .map(LacpPartner::new); } diff --git a/src-java/kilda-persistence-tinkerpop/src/test/java/org/openkilda/persistence/ferma/repositories/FermaLacpPartnerRepositoryTest.java b/src-java/kilda-persistence-tinkerpop/src/test/java/org/openkilda/persistence/ferma/repositories/FermaLacpPartnerRepositoryTest.java index 5c4f0e37dc3..bb5141e53f9 100644 --- a/src-java/kilda-persistence-tinkerpop/src/test/java/org/openkilda/persistence/ferma/repositories/FermaLacpPartnerRepositoryTest.java +++ b/src-java/kilda-persistence-tinkerpop/src/test/java/org/openkilda/persistence/ferma/repositories/FermaLacpPartnerRepositoryTest.java @@ -1,4 +1,4 @@ -/* Copyright 2021 Telstra Open Source +/* Copyright 2023 Telstra Open Source * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/request/GetLacpStatusRequest.java b/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/request/GetLacpStatusRequest.java index 7185059672b..285f988936a 100644 --- a/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/request/GetLacpStatusRequest.java +++ b/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/request/GetLacpStatusRequest.java @@ -1,4 +1,4 @@ -/* Copyright 2022 Telstra Open Source +/* Copyright 2023 Telstra Open Source * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/request/GetSwitchLacpStatusRequest.java b/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/request/GetSwitchLacpStatusRequest.java index 7f2b5fed1ad..d3091a85263 100644 --- a/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/request/GetSwitchLacpStatusRequest.java +++ b/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/request/GetSwitchLacpStatusRequest.java @@ -1,4 +1,4 @@ -/* Copyright 2022 Telstra Open Source +/* Copyright 2023 Telstra Open Source * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/response/LacpStatusDto.java b/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/response/LacpStatusDto.java index 4df9f136598..622a1fd68ee 100644 --- a/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/response/LacpStatusDto.java +++ b/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/response/LacpStatusDto.java @@ -1,4 +1,4 @@ -/* Copyright 2022 Telstra Open Source +/* Copyright 2023 Telstra Open Source * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/response/SwitchLacpStatusResponse.java b/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/response/SwitchLacpStatusResponse.java index e7d68d77872..d61efd03d5f 100644 --- a/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/response/SwitchLacpStatusResponse.java +++ b/src-java/nbworker-topology/nbworker-messaging/src/main/java/org/openkilda/messaging/nbtopology/response/SwitchLacpStatusResponse.java @@ -1,4 +1,4 @@ -/* Copyright 2022 Telstra Open Source +/* Copyright 2023 Telstra Open Source * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/share/mappers/LacpStatusMapper.java b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/share/mappers/LacpStatusMapper.java index 9f16c84c6c5..ab1de7a3b29 100644 --- a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/share/mappers/LacpStatusMapper.java +++ b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/share/mappers/LacpStatusMapper.java @@ -1,4 +1,4 @@ -/* Copyright 2022 Telstra Open Source +/* Copyright 2023 Telstra Open Source * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/services/SwitchOperationsService.java b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/services/SwitchOperationsService.java index 73be8b46166..1aeaf2ea47f 100644 --- a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/services/SwitchOperationsService.java +++ b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/services/SwitchOperationsService.java @@ -446,9 +446,9 @@ private void validateSwitchProperties(SwitchId switchId, SwitchProperties update if (!flowsWitchEnabledLldp.isEmpty()) { throw new IllegalSwitchPropertiesException( format("Illegal switch properties combination for switch %s. " - + "Detect Connected Devices feature is turn on for following flows [%s]. " - + "For correct work of this feature switch property 'multiTable' must be set to 'true' " - + "Please disable detecting of connected devices via LLDP for each flow before set " + + "Detect Connected Devices feature via LLDP is turned on for following flows [%s]." + + "For correct work of this feature, switch property 'multiTable' must be set to 'true' " + + "Please disable detecting of connected devices via LLDP for each flow before setting " + "'multiTable' property to 'false'", switchId, String.join(", ", flowsWitchEnabledLldp))); } diff --git a/src-java/northbound-service/northbound-api/src/main/java/org/openkilda/northbound/dto/v2/switches/LacpStatusResponse.java b/src-java/northbound-service/northbound-api/src/main/java/org/openkilda/northbound/dto/v2/switches/LacpStatusResponse.java index 5c4d0a6a1bb..7f4414c35f2 100644 --- a/src-java/northbound-service/northbound-api/src/main/java/org/openkilda/northbound/dto/v2/switches/LacpStatusResponse.java +++ b/src-java/northbound-service/northbound-api/src/main/java/org/openkilda/northbound/dto/v2/switches/LacpStatusResponse.java @@ -1,4 +1,4 @@ -/* Copyright 2022 Telstra Open Source +/* Copyright 2023 Telstra Open Source * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/controller/v2/SwitchControllerV2.java b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/controller/v2/SwitchControllerV2.java index 99f3a41f176..8da79bfd07c 100644 --- a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/controller/v2/SwitchControllerV2.java +++ b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/controller/v2/SwitchControllerV2.java @@ -221,7 +221,8 @@ public CompletableFuture> getLagPorts(@PathVariable("switc * * @param switchId the switch */ - @ApiOperation(value = "Read all LACP status on specific switch", response = LacpStatusResponse.class) + @ApiOperation(value = "Read all LACP status values/fields, on a specific switch", + response = LacpStatusResponse.class) @GetMapping(value = "/{switch_id}/lacpstatus") @ResponseStatus(HttpStatus.OK) public CompletableFuture> getLacpStatus(@PathVariable("switch_id") SwitchId switchId) { @@ -235,7 +236,8 @@ public CompletableFuture> getLacpStatus(@PathVariable(" * @param logicalPortNumber the switch * */ - @ApiOperation(value = "Read LACP status on specific port of the switch", response = LacpStatusResponse.class) + @ApiOperation(value = "Read LACP status values/fields, on a specific port of the switch", + response = LacpStatusResponse.class) @GetMapping(value = "/{switch_id}/lacp/{logical_port_number}") @ResponseStatus(HttpStatus.OK) public CompletableFuture getLacpStatus(@PathVariable("switch_id") SwitchId switchId, diff --git a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/converter/LacpStatusMapper.java b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/converter/LacpStatusMapper.java index 9ffe1885922..91a242da12c 100644 --- a/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/converter/LacpStatusMapper.java +++ b/src-java/northbound-service/northbound/src/main/java/org/openkilda/northbound/converter/LacpStatusMapper.java @@ -1,4 +1,4 @@ -/* Copyright 2022 Telstra Open Source +/* Copyright 2023 Telstra Open Source * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 0185f4a76a085930ebf0b3e617ba1674280ecc15 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 1 Feb 2023 09:21:44 +0000 Subject: [PATCH 8/9] #4964 LACP status - Updated based on review comments --- .../wfm/topology/nbworker/bolts/SwitchOperationsBolt.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/bolts/SwitchOperationsBolt.java b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/bolts/SwitchOperationsBolt.java index 4072ba9d1ba..ba5c1db4661 100644 --- a/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/bolts/SwitchOperationsBolt.java +++ b/src-java/nbworker-topology/nbworker-storm-topology/src/main/java/org/openkilda/wfm/topology/nbworker/bolts/SwitchOperationsBolt.java @@ -338,7 +338,7 @@ private List getSwitchLacpStatus(GetSwitchLacpStatusRe .collect(Collectors.toList()); } catch (SwitchNotFoundException e) { throw new MessageException(ErrorType.NOT_FOUND, e.getMessage(), - "Could not get LACP Status for non existent switch"); + "Could not get LACP Status for non-existent switch"); } } From a153cf453f132b0e223a25c57a855038bb3ee5e2 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 6 Feb 2023 22:12:46 +0000 Subject: [PATCH 9/9] Renamed Migration Files --- ...-lacp-partner-class.yaml => 024-add-lacp-partner-class.yaml} | 2 +- docker/db-migration/migrations/root.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename docker/db-migration/migrations/{025-add-lacp-partner-class.yaml => 024-add-lacp-partner-class.yaml} (97%) diff --git a/docker/db-migration/migrations/025-add-lacp-partner-class.yaml b/docker/db-migration/migrations/024-add-lacp-partner-class.yaml similarity index 97% rename from docker/db-migration/migrations/025-add-lacp-partner-class.yaml rename to docker/db-migration/migrations/024-add-lacp-partner-class.yaml index fd3aaae5901..8429ef35bc8 100644 --- a/docker/db-migration/migrations/025-add-lacp-partner-class.yaml +++ b/docker/db-migration/migrations/024-add-lacp-partner-class.yaml @@ -4,7 +4,7 @@ databaseChangeLog: author: dkakollu changes: - tagDatabase: - tag: 025-add-lacp-partner-class + tag: 024-add-lacp-partner-class - changeSet: id: add-lacp-partner-class diff --git a/docker/db-migration/migrations/root.yaml b/docker/db-migration/migrations/root.yaml index 73169497682..acb36b16712 100644 --- a/docker/db-migration/migrations/root.yaml +++ b/docker/db-migration/migrations/root.yaml @@ -83,4 +83,4 @@ databaseChangeLog: file: 023-add-lacp-reply-into-lag-class.yaml - include: relativeToChangelogFile: true - file: 025-add-lacp-partner-class.yaml + file: 024-add-lacp-partner-class.yaml