Break out more FRM components 84/110184/4
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 7 Feb 2024 13:28:08 +0000 (14:28 +0100)
committerRobert Varga <robert.varga@pantheon.tech>
Thu, 8 Feb 2024 11:00:53 +0000 (12:00 +0100)
We have various bits of wiring which can easily be catered to by OSGi
DS. Break them out of the blueprint container.

JIRA: OPNFLWPLUG-1112
Change-Id: I226f7436c5f7aedcd456deb9d719ab0dfc5be508
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/ReconciliationJMXAgent.java
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/ReconciliationJMXService.java
applications/forwardingrules-manager/src/main/java/org/opendaylight/openflowplugin/applications/frm/recovery/impl/OpenflowServiceRecoveryHandlerImpl.java
applications/forwardingrules-manager/src/main/resources/OSGI-INF/blueprint/forwardingrules-manager.xml
openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/services/cache/FlowGroupCacheManagerImpl.java
openflowplugin-impl/src/main/resources/OSGI-INF/blueprint/openflowplugin-impl.xml

index 2cb492cace665216a27d144e4a8b0f8aa168c3c6..1b86ef9c9e33601c3b5c5c47d8f5e5bf2014c897 100644 (file)
@@ -9,43 +9,68 @@
 package org.opendaylight.openflowplugin.applications.frm;
 
 import java.lang.management.ManagementFactory;
+import javax.annotation.PreDestroy;
 import javax.inject.Inject;
+import javax.inject.Singleton;
 import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
 import javax.management.MBeanRegistrationException;
 import javax.management.MBeanServer;
 import javax.management.MalformedObjectNameException;
 import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectInstance;
 import javax.management.ObjectName;
+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 final class ReconciliationJMXAgent {
+@Singleton
+@Component(service = { })
+public final class ReconciliationJMXAgent implements AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(ReconciliationJMXAgent.class);
-    private static final String OF_RECONC_BEANNAME
-            = "org.opendaylight.openflowplugin.frm:type=ReconciliationState";
-    private MBeanServer mbs = null;
-    private ObjectName objectName = null;
+    private static final ObjectName OF_RECONF_OBJNAME;
 
-    @Inject
-    public ReconciliationJMXAgent(final ReconciliationJMXService reconciliationJMXService) {
-        mbs = ManagementFactory.getPlatformMBeanServer();
+    static {
         try {
-            objectName = new ObjectName(OF_RECONC_BEANNAME);
-            registerReconciliationMbean(reconciliationJMXService);
+            OF_RECONF_OBJNAME = new ObjectName("org.opendaylight.openflowplugin.frm:type=ReconciliationState");
         } catch (MalformedObjectNameException e) {
-            LOG.error("ObjectName instance creation failed for Mbean {} : ", OF_RECONC_BEANNAME, e);
+            throw new ExceptionInInitializerError(e);
         }
     }
 
-    public void registerReconciliationMbean(ReconciliationJMXService reconciliationJMXService) {
-        try {
-            // Uniquely identify the MBeans and register them with the platform MBeanServer
-            if (!mbs.isRegistered(objectName)) {
-                mbs.registerMBean(reconciliationJMXService, objectName);
-                LOG.debug("Registered Mbean {} successfully", OF_RECONC_BEANNAME);
+    private final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+    private ObjectInstance objInstance;
+
+    @Inject
+    @Activate
+    public ReconciliationJMXAgent(@Reference final ReconciliationJMXServiceMBean reconciliationJMXService) {
+        // Uniquely identify the MBeans and register them with the platform MBeanServer
+        ObjectInstance inst = null;
+        if (!mbs.isRegistered(OF_RECONF_OBJNAME)) {
+            try {
+                inst = mbs.registerMBean(reconciliationJMXService, OF_RECONF_OBJNAME);
+                LOG.debug("Registered Mbean {} successfully", OF_RECONF_OBJNAME);
+            } catch (InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException e) {
+                LOG.warn("Registeration failed for Mbean {} : ", OF_RECONF_OBJNAME , e);
+            }
+        }
+        objInstance = inst;
+    }
+
+    @PreDestroy
+    @Deactivate
+    @Override
+    public void close() {
+        if (objInstance != null) {
+            objInstance = null;
+            try {
+                mbs.unregisterMBean(OF_RECONF_OBJNAME);
+            } catch (MBeanRegistrationException | InstanceNotFoundException e) {
+                LOG.warn("Unregistration failed for Mbean {} : ", OF_RECONF_OBJNAME , e);
             }
-        } catch (MBeanRegistrationException | InstanceAlreadyExistsException | NotCompliantMBeanException e) {
-            LOG.error("Registeration failed for Mbean {} : ", OF_RECONC_BEANNAME , e);
         }
     }
 }
index 67c33d09e8e01af84cdd2a5323ab5b017df8a234..0002871a4e8a03965b087c0374c9627a724c203a 100644 (file)
@@ -5,27 +5,34 @@
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
-
 package org.opendaylight.openflowplugin.applications.frm;
 
-import java.util.HashMap;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.Maps;
 import java.util.Map;
 import javax.inject.Inject;
+import javax.inject.Singleton;
 import org.opendaylight.openflowplugin.api.openflow.FlowGroupCacheManager;
+import org.opendaylight.openflowplugin.api.openflow.ReconciliationState;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
 
-public class ReconciliationJMXService implements ReconciliationJMXServiceMBean {
-    private FlowGroupCacheManager flowGroupCacheManager;
+@Singleton
+@Component
+public final class ReconciliationJMXService implements ReconciliationJMXServiceMBean {
+    private final FlowGroupCacheManager flowGroupCacheManager;
 
     @Inject
-    public ReconciliationJMXService(final FlowGroupCacheManager floGroupCacheManager) {
-        this.flowGroupCacheManager = floGroupCacheManager;
+    @Activate
+    public ReconciliationJMXService(@Reference final FlowGroupCacheManager floGroupCacheManager) {
+        flowGroupCacheManager = requireNonNull(floGroupCacheManager);
     }
 
     @Override
     public Map<String, String> acquireReconciliationStates() {
-        Map<String, String> reconciliationStatesMap = new HashMap<>();
-        flowGroupCacheManager.getReconciliationStates().forEach((datapathId, reconciliationState) ->
-                reconciliationStatesMap.put(datapathId, reconciliationState.toString()));
-        return reconciliationStatesMap;
+        return Map.copyOf(Maps.transformValues(flowGroupCacheManager.getReconciliationStates(),
+            ReconciliationState::toString));
     }
 }
index a6e16c6bd6e87c4fe44c4bf5637274a35f282496..15cb35a5413e5701f1ed087ccd2cc3bcc8aba9fc 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.openflowplugin.applications.frm.recovery.impl;
 
+import static java.util.Objects.requireNonNull;
+
 import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.opendaylight.openflowplugin.applications.frm.recovery.OpenflowServiceRecoveryHandler;
@@ -14,40 +16,37 @@ import org.opendaylight.serviceutils.srm.RecoverableListener;
 import org.opendaylight.serviceutils.srm.ServiceRecoveryInterface;
 import org.opendaylight.serviceutils.srm.ServiceRecoveryRegistry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.serviceutils.srm.types.rev180626.Ofplugin;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Singleton
-public final class OpenflowServiceRecoveryHandlerImpl implements ServiceRecoveryInterface,
-        OpenflowServiceRecoveryHandler {
-
+@Component(service = OpenflowServiceRecoveryHandler.class, immediate = true)
+public final class OpenflowServiceRecoveryHandlerImpl
+        implements ServiceRecoveryInterface, OpenflowServiceRecoveryHandler {
     private static final Logger LOG = LoggerFactory.getLogger(OpenflowServiceRecoveryHandlerImpl.class);
 
     private final ServiceRecoveryRegistry serviceRecoveryRegistry;
 
     @Inject
-    public OpenflowServiceRecoveryHandlerImpl(final ServiceRecoveryRegistry serviceRecoveryRegistry) {
+    @Activate
+    public OpenflowServiceRecoveryHandlerImpl(@Reference final ServiceRecoveryRegistry serviceRecoveryRegistry) {
+        this.serviceRecoveryRegistry = requireNonNull(serviceRecoveryRegistry);
+        // FIXME: how can we undo this registration?
         LOG.info("Registering openflowplugin service recovery handlers");
-        this.serviceRecoveryRegistry = serviceRecoveryRegistry;
         serviceRecoveryRegistry.registerServiceRecoveryRegistry(buildServiceRegistryKey(), this);
     }
 
-    private void deregisterListeners() {
-        serviceRecoveryRegistry.getRecoverableListeners(buildServiceRegistryKey())
-                .forEach(RecoverableListener::deregisterListener);
-    }
-
-    private void registerListeners() {
-        serviceRecoveryRegistry.getRecoverableListeners(buildServiceRegistryKey())
-                .forEach(RecoverableListener::registerListener);
-    }
-
     @Override
     public void recoverService(final String entityId) {
         LOG.info("Recover Openflowplugin service by deregistering and registering all relevant listeners");
-        deregisterListeners();
-        //FIXME: device group registry cache to be cleared before starting the listeners
-        registerListeners();
+        serviceRecoveryRegistry.getRecoverableListeners(buildServiceRegistryKey())
+            .forEach(RecoverableListener::deregisterListener);
+        // FIXME: device group registry cache to be cleared before starting the listeners
+        serviceRecoveryRegistry.getRecoverableListeners(buildServiceRegistryKey())
+            .forEach(RecoverableListener::registerListener);
     }
 
     @Override
index 310f57ee50e09e69d1f509ff1fc66f0ac98a6978..e0b9ec028b5e2ffe79fd6b4d20393e9fc35a43d5 100644 (file)
@@ -9,18 +9,6 @@
   <service ref="frmReconciliationServiceImpl"
            interface="org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.app.frm.reconciliation.service.rev180227.FrmReconciliationService"/>
 
-  <bean id="reconciliationJMXServiceMBean"
-        class="org.opendaylight.openflowplugin.applications.frm.ReconciliationJMXService">
-    <argument ref="flowGroupCacheManager"/>
-  </bean>
-  <service ref="reconciliationJMXServiceMBean"
-           interface="org.opendaylight.openflowplugin.applications.frm.ReconciliationJMXServiceMBean"/>
-
-  <bean id="reconciliationJMXAgent"
-        class="org.opendaylight.openflowplugin.applications.frm.ReconciliationJMXAgent">
-    <argument ref="reconciliationJMXService"/>
-  </bean>
-
   <bean id="forwardingRulesManagerImpl"
         class="org.opendaylight.openflowplugin.applications.frm.impl.ForwardingRulesManagerImpl"
         init-method="start"
@@ -33,7 +21,7 @@
     <argument ref="clusterSingletonServiceProvider"/>
     <argument ref="configurationService"/>
     <argument ref="reconciliationManager"/>
-    <argument ref="openflowServiceRecoveryHandlerImpl"/>
+    <argument ref="openflowServiceRecoveryHandler"/>
     <argument ref="serviceRecoveryRegistry"/>
     <argument ref="flowGroupCacheManager"/>
     <argument ref="listenerRegistrationHelper"/>
   <odl:clustered-app-config id="forwardingRulesManagerConfig"
                             binding-class="org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.app.forwardingrules.manager.config.rev160511.ForwardingRulesManagerConfig"/>
 
-  <bean id="openflowServiceRecoveryHandlerImpl"
-        class="org.opendaylight.openflowplugin.applications.frm.recovery.impl.OpenflowServiceRecoveryHandlerImpl">
-    <argument ref="serviceRecoveryRegistry"/>
-  </bean>
-  <service ref="openflowServiceRecoveryHandlerImpl"
-           interface="org.opendaylight.openflowplugin.applications.frm.recovery.OpenflowServiceRecoveryHandler"/>
-
-  <bean id="reconciliationJMXService"
-        class="org.opendaylight.openflowplugin.applications.frm.ReconciliationJMXService">
-    <argument ref="flowGroupCacheManager"/>
-  </bean>
-
   <reference id="flowGroupCacheManager"
              interface="org.opendaylight.openflowplugin.api.openflow.FlowGroupCacheManager"/>
   <reference id="dataBroker"
@@ -74,4 +50,6 @@
              interface="org.opendaylight.serviceutils.srm.ServiceRecoveryRegistry"/>
   <reference id="listenerRegistrationHelper"
              interface="org.opendaylight.openflowplugin.applications.frm.impl.ListenerRegistrationHelper"/>
+  <reference id="openflowServiceRecoveryHandler"
+             interface="org.opendaylight.openflowplugin.applications.frm.recovery.OpenflowServiceRecoveryHandler"/>
 </blueprint>
index 38f4df09cfb0c20f088e057a3bb0d9645733e7ad..0b1774b5c151951b850fcfdce7a65d94a33dae49 100644 (file)
@@ -9,13 +9,24 @@ package org.opendaylight.openflowplugin.impl.services.cache;
 
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.opendaylight.openflowplugin.api.openflow.FlowGroupCacheManager;
 import org.opendaylight.openflowplugin.api.openflow.ReconciliationState;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
 
 @Singleton
+@Component
 public class FlowGroupCacheManagerImpl implements FlowGroupCacheManager {
-    private final Map<String, ReconciliationState> reconciliationStates = new ConcurrentHashMap<>();
+    private final ConcurrentMap<String, ReconciliationState> reconciliationStates = new ConcurrentHashMap<>();
+
+    @Inject
+    @Activate
+    public FlowGroupCacheManagerImpl() {
+        // Exposed for DI
+    }
 
     @Override
     public Map<String, ReconciliationState> getReconciliationStates() {
index 38a9d19b6407a83f00440ffb9e5320b7c2649952..94c1a25a48669f596ac9f1f5d3f8f8e11bc8f598 100644 (file)
     </interfaces>
   </service>
 
-  <bean id="flowGroupCacheManagerImpl"
-        class="org.opendaylight.openflowplugin.impl.services.cache.FlowGroupCacheManagerImpl"/>
-  <service ref="flowGroupCacheManagerImpl"
-           interface="org.opendaylight.openflowplugin.api.openflow.FlowGroupCacheManager"/>
-
   <bean id="configurationService"
         factory-ref="configurationServiceFactory"
         factory-method="newInstance"