BUG-4117: preparation for FlowCapableNode notification impl. 39/31539/4
authorMartin Bobak <mbobak@cisco.com>
Thu, 20 Aug 2015 21:45:07 +0000 (23:45 +0200)
committermichal rehak <mirehak@cisco.com>
Wed, 20 Jan 2016 12:31:25 +0000 (12:31 +0000)
 - add abstract implementation

Note: Original commit https://git.opendaylight.org/gerrit/#/c/25965/
has to be broken to a chain of smaller commits

Change-Id: Ib1165a63acc43f2f57ecd7282a9da21a446dc566
Signed-off-by: Martin Bobak <mbobak@cisco.com>
Signed-off-by: Vaclav Demcak <vdemcak@cisco.com>
(cherry picked from commit 15a7d24e83bdd182b84d8c8f77ab636ff5857cf3)

applications/old-notification-supplier/src/main/java/org/opendaylight/openflowplugin/applications/old/notification/supplier/OldNotifProviderImpl.java [new file with mode: 0644]
applications/old-notification-supplier/src/main/java/org/opendaylight/openflowplugin/applications/old/notification/supplier/OldNotifSupplierForItemRoot.java [new file with mode: 0644]
applications/old-notification-supplier/src/main/java/org/opendaylight/openflowplugin/applications/old/notification/supplier/impl/AbstractNofitSupplierFoItemRoot.java [new file with mode: 0644]
applications/old-notification-supplier/src/main/java/org/opendaylight/openflowplugin/applications/old/notification/supplier/impl/AbstractNotifSupplierBase.java [new file with mode: 0644]
applications/old-notification-supplier/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/openflow/applications/old/notification/supplier/rev150820/OldNotifModule.java

diff --git a/applications/old-notification-supplier/src/main/java/org/opendaylight/openflowplugin/applications/old/notification/supplier/OldNotifProviderImpl.java b/applications/old-notification-supplier/src/main/java/org/opendaylight/openflowplugin/applications/old/notification/supplier/OldNotifProviderImpl.java
new file mode 100644 (file)
index 0000000..c974de9
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  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.openflowplugin.applications.old.notification.supplier;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import java.util.List;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.openflowplugin.applications.old.notification.supplier.tools.OldNotifProviderConfig;
+
+/**
+ * Provider Implementation
+ */
+public class OldNotifProviderImpl implements OldNotifProvider {
+
+    private final DataBroker db;
+    private final OldNotifProviderConfig config;
+    private final NotificationProviderService nps;
+
+    /* Supplier List property help for easy close method implementation and testing */
+    private List<OldNotifSupplierDefinition<?>> supplierList;
+
+    /**
+     * Provider constructor set all needed final parameters
+     *
+     * @param config - Configuration Object
+     * @param nps - notifProviderService
+     * @param db - dataBroker
+     */
+    public OldNotifProviderImpl(final OldNotifProviderConfig config,
+            final NotificationProviderService nps, final DataBroker db) {
+        this.config = Preconditions.checkNotNull(config);
+        this.db = Preconditions.checkNotNull(db);
+        this.nps = Preconditions.checkNotNull(nps);
+    }
+
+    @Override
+    public void start() {
+    }
+
+    @Override
+    public void close() throws Exception {
+        for (OldNotifSupplierDefinition<?> supplier : supplierList) {
+            if (supplier != null) {
+                supplier.close();
+                supplier = null;
+            }
+        }
+    }
+
+    @VisibleForTesting
+    List<OldNotifSupplierDefinition<?>> getSupplierList() {
+        return supplierList;
+    }
+}
+
diff --git a/applications/old-notification-supplier/src/main/java/org/opendaylight/openflowplugin/applications/old/notification/supplier/OldNotifSupplierForItemRoot.java b/applications/old-notification-supplier/src/main/java/org/opendaylight/openflowplugin/applications/old/notification/supplier/OldNotifSupplierForItemRoot.java
new file mode 100644 (file)
index 0000000..e2deace
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  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.openflowplugin.applications.old.notification.supplier;
+
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.Notification;
+
+/**
+ * Supplier Root Item contracts definition for every Old Notifications. All root items
+ * are described by two notifications. Notification for Create and Delete.
+ * So interface has to contain two methods for relevant Notification.
+ *
+ * @param <O> - data tree item Object
+ * @param <C> - Create notification
+ * @param <D> - Delete notification
+ */
+public interface OldNotifSupplierForItemRoot<O extends DataObject,
+                                             C extends Notification,
+                                             D extends Notification>
+                extends OldNotifSupplierDefinition<O> {
+
+    /**
+     * Method produces relevant addItem kind of {@link Notification} from
+     * data tree item identified by {@link InstanceIdentifier} path.
+     * 
+     * @param o - Data Tree Item object
+     * @param path - Identifier of Data Tree Item
+     * @return {@link Notification} - relevant API contract Notification
+     */
+    C createNotification(O o, InstanceIdentifier<O> path);
+
+    /**
+     * Method produces relevant deleteItem kind of {@link Notification} from
+     * path {@link InstanceIdentifier} to deleted item.
+     * 
+     * @param path - Identifier of Data Tree Item
+     * @return {@link Notification} - relevant API contract Notification
+     */
+    D deleteNotification(InstanceIdentifier<O> path);
+}
+
diff --git a/applications/old-notification-supplier/src/main/java/org/opendaylight/openflowplugin/applications/old/notification/supplier/impl/AbstractNofitSupplierFoItemRoot.java b/applications/old-notification-supplier/src/main/java/org/opendaylight/openflowplugin/applications/old/notification/supplier/impl/AbstractNofitSupplierFoItemRoot.java
new file mode 100644 (file)
index 0000000..52b7558
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  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.openflowplugin.applications.old.notification.supplier.impl;
+
+import com.google.common.base.Preconditions;
+import java.util.Map.Entry;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+import org.opendaylight.openflowplugin.applications.old.notification.supplier.OldNotifSupplierForItemRoot;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.Notification;
+
+/**
+ * Class is package protected abstract implementation for all Old Root Items
+ * Notification Suppliers
+ *
+ * @param <O> - data tree item Object
+ * @param <C> - Create notification
+ * @param <D> - Delete notification
+ */
+abstract class AbstractNofitSupplierFoItemRoot<O extends DataObject,
+                                               C extends Notification,
+                                               D extends Notification>
+                    extends AbstractNotifSupplierBase<O>
+                    implements OldNotifSupplierForItemRoot<O, C, D> {
+
+    private final NotificationProviderService notifProviderService;
+
+    /**
+     * Default constructor for all Root Item Notification Supplier implementation
+     *
+     * @param notifProviderService - notification publisher
+     * @param db - DataBroker for DataChangeEvent registration
+     * @param clazz - Statistics Notification Class
+     */
+    public AbstractNofitSupplierFoItemRoot(final NotificationProviderService notifProviderService, final DataBroker db,
+            final Class<O> clazz) {
+        super(db, clazz);
+        this.notifProviderService = Preconditions.checkNotNull(notifProviderService);
+    }
+
+    @Override
+    public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
+        Preconditions.checkArgument(change != null, "ChangeEvent can not be null!");
+        if (change.getCreatedData() != null && ! (change.getCreatedData().isEmpty())) {
+            for (final Entry<InstanceIdentifier<?>, DataObject> createDataObj : change.getCreatedData().entrySet()) {
+                if (clazz.isAssignableFrom(createDataObj.getKey().getTargetType())) {
+                    final InstanceIdentifier<O> ii = createDataObj.getKey().firstIdentifierOf(clazz);
+                    final C notif = createNotification((O) createDataObj.getValue(), ii);
+                    if (notif != null) {
+                        notifProviderService.publish(notif);
+                    }
+                }
+            }
+        }
+
+        if (change.getRemovedPaths() != null && !(change.getRemovedPaths().isEmpty())) {
+            for (final InstanceIdentifier<?> deleteDataPath : change.getRemovedPaths()) {
+                if (clazz.isAssignableFrom(deleteDataPath.getTargetType())) {
+                    final D notif = deleteNotification(deleteDataPath.firstIdentifierOf(clazz));
+                    if (notif != null) {
+                        notifProviderService.publish(notif);
+                    }
+                }
+            }
+        }
+    }
+}
+
diff --git a/applications/old-notification-supplier/src/main/java/org/opendaylight/openflowplugin/applications/old/notification/supplier/impl/AbstractNotifSupplierBase.java b/applications/old-notification-supplier/src/main/java/org/opendaylight/openflowplugin/applications/old/notification/supplier/impl/AbstractNotifSupplierBase.java
new file mode 100644 (file)
index 0000000..065e524
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  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.openflowplugin.applications.old.notification.supplier.impl;
+
+import com.google.common.base.Preconditions;
+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;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.openflowplugin.applications.old.notification.supplier.OldNotifSupplierDefinition;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
+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.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+
+/**
+ * Public abstract basic Supplier implementation contains code for a make Supplier instance,
+ * registration Supplier like {@link org.opendaylight.controller.md.sal.binding.api.DataChangeListener} and close
+ * method. In additional case, it contains help methods for all Supplier implementations.
+ * 
+ * @param <O> - data tree item Object extends {@link DataObject}
+ */
+public abstract class AbstractNotifSupplierBase<O extends DataObject> implements OldNotifSupplierDefinition<O> {
+
+    protected final Class<O> clazz;
+    private ListenerRegistration<DataChangeListener> listenerRegistration;
+
+    /**
+     * Default constructor for all Notification Supplier implementation
+     * 
+     * @param db - {@link DataBroker}
+     * @param clazz - API contract class extended {@link DataObject}
+     */
+    public AbstractNotifSupplierBase(final DataBroker db, final Class<O> clazz) {
+        Preconditions.checkArgument(db != null, "DataBroker can not be null!");
+        listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, getWildCardPath(), this,
+                DataChangeScope.BASE);
+        this.clazz = clazz;
+    }
+
+    @Override
+    public void close() throws Exception {
+        if (listenerRegistration != null) {
+            listenerRegistration.close();
+            listenerRegistration = null;
+        }
+    }
+
+    /**
+     * Method returns a wildCard {@link InstanceIdentifier} for {@link Node} from inventory
+     * because this path is a base for every OF paths.
+     * 
+     * @return WildCarded InstanceIdentifier for Node
+     */
+    protected static InstanceIdentifier<Node> getNodeWildII() {
+        return InstanceIdentifier.create(Nodes.class).child(Node.class);
+    }
+
+    /**
+     * Method returns a keyed {@link InstanceIdentifier} for {@link Node} from inventory
+     * because this path is a base for every OF paths.
+     * 
+     * @param ii - key for keyed {@link Node} {@link InstanceIdentifier}
+     * @return Keyed InstanceIdentifier for Node
+     */
+    protected static KeyedInstanceIdentifier<Node, NodeKey> getNodeII(final InstanceIdentifier<?> ii) {
+        final NodeKey key = ii.firstKeyOf(Node.class, NodeKey.class);
+        Preconditions.checkArgument(key != null);
+        return InstanceIdentifier.create(Nodes.class).child(Node.class, key);
+    }
+
+    /**
+     * @param path pointer to element
+     * @return extracted {@link NodeKey} and wrapped in {@link NodeRef}
+     */
+    public static NodeRef createNodeRef(final InstanceIdentifier<?> path) {
+        final InstanceIdentifier<Node> nodePath = Preconditions.checkNotNull(path.firstIdentifierOf(Node.class));
+        return new NodeRef(nodePath);
+    }
+
+    /**
+     * @param path pointer to element
+     * @return extracted {@link NodeId}
+     */
+    public static NodeId getNodeId(final InstanceIdentifier<?> path) {
+        final NodeKey nodeKey = Preconditions.checkNotNull(path.firstKeyOf(Node.class, NodeKey.class));
+        return nodeKey.getId();
+    }
+
+}
index d89228306c2ad86b942a4cdc6eab70dd29fce9ba..428f8623a93bf888be4a73dfd916ab21292148d4 100644 (file)
@@ -11,6 +11,8 @@ package org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflo
 import com.google.common.base.Preconditions;
 import org.opendaylight.controller.config.api.DependencyResolver;
 import org.opendaylight.controller.config.api.ModuleIdentifier;
+import org.opendaylight.openflowplugin.applications.old.notification.supplier.OldNotifProvider;
+import org.opendaylight.openflowplugin.applications.old.notification.supplier.OldNotifProviderImpl;
 import org.opendaylight.openflowplugin.applications.old.notification.supplier.tools.OldNotifProviderConfig;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -59,7 +61,23 @@ public class OldNotifModule extends AbstractOldNotifModule {
         LOG.info("OldNotificationSupplier module initialization.");
         LOG.warn("OldNotificationSupplier module is marked like DEPRECATED. Modul could supplie old notification only for lithium release.");
         final OldNotifProviderConfig config = createConfig();
-        return null;
+        final OldNotifProvider provider = new OldNotifProviderImpl(config, getNotificationServiceDependency(),
+                getDataBrokerDependency());
+        provider.start();
+        LOG.info("StatisticsManager started successfully.");
+
+        return new AutoCloseable() {
+
+            @Override
+            public void close() throws Exception {
+                try {
+                    provider.close();
+                } catch (final Exception e) {
+                    LOG.error("Unexpected error by stoppping Old-Notification-Supplier module", e);
+                }
+                LOG.info("Old-Notification-Supplier module stopped.");
+            }
+        };
     }
 
     /*