2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.md.statistics.manager.impl;
12 import java.util.concurrent.ConcurrentHashMap;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
16 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
17 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
18 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
19 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
20 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
21 import org.opendaylight.controller.md.statistics.manager.StatListeningCommiter;
22 import org.opendaylight.controller.md.statistics.manager.StatisticsManager;
23 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
25 import org.opendaylight.yangtools.concepts.ListenerRegistration;
26 import org.opendaylight.yangtools.yang.binding.DataObject;
27 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
28 import org.opendaylight.yangtools.yang.binding.NotificationListener;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
32 import com.google.common.base.Optional;
33 import com.google.common.base.Preconditions;
37 * org.opendaylight.controller.md.statistics.manager.impl
39 * StatAbstractListeneningCommiter
40 * Class is abstract implementation for all Configuration/DataStore DataChange
41 * listenable DataObjects like flows, groups, meters. It is a holder for common
42 * functionality needed by construction/destruction class and for DataChange
46 public abstract class StatAbstractListenCommit<T extends DataObject, N extends NotificationListener>
47 extends StatAbstractNotifyCommit<N> implements StatListeningCommiter<T,N> {
49 private static final Logger LOG = LoggerFactory.getLogger(StatAbstractListenCommit.class);
51 private ListenerRegistration<DataChangeListener> listenerRegistration;
53 protected final Map<InstanceIdentifier<Node>, Map<InstanceIdentifier<T>, Integer>> mapNodesForDelete = new ConcurrentHashMap<>();
54 protected final Map<InstanceIdentifier<Node>, Integer> mapNodeFeautureRepeater = new ConcurrentHashMap<>();
56 private final Class<T> clazz;
58 private final DataBroker dataBroker;
60 private volatile ReadOnlyTransaction currentReadTx;
62 /* Constructor has to make a registration */
63 public StatAbstractListenCommit(final StatisticsManager manager, final DataBroker db,
64 final NotificationProviderService nps, final Class<T> clazz) {
66 this.clazz = Preconditions.checkNotNull(clazz, "Referenced Class can not be null");
67 Preconditions.checkArgument(db != null, "DataBroker can not be null!");
68 listenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
69 getWildCardedRegistrationPath(), this, DataChangeScope.BASE);
74 * Method returns WildCarded Path which is used for registration as a listening path changes in
75 * {@link org.opendaylight.controller.md.sal.binding.api.DataChangeListener}
78 protected abstract InstanceIdentifier<T> getWildCardedRegistrationPath();
81 public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
82 Preconditions.checkNotNull(changeEvent,"Async ChangeEvent can not be null!");
84 * If we have opened read transaction for configuraiton data store,
85 * we will close and null it.
87 * Latest read transaction will be allocated on another read using readLatestConfiguration
89 if(currentReadTx != null) {
90 final ReadOnlyTransaction previous = currentReadTx;
96 @SuppressWarnings("unchecked")
97 protected void removeData(final InstanceIdentifier<?> key, final Integer value) {
98 if (clazz.equals(key.getTargetType())) {
99 final InstanceIdentifier<Node> nodeIdent = key.firstIdentifierOf(Node.class);
100 Map<InstanceIdentifier<T>, Integer> map = null;
101 if (mapNodesForDelete.containsKey(nodeIdent)) {
102 map = mapNodesForDelete.get(nodeIdent);
105 map = new ConcurrentHashMap<>();
106 mapNodesForDelete.put(nodeIdent, map);
108 map.put((InstanceIdentifier<T>) key, value);
113 public void cleanForDisconnect(final InstanceIdentifier<Node> nodeIdent) {
114 mapNodesForDelete.remove(nodeIdent);
118 public void close() {
119 if (listenerRegistration != null) {
121 listenerRegistration.close();
122 } catch (final Exception e) {
123 LOG.error("Error by stop {} DataChange StatListeningCommiter.", clazz.getSimpleName(), e);
125 listenerRegistration = null;
132 * Method return actual DataObject identified by InstanceIdentifier from Config/DS
136 protected final <K extends DataObject> Optional<K> readLatestConfiguration(final InstanceIdentifier<K> path) {
137 if(currentReadTx == null) {
138 currentReadTx = dataBroker.newReadOnlyTransaction();
141 return currentReadTx.read(LogicalDatastoreType.CONFIGURATION, path).checkedGet();
142 } catch (final ReadFailedException e) {
143 return Optional.absent();