Refactor MD-SAL listener classes. 24/17924/1
authorShigeru Yasuda <s-yasuda@da.jp.nec.com>
Wed, 8 Apr 2015 13:51:44 +0000 (22:51 +0900)
committerShigeru Yasuda <s-yasuda@da.jp.nec.com>
Wed, 8 Apr 2015 13:52:11 +0000 (22:52 +0900)
  * Data change listener and notificaiton listener can keep more than
    one auto-closeables.

Change-Id: Ia7100974d382fb9ac35d7257b9a50dd5fab79034
Signed-off-by: Shigeru Yasuda <s-yasuda@da.jp.nec.com>
16 files changed:
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/config/ConfigListener.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/config/OperationalListener.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/flow/cond/FlowCondManager.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/inventory/NodeConnectorListener.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/inventory/NodeListener.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/inventory/TopologyListener.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/inventory/VTNInventoryManager.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/packet/VTNPacketService.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/PathMapManager.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/PathPolicyListener.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/VTNRoutingManager.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/util/AbstractDataChangeListener.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/util/CloseableContainer.java [new file with mode: 0644]
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/util/SalNotificationListener.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/vnode/VTenantManager.java
manager/implementation/src/test/java/org/opendaylight/vtn/manager/internal/util/SalNotificationListenerTest.java

index 7e35a5e8adea6967b25a2356cc5212dc33f63d7f..6ed187c1aa4e14694a5d951f7ca48e156b035bd2 100644 (file)
@@ -222,6 +222,8 @@ public final class ConfigListener extends DataStoreListener<VtnConfig, Void> {
         return VTNConfigManager.CONFIG_IDENT;
     }
 
+    // CloseableContainer
+
     /**
      * {@inheritDoc}
      */
index 5711b14cb283cacaf32e609cc6ef495c6db51ca3..51f0b0225a163961eae258638058a3be12a16ffa 100644 (file)
@@ -174,6 +174,8 @@ public final class OperationalListener
         return VTNConfigManager.CONFIG_IDENT;
     }
 
+    // CloseableContainer
+
     /**
      * {@inheritDoc}
      */
index f8a1add73f518c59ef93479dd6ec46cf2d462f59..5227414bcdc335ec5c66a772c571cc34d7cd9703 100644 (file)
@@ -361,6 +361,8 @@ public final class FlowCondManager
             child(VtnFlowCondition.class).build();
     }
 
+    // CloseableContainer
+
     /**
      * {@inheritDoc}
      */
index 98d1d2a24ba1a3802341579ef5fda092434317f0..8b239fdf100cee8ad8e375d6b9d8f0c12633f35a 100644 (file)
@@ -144,6 +144,8 @@ public final class NodeConnectorListener
             augmentation(FlowCapableNodeConnector.class).build();
     }
 
+    // CloseableContainer
+
     /**
      * {@inheritDoc}
      */
index 3fe4780820732187344b1f7090bccded25c2ade1..5351b46acc03479018aa598634b4f195796c6243 100644 (file)
@@ -227,14 +227,6 @@ public final class NodeListener
             augmentation(FlowCapableNode.class).build();
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected Logger getLogger() {
-        return LOG;
-    }
-
     /**
      * Return a set of {@link VtnUpdateType} instances that specifies
      * event types to be listened.
@@ -245,4 +237,14 @@ public final class NodeListener
     protected Set<VtnUpdateType> getRequiredEvents() {
         return REQUIRED_EVENTS;
     }
+
+    // CloseableContainer
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Logger getLogger() {
+        return LOG;
+    }
 }
index 755eb3db8d4fdf48e7c9a70a4030fe105cf8605e..8f8be7ddbc7a6a509f7f924cbe914f8739978f67 100644 (file)
@@ -222,14 +222,6 @@ public final class TopologyListener
             child(Topology.class, topoKey).child(Link.class).build();
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected Logger getLogger() {
-        return LOG;
-    }
-
     /**
      * Return a set of {@link VtnUpdateType} instances that specifies
      * event types to be listened.
@@ -240,4 +232,14 @@ public final class TopologyListener
     protected Set<VtnUpdateType> getRequiredEvents() {
         return REQUIRED_EVENTS;
     }
+
+    // CloseableContainer
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Logger getLogger() {
+        return LOG;
+    }
 }
index 3dda1fb6136714f0d84c0e31241b92917bab7453..8c61c303a9c92892450d30ecebb0c4a9f70c903e 100644 (file)
@@ -341,6 +341,8 @@ public final class VTNInventoryManager
             child(VtnNode.class).build();
     }
 
+    // CloseableContainer
+
     /**
      * {@inheritDoc}
      */
index c137a9eeb463b50a8230ab377082b436b898afbd..f3f4116d06c1a67b4218b497efb016508279d698 100644 (file)
@@ -263,7 +263,7 @@ public final class VTNPacketService extends SalNotificationListener
         }
     }
 
-    // SalNotificationListener
+    // CloseableContainer
 
     /**
      * {@inheritDoc}
index a1074fa26e56307d0f8fb57c1ef09d7cd0c7490d..d926eb0470785faae45a9d74d6b563001222156b 100644 (file)
@@ -363,6 +363,8 @@ public final class PathMapManager
             child(VtnPathMap.class).build();
     }
 
+    // CloseableContainer
+
     /**
      * {@inheritDoc}
      */
index 8ca173eee607512923950e0118ecfb18213827fa..9f02899416dd813d5ff47f9cc963802468135a99 100644 (file)
@@ -366,6 +366,8 @@ final class PathPolicyListener
             child(VtnPathPolicy.class).build();
     }
 
+    // CloseableContainer
+
     /**
      * {@inheritDoc}
      */
index c9c3430ff820b97bc81372cca85bc28582739fdd..e2ec2a8b121a010c7f5b5c1213d4793d2a8c6897 100644 (file)
@@ -282,14 +282,6 @@ public final class VTNRoutingManager
             child(VtnLink.class).build();
     }
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected Logger getLogger() {
-        return LOG;
-    }
-
     /**
      * Return a set of {@link VtnUpdateType} instances that specifies
      * event types to be listened.
@@ -301,6 +293,16 @@ public final class VTNRoutingManager
         return REQUIRED_EVENTS;
     }
 
+    // CloseableContainer
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected Logger getLogger() {
+        return LOG;
+    }
+
     // VTNConfigProvider
 
     /**
index 804968c88262cf068cb8ec0dd64100edee748b19..023afb66003e823b32e782c3e7a2d2607d392534 100644 (file)
@@ -13,8 +13,6 @@ import java.util.Collections;
 import java.util.Map;
 import java.util.Set;
 
-import org.slf4j.Logger;
-
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
@@ -34,17 +32,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VtnUpda
  * @param <C>  Type of event context.
  */
 public abstract class AbstractDataChangeListener<T extends DataObject, C>
-    implements AutoCloseable, DataChangeListener {
+    extends CloseableContainer implements DataChangeListener {
     /**
      * The type of the target data.
      */
     private final Class<T>  targetType;
 
-    /**
-     * A closeable objects to be closed on a {@link #close()} call.
-     */
-    private final CompositeAutoCloseable  closeables;
-
     /**
      * Construct a new instance.
      *
@@ -52,7 +45,6 @@ public abstract class AbstractDataChangeListener<T extends DataObject, C>
      */
     protected AbstractDataChangeListener(Class<T> cls) {
         targetType = cls;
-        closeables = new CompositeAutoCloseable(getLogger());
     }
 
     /**
@@ -90,19 +82,6 @@ public abstract class AbstractDataChangeListener<T extends DataObject, C>
         }
     }
 
-    /**
-     * Add the given closeable object to the closeable object set.
-     *
-     * <p>
-     *   The given object will be closed on a {@link #close()} call.
-     * </p>
-     *
-     * @param ac  An {@link AutoCloseable} instance.
-     */
-    protected final void addCloseable(AutoCloseable ac) {
-        closeables.add(ac);
-    }
-
     /**
      * Verify an instance identifier notified by a data change event.
      *
@@ -298,23 +277,6 @@ public abstract class AbstractDataChangeListener<T extends DataObject, C>
      */
     protected abstract InstanceIdentifier<T> getWildcardPath();
 
-    /**
-     * Return a logger instance.
-     *
-     * @return  A {@link Logger} instance.
-     */
-    protected abstract Logger getLogger();
-
-    // AutoCloseable
-
-    /**
-     * Close this listener.
-     */
-    @Override
-    public void close() {
-        closeables.close();
-    }
-
     // DataChangeListener
 
     /**
diff --git a/manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/util/CloseableContainer.java b/manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/util/CloseableContainer.java
new file mode 100644 (file)
index 0000000..06c1ce8
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2015 NEC Corporation
+ * All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * 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.vtn.manager.internal.util;
+
+import org.slf4j.Logger;
+
+/**
+ * {@code CloseableContainer} describes a container that contains one or
+ * more {@link AutoCloseable} instances.
+ */
+public abstract class CloseableContainer implements AutoCloseable {
+    /**
+     * A closeable objects to be closed on a {@link #close()} call.
+     */
+    private final CompositeAutoCloseable  closeables;
+
+    /**
+     * Construct a new instance.
+     */
+    protected CloseableContainer() {
+        closeables = new CompositeAutoCloseable(getLogger());
+    }
+
+    /**
+     * Add the given closeable object to the closeable object set.
+     *
+     * <p>
+     *   The given object will be closed on the first {@link #close()} call.
+     * </p>
+     *
+     * @param ac  An {@link AutoCloseable} instance.
+     */
+    protected final void addCloseable(AutoCloseable ac) {
+        closeables.add(ac);
+    }
+
+    /**
+     * Return a logger instance.
+     *
+     * <p>
+     *   Note that this method will be called before the constructor returns.
+     * </p>
+     *
+     * @return  A {@link Logger} instance.
+     */
+    protected abstract Logger getLogger();
+
+    // AutoCloseable
+
+    /**
+     * Close all the closeables in this instance.
+     */
+    @Override
+    public void close() {
+        closeables.close();
+    }
+}
index 3d083dc63518662190fec1522d134f3318e3f781..e9fa45c48dbfa535d668dd06a2bc041a48c3fadb 100644 (file)
@@ -9,32 +9,15 @@
 
 package org.opendaylight.vtn.manager.internal.util;
 
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.slf4j.Logger;
-
 import org.opendaylight.controller.sal.binding.api.NotificationService;
 
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.NotificationListener;
 
 /**
  * Abstract base class for MD-SAL notification listener.
  */
-public abstract class SalNotificationListener
-    implements AutoCloseable, NotificationListener {
-    /**
-     * Registration of the notification listener.
-     */
-    private final AtomicReference<ListenerRegistration<NotificationListener>> registration =
-        new AtomicReference<>();
-
-    /**
-     * Construct a new instance.
-     */
-    protected SalNotificationListener() {
-    }
-
+public abstract class SalNotificationListener extends CloseableContainer
+    implements NotificationListener {
     /**
      * Register this instance as a SAL notification listener.
      *
@@ -42,7 +25,7 @@ public abstract class SalNotificationListener
      */
     protected final void registerListener(NotificationService nsv) {
         try {
-            registration.set(nsv.registerNotificationListener(this));
+            addCloseable(nsv.registerNotificationListener(this));
         } catch (Exception e) {
             String msg = "Failed to register notification listener: " +
                 getClass().getName();
@@ -50,31 +33,4 @@ public abstract class SalNotificationListener
             throw new IllegalStateException(msg, e);
         }
     }
-
-    /**
-     * Return a logger instance.
-     *
-     * @return  A {@link Logger} instance.
-     */
-    protected abstract Logger getLogger();
-
-    // AutoCloseable
-
-    /**
-     * Close this listener.
-     */
-    @Override
-    public void close() {
-        ListenerRegistration<NotificationListener> reg =
-            registration.getAndSet(null);
-        if (reg != null) {
-            try {
-                reg.close();
-            } catch (Exception e) {
-                String msg = "Failed to unregister notification listener: " +
-                    getClass().getName();
-                getLogger().error(msg, e);
-            }
-        }
-    }
 }
index 0272b5b3ec682d49c65a95ab7ac97d07ba6f4d78..1fe2ff742f625a9dc831482db1d5c3dd850a8858 100644 (file)
@@ -365,6 +365,8 @@ public final class VTenantManager
             child(Vtn.class).build();
     }
 
+    // CloseableContainer
+
     /**
      * {@inheritDoc}
      */
index 0d62b88e2f62dfa6e9af4439b8f272d512f0a301..7a6780804fbd6967da43f75cad508aeb2573a7a3 100644 (file)
@@ -33,13 +33,19 @@ public class SalNotificationListenerTest extends TestBase {
         /**
          * Logger instance.
          */
-        private final Logger  logger = Mockito.mock(Logger.class);
+        private Logger  logger;
 
         /**
          * {@inheritDoc}
          */
+        @Override
         protected Logger getLogger() {
-            return logger;
+            Logger log = logger;
+            if (log == null) {
+                log = Mockito.mock(Logger.class);
+                logger = log;
+            }
+            return log;
         }
     }
 
@@ -148,8 +154,7 @@ public class SalNotificationListenerTest extends TestBase {
         Mockito.verify(logger, Mockito.never()).error(Mockito.anyString());
 
         // Unregister a listener.
-        String msg = "Failed to unregister notification listener: " +
-            listener.getClass().getName();
+        String msg = "Failed to close instance: " + reg;
         IllegalArgumentException iae =
             new IllegalArgumentException("Bad argument");
         Mockito.doThrow(iae).when(reg).close();