import org.opendaylight.openflowplugin.applications.old.notification.supplier.impl.item.FlowNotificationSupplierImpl;
import org.opendaylight.openflowplugin.applications.old.notification.supplier.impl.item.GroupNotificationSupplierImpl;
import org.opendaylight.openflowplugin.applications.old.notification.supplier.impl.item.MeterNotificationSupplierImpl;
+import org.opendaylight.openflowplugin.applications.old.notification.supplier.impl.item.stat.FlowStatNotifSupplierImpl;
import org.opendaylight.openflowplugin.applications.old.notification.supplier.tools.OldNotifProviderConfig;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNodeConnector;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemoved;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatistics;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupAdded;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupRemoved;
import org.opendaylight.yang.gen.v1.urn.opendaylight.group.service.rev130918.GroupUpdated;
private OldNotifSupplierForItem<Flow, FlowAdded, FlowUpdated, FlowRemoved> flowSupp;
private OldNotifSupplierForItem<Meter, MeterAdded, MeterUpdated, MeterRemoved> meterSupp;
private OldNotifSupplierForItem<Group, GroupAdded, GroupUpdated, GroupRemoved> groupSupp;
+ private OldNotifSupplierForItemStat<FlowStatistics, FlowsStatisticsUpdate> flowStatSupp;
/**
* Provider constructor set all needed final parameters
flowSupp = config.isFlowSupport() ? new FlowNotificationSupplierImpl(nps, db) : null;
meterSupp = config.isMeterSupport() ? new MeterNotificationSupplierImpl(nps, db) : null;
groupSupp = config.isGroupSupport() ? new GroupNotificationSupplierImpl(nps, db) : null;
+ flowStatSupp = config.isFlowStatSupport() ? new FlowStatNotifSupplierImpl(nps, db) : null;
- supplierList = new ArrayList<>(Arrays.asList(nodeSupp, connectorSupp, flowSupp, meterSupp, groupSupp));
+ supplierList = new ArrayList<>(Arrays.asList(nodeSupp, connectorSupp, flowSupp, meterSupp, groupSupp,
+ flowStatSupp));
}
@Override
* @param <U> - Update notification
* @param <D> - Delete notification
*/
-public interface OldNotifSupplierForItem<O extends DataObject, C extends Notification, U extends Notification, D extends Notification>
+public interface OldNotifSupplierForItem<O extends DataObject,
+ C extends Notification,
+ U 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
/**
* Method produces relevant updateItem 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
/**
* 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);
+ D deleteNotification(InstanceIdentifier<O> path);
}
--- /dev/null
+/*
+ * 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;
+
+/**
+ * Notifications for Statistics have little bit different case,
+ * because it looks like they have response for create and update.
+ * But follow the statistics internal implementation processing
+ * is talks only about create event.
+ *
+ * @param <O> - data tree item Object
+ * @param <N> - Statistics Notification
+ */
+public interface OldNotifSupplierForItemStat<O extends DataObject, N extends Notification>
+ extends OldNotifSupplierDefinition<O> {
+
+
+ /**
+ * Method produces relevant Statistics kind of {@link Notification} from statistics
+ * data tree item identified by {@link InstanceIdentifier} path.
+ *
+ * @param o - Statistics Data Tree Item
+ * @param path - Identifier of Data Tree Item
+ * @return {@link Notification} - relevant API contract Notification
+ */
+ N createNotification(O o, InstanceIdentifier<O> path);
+}
+
--- /dev/null
+/*
+ * 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.item.stat;
+
+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.OldNotifSupplierForItemStat;
+import org.opendaylight.openflowplugin.applications.old.notification.supplier.impl.AbstractNotifSupplierBase;
+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 Statistics
+ * Notification Suppliers
+ *
+ * @param <O> - Statistics {@link DataObject}
+ * @param <N> - Statistics Notification
+ */
+abstract class AbstractNotifSupplierForItemStat<O extends DataObject,
+ N extends Notification>
+ extends AbstractNotifSupplierBase<O>
+ implements OldNotifSupplierForItemStat<O, N> {
+
+ private final NotificationProviderService notifProviderService;
+
+ /**
+ * Default constructor for all Statistic Notification Supplier implementation
+ *
+ * @param notifProviderService - notification publisher
+ * @param db - DataBroker for DataChangeEvent registration
+ * @param clazz - Statistics Notification Class
+ */
+ public AbstractNotifSupplierForItemStat(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 N notif = createNotification((O) createDataObj.getValue(), ii);
+ if (notif != null) {
+ notifProviderService.publish(notif);
+ }
+ }
+ }
+ }
+ }
+}
+
--- /dev/null
+/*
+ * 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.item.stat;
+
+import com.google.common.base.Preconditions;
+import java.util.Collections;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
+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;
+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.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.and.statistics.map.list.FlowAndStatisticsMapListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Implementation define a contract between {@link FlowStatistics} data object
+ * and {@link FlowsStatisticsUpdate} notification.
+ */
+public class FlowStatNotifSupplierImpl extends AbstractNotifSupplierForItemStat<FlowStatistics, FlowsStatisticsUpdate> {
+
+ private static final InstanceIdentifier<FlowStatistics> wildCardedInstanceIdent =
+ getNodeWildII().augmentation(FlowCapableNode.class).child(Table.class)
+ .child(Flow.class).augmentation(FlowStatisticsData.class).child(FlowStatistics.class);
+
+ /**
+ * Constructor register supplier as DataChangeLister and create wildCarded InstanceIdentifier.
+ *
+ * @param notifProviderService - {@link NotificationProviderService}
+ * @param db - {@link DataBroker}
+ */
+ public FlowStatNotifSupplierImpl(final NotificationProviderService notifProviderService, final DataBroker db) {
+ super(notifProviderService, db, FlowStatistics.class);
+ }
+
+ @Override
+ public InstanceIdentifier<FlowStatistics> getWildCardPath() {
+ return wildCardedInstanceIdent;
+ }
+
+ @Override
+ public FlowsStatisticsUpdate createNotification(final FlowStatistics o, final InstanceIdentifier<FlowStatistics> path) {
+ Preconditions.checkArgument(o != null);
+ Preconditions.checkArgument(path != null);
+
+ final FlowAndStatisticsMapListBuilder fsmlBuilder = new FlowAndStatisticsMapListBuilder(o);
+ fsmlBuilder.setFlowId(new FlowId(path.firstKeyOf(Flow.class, FlowKey.class).getId().getValue()));
+
+ final FlowsStatisticsUpdateBuilder builder = new FlowsStatisticsUpdateBuilder();
+ builder.setId(getNodeId(path));
+ builder.setMoreReplies(Boolean.FALSE);
+ // NOTE : fix if it needs, but we have to ask DataStore for the NodeConnector list
+ builder.setNodeConnector(Collections.<NodeConnector> emptyList());
+ builder.setFlowAndStatisticsMapList(Collections.singletonList(fsmlBuilder.build()));
+ return builder.build();
+ }
+}
+
--- /dev/null
+/*
+ * 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 contains OF Statistics Items (Flow, Group, Meter ...) notification listener/supplier implementations
+ */
+package org.opendaylight.openflowplugin.applications.old.notification.supplier.impl.item.stat;
\ No newline at end of file
--- /dev/null
+/*
+ * 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.item.stat;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Matchers;
+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.impl.helper.TestChangeEventBuildHelper;
+import org.opendaylight.openflowplugin.applications.old.notification.supplier.impl.helper.TestSupplierVerifyHelper;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey;
+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.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowStatisticsData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.FlowsStatisticsUpdate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatistics;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.flow.statistics.FlowStatisticsBuilder;
+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.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+public class FlowStatNotifSupplierImplTest {
+
+ private static final String FLOW_NODE_ID = "test-111";
+ private static final Short FLOW_TABLE_ID = 111;
+ private static final String FLOW_ID = "test-flow-111";
+ private FlowStatNotifSupplierImpl notifSupplierImpl;
+ private NotificationProviderService notifProviderService;
+ private DataBroker dataBroker;
+
+ @Before
+ public void initalization() {
+ notifProviderService = mock(NotificationProviderService.class);
+ dataBroker = mock(DataBroker.class);
+ notifSupplierImpl = new FlowStatNotifSupplierImpl(notifProviderService, dataBroker);
+ TestSupplierVerifyHelper.verifyDataChangeRegistration(dataBroker);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testNullChangeEvent() {
+ notifSupplierImpl.onDataChanged(null);
+ }
+
+ @Test
+ public void testNullableChangeEvent() {
+ notifSupplierImpl.onDataChanged(TestChangeEventBuildHelper.createEmptyTestDataEvent());
+ }
+
+ @Test
+ public void testEmptyChangeEvent() {
+ notifSupplierImpl.onDataChanged(TestChangeEventBuildHelper.createEmptyTestDataEvent());
+ }
+
+ @Test
+ public void testCreate() {
+ final FlowsStatisticsUpdate notification = notifSupplierImpl.createNotification(createTestFlowStat(), createTestFlowStatPath());
+ assertNotNull(notification);
+ assertEquals(FLOW_NODE_ID, notification.getId().getValue());
+ }
+
+ @Test
+ public void testCreateChangeEvent() {
+ final Map<InstanceIdentifier<?>, DataObject> createdData = new HashMap<>();
+ createdData.put(createTestFlowStatPath(), createTestFlowStat());
+ notifSupplierImpl.onDataChanged(TestChangeEventBuildHelper.createTestDataEvent(createdData, null, null));
+ verify(notifProviderService, times(1)).publish(Matchers.any(FlowsStatisticsUpdate.class));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCreateFromNullNodeConnector() {
+ notifSupplierImpl.createNotification(null, createTestFlowStatPath());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testCreateFromNullPath() {
+ notifSupplierImpl.createNotification(createTestFlowStat(), null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testUpdateFromNullNodeConnector() {
+ notifSupplierImpl.createNotification(null, createTestFlowStatPath());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testUpdateFromNullPath() {
+ notifSupplierImpl.createNotification(createTestFlowStat(), null);
+ }
+
+ private static InstanceIdentifier<FlowStatistics> createTestFlowStatPath() {
+ return InstanceIdentifier.create(Nodes.class).child(Node.class, new NodeKey(new NodeId(FLOW_NODE_ID)))
+ .augmentation(FlowCapableNode.class).child(Table.class, new TableKey(FLOW_TABLE_ID))
+ .child(Flow.class, new FlowKey(new FlowId(FLOW_ID))).augmentation(FlowStatisticsData.class)
+ .child(FlowStatistics.class);
+ }
+
+ private static FlowStatistics createTestFlowStat() {
+ final FlowStatisticsBuilder builder = new FlowStatisticsBuilder();
+ return builder.build();
+ }
+}
+