Ditch blueprint from table-miss-enforcer 74/110174/1
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 7 Feb 2024 09:29:16 +0000 (10:29 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Wed, 7 Feb 2024 09:31:24 +0000 (10:31 +0100)
This again is a very simple AddFlow-based application, use
annotation-driven activation.

JIRA: OPNFLWPLUG-1112
Change-Id: If994133803cc60020e0fde38f33a15b67c4a5c66
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
applications/table-miss-enforcer/pom.xml
applications/table-miss-enforcer/src/main/java/org/opendaylight/openflowplugin/applications/tablemissenforcer/LLDPPacketPuntEnforcer.java
applications/table-miss-enforcer/src/main/resources/OSGI-INF/blueprint/table-miss-enforcer.xml [deleted file]
applications/table-miss-enforcer/src/test/java/org/opendaylight/openflowplugin/applications/tablemissenforcer/LLDPDataTreeChangeListenerTest.java

index 763bf3623ed43cff6559fc3d38c1274a97dc7f78..d474cf54d76a8ac55a50e7aadfd0785dd63e7011 100644 (file)
@@ -1,46 +1,55 @@
 <?xml version="1.0"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  <parent>
-    <groupId>org.opendaylight.openflowplugin</groupId>
-    <artifactId>openflowplugin-parent</artifactId>
-    <version>0.18.0-SNAPSHOT</version>
-    <relativePath>../../parent</relativePath>
-  </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.openflowplugin</groupId>
+        <artifactId>openflowplugin-parent</artifactId>
+        <version>0.18.0-SNAPSHOT</version>
+        <relativePath>../../parent</relativePath>
+    </parent>
 
-  <groupId>org.opendaylight.openflowplugin.applications</groupId>
-  <artifactId>table-miss-enforcer</artifactId>
-  <packaging>bundle</packaging>
+    <groupId>org.opendaylight.openflowplugin.applications</groupId>
+    <artifactId>table-miss-enforcer</artifactId>
+    <packaging>bundle</packaging>
 
-  <dependencies>
-      <dependency>
-          <groupId>org.opendaylight.openflowplugin</groupId>
-          <artifactId>openflowplugin-api</artifactId>
-      </dependency>
-      <dependency>
-          <groupId>org.opendaylight.openflowplugin</groupId>
-          <artifactId>openflowplugin-common</artifactId>
-      </dependency>
-
-      <dependency>
-          <groupId>org.opendaylight.mdsal</groupId>
-          <artifactId>mdsal-binding-api</artifactId>
-      </dependency>
-      <dependency>
-          <groupId>org.opendaylight.openflowplugin.model</groupId>
-          <artifactId>model-inventory</artifactId>
-      </dependency>
-      <dependency>
-          <groupId>org.opendaylight.openflowplugin.model</groupId>
-          <artifactId>model-flow-service</artifactId>
-      </dependency>
-      <dependency>
-          <groupId>org.opendaylight.infrautils</groupId>
-          <artifactId>infrautils-util</artifactId>
-      </dependency>
-      <dependency>
-          <groupId>org.opendaylight.openflowplugin.applications</groupId>
-          <artifactId>device-ownership-service</artifactId>
-      </dependency>
-  </dependencies>
+    <dependencies>
+        <dependency>
+            <groupId>com.guicedee.services</groupId>
+            <artifactId>javax.inject</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>jakarta.annotation</groupId>
+            <artifactId>jakarta.annotation-api</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.infrautils</groupId>
+            <artifactId>infrautils-util</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>mdsal-binding-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin</groupId>
+            <artifactId>openflowplugin-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin.applications</groupId>
+            <artifactId>device-ownership-service</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin.model</groupId>
+            <artifactId>model-inventory</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.openflowplugin.model</groupId>
+            <artifactId>model-flow-service</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.component.annotations</artifactId>
+        </dependency>
+    </dependencies>
 </project>
index b9bd16d3e26708216131f0a254161bc9ed747976..f628621cdea806d12e4677ffbc06a52bb0f78225 100644 (file)
@@ -10,12 +10,16 @@ package org.opendaylight.openflowplugin.applications.tablemissenforcer;
 import static java.util.Objects.requireNonNull;
 
 import java.util.Collection;
+import javax.annotation.PreDestroy;
+import javax.inject.Inject;
+import javax.inject.Singleton;
 import org.opendaylight.infrautils.utils.concurrent.LoggingFutures;
 import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener;
 import org.opendaylight.mdsal.binding.api.DataBroker;
 import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType;
 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
 import org.opendaylight.mdsal.binding.api.DataTreeModification;
+import org.opendaylight.mdsal.binding.api.RpcConsumerRegistry;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.openflowplugin.api.OFConstants;
 import org.opendaylight.openflowplugin.applications.deviceownershipservice.DeviceOwnershipService;
@@ -28,8 +32,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.Fl
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.OutputPortValues;
@@ -47,52 +51,56 @@ import org.opendaylight.yangtools.yang.binding.util.BindingMap;
 import org.opendaylight.yangtools.yang.common.Uint16;
 import org.opendaylight.yangtools.yang.common.Uint64;
 import org.opendaylight.yangtools.yang.common.Uint8;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+import org.osgi.service.component.annotations.Reference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class LLDPPacketPuntEnforcer implements AutoCloseable, ClusteredDataTreeChangeListener<FlowCapableNode> {
+@Singleton
+@Component(service = { })
+public final class LLDPPacketPuntEnforcer implements AutoCloseable, ClusteredDataTreeChangeListener<FlowCapableNode> {
     private static final Logger LOG = LoggerFactory.getLogger(LLDPPacketPuntEnforcer.class);
     private static final Uint8 TABLE_ID = Uint8.ZERO;
     private static final String LLDP_PUNT_WHOLE_PACKET_FLOW = "LLDP_PUNT_WHOLE_PACKET_FLOW";
     private static final String DEFAULT_FLOW_ID = "42";
 
-    private final SalFlowService flowService;
-    private final DataBroker dataBroker;
     private final DeviceOwnershipService deviceOwnershipService;
-    private Registration listenerRegistration;
+    private final Registration listenerRegistration;
+    private final AddFlow addFlow;
 
-    public LLDPPacketPuntEnforcer(final SalFlowService flowService, final DataBroker dataBroker,
-            final DeviceOwnershipService deviceOwnershipService) {
-        this.flowService = flowService;
-        this.dataBroker = dataBroker;
-        this.deviceOwnershipService = requireNonNull(deviceOwnershipService, "DeviceOwnershipService can not be null");
-    }
-
-    public void start() {
+    @Inject
+    @Activate
+    public LLDPPacketPuntEnforcer(@Reference final DataBroker dataBroker,
+            @Reference final DeviceOwnershipService deviceOwnershipService,
+            @Reference final RpcConsumerRegistry rpcService) {
+        this.deviceOwnershipService = requireNonNull(deviceOwnershipService);
+        addFlow = rpcService.getRpc(AddFlow.class);
         listenerRegistration = dataBroker.registerDataTreeChangeListener(
             DataTreeIdentifier.create(LogicalDatastoreType.OPERATIONAL,
                 InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class)),
             this);
     }
 
+    @PreDestroy
+    @Deactivate
     @Override
     public void close() {
-        if (listenerRegistration != null) {
-            listenerRegistration.close();
-        }
+        listenerRegistration.close();
     }
 
     @Override
     public void onDataTreeChanged(final Collection<DataTreeModification<FlowCapableNode>> modifications) {
-        for (DataTreeModification<FlowCapableNode> modification : modifications) {
+        for (var modification : modifications) {
             if (modification.getRootNode().getModificationType() == ModificationType.WRITE) {
-                String nodeId = modification.getRootPath().getRootIdentifier()
+                final var nodeId = modification.getRootPath().getRootIdentifier()
                         .firstKeyOf(Node.class).getId().getValue();
                 if (deviceOwnershipService.isEntityOwned(nodeId)) {
-                    AddFlowInputBuilder addFlowInput = new AddFlowInputBuilder(createFlow());
-                    addFlowInput.setNode(new NodeRef(modification.getRootPath()
-                            .getRootIdentifier().firstIdentifierOf(Node.class)));
-                    LoggingFutures.addErrorLogging(flowService.addFlow(addFlowInput.build()), LOG, "addFlow");
+                    LoggingFutures.addErrorLogging(addFlow.invoke(new AddFlowInputBuilder(createFlow())
+                        .setNode(new NodeRef(modification.getRootPath()
+                            .getRootIdentifier().firstIdentifierOf(Node.class)))
+                        .build()), LOG, "addFlow");
                 } else {
                     LOG.debug("Node {} is not owned by this controller, so skip adding LLDP table miss flow", nodeId);
                 }
diff --git a/applications/table-miss-enforcer/src/main/resources/OSGI-INF/blueprint/table-miss-enforcer.xml b/applications/table-miss-enforcer/src/main/resources/OSGI-INF/blueprint/table-miss-enforcer.xml
deleted file mode 100644 (file)
index dee7a07..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
-           xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
-           odl:use-default-for-reference-types="true">
-
-  <reference id="dataBroker" interface="org.opendaylight.mdsal.binding.api.DataBroker"/>
-  <reference id="deviceOwnershipService" interface="org.opendaylight.openflowplugin.applications.deviceownershipservice.DeviceOwnershipService"/>
-
-  <odl:rpc-service id="flowService" interface="org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService"/>
-
-  <bean id="LLDPPacketPuntEnforcer" class="org.opendaylight.openflowplugin.applications.tablemissenforcer.LLDPPacketPuntEnforcer"
-          init-method="start" destroy-method="close">
-    <argument ref="flowService"/>
-    <argument ref="dataBroker"/>
-    <argument ref="deviceOwnershipService"/>
-  </bean>
-</blueprint>
index 2589ba7238536bb2ec1bad5598674bb28e428eb3..5507eea97669c0d4b55507e7884f1a40cb25b808 100644 (file)
@@ -32,14 +32,15 @@ import org.opendaylight.mdsal.binding.api.DataObjectModification;
 import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType;
 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
 import org.opendaylight.mdsal.binding.api.DataTreeModification;
+import org.opendaylight.mdsal.binding.api.RpcConsumerRegistry;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.openflowplugin.applications.deviceownershipservice.DeviceOwnershipService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlow;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
@@ -48,6 +49,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.common.Uint16;
@@ -57,11 +59,16 @@ import org.opendaylight.yangtools.yang.common.Uint16;
  */
 @RunWith(MockitoJUnitRunner.class)
 public class LLDPDataTreeChangeListenerTest {
-    private LLDPPacketPuntEnforcer lldpPacketPuntEnforcer;
     private static final InstanceIdentifier<Node> NODE_IID = InstanceIdentifier.create(Nodes.class)
             .child(Node.class, new NodeKey(new NodeId("testnode:1")));
     @Mock
-    private SalFlowService flowService;
+    private DataBroker dataBroker;
+    @Mock
+    private ListenerRegistration<?> reg;
+    @Mock
+    private RpcConsumerRegistry rpcService;
+    @Mock
+    private AddFlow addFlow;
     @Mock
     private DataTreeModification<FlowCapableNode> dataTreeModification;
     @Mock
@@ -69,11 +76,14 @@ public class LLDPDataTreeChangeListenerTest {
     @Captor
     private ArgumentCaptor<AddFlowInput> addFlowInputCaptor;
 
+    private LLDPPacketPuntEnforcer lldpPacketPuntEnforcer;
+
     @Before
     public void setUp() {
-        doReturn(RpcResultBuilder.success().buildFuture()).when(flowService).addFlow(any());
-        lldpPacketPuntEnforcer = new LLDPPacketPuntEnforcer(flowService, mock(DataBroker.class),
-                deviceOwnershipService);
+        doReturn(reg).when(dataBroker).registerDataTreeChangeListener(any(), any());
+        doReturn(RpcResultBuilder.success().buildFuture()).when(addFlow).invoke(any());
+        doReturn(addFlow).when(rpcService).getRpc(any());
+        lldpPacketPuntEnforcer = new LLDPPacketPuntEnforcer(dataBroker, deviceOwnershipService, rpcService);
         final DataTreeIdentifier<FlowCapableNode> identifier = DataTreeIdentifier.create(
                 LogicalDatastoreType.OPERATIONAL, NODE_IID.augmentation(FlowCapableNode.class));
         when(dataTreeModification.getRootPath()).thenReturn(identifier);
@@ -90,7 +100,7 @@ public class LLDPDataTreeChangeListenerTest {
     @Test
     public void testOnDataTreeChanged() {
         lldpPacketPuntEnforcer.onDataTreeChanged(Collections.singleton(dataTreeModification));
-        verify(flowService).addFlow(addFlowInputCaptor.capture());
+        verify(addFlow).invoke(addFlowInputCaptor.capture());
         AddFlowInput captured = addFlowInputCaptor.getValue();
         assertEquals(NODE_IID, captured.getNode().getValue());
     }