MDSAL-API Migration
[genius.git] / mdsalutil / mdsalutil-api / src / main / java / org / opendaylight / genius / datastoreutils / AsyncDataTreeChangeListenerBase.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
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
7  */
8
9 /*package org.opendaylight.genius.datastoreutils;
10
11 import com.google.common.base.Preconditions;
12 import java.util.Collection;
13 import java.util.concurrent.ExecutorService;
14 import javax.annotation.PostConstruct;
15 import javax.annotation.PreDestroy;
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
18 import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
19 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
20 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
21 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
22 import org.opendaylight.genius.utils.SuperTypeUtil;
23 import org.opendaylight.infrautils.metrics.MetricProvider;
24 import org.opendaylight.infrautils.utils.concurrent.Executors;
25 import org.opendaylight.serviceutils.tools.mdsal.listener.ChainableDataTreeChangeListener;
26 import org.opendaylight.serviceutils.tools.mdsal.listener.ChainableDataTreeChangeListenerImpl;
27 import org.opendaylight.yangtools.concepts.ListenerRegistration;
28 import org.opendaylight.yangtools.yang.binding.DataObject;
29 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 */
34 /**
35  * Deprecated DS listener.
36  * @deprecated Please use
37  * {@link org.opendaylight.serviceutils.tools.mdsal.listener.AbstractAsyncDataTreeChangeListener} instead of this!
38  *//*
39
40 @Deprecated
41 public abstract class AsyncDataTreeChangeListenerBase<T extends DataObject, K extends DataTreeChangeListener<T>>
42         implements DataTreeChangeListener<T>, ChainableDataTreeChangeListener<T>, AutoCloseable {
43
44     private static final Logger LOG = LoggerFactory.getLogger(AsyncDataTreeChangeListenerBase.class);
45
46     private ListenerRegistration<K> listenerRegistration;
47     private final ChainableDataTreeChangeListenerImpl<T> chainingDelegate = new ChainableDataTreeChangeListenerImpl<>();
48     private final ExecutorService dataTreeChangeHandlerExecutor;
49     protected final Class<T> clazz;
50     private DataStoreMetrics dataStoreMetrics;
51
52     protected AsyncDataTreeChangeListenerBase() {
53         this.clazz = SuperTypeUtil.getTypeParameter(getClass(), 0);
54         this.dataTreeChangeHandlerExecutor = newThreadPoolExecutor(clazz);
55     }
56
57     protected AsyncDataTreeChangeListenerBase(MetricProvider metricProvider) {
58         this();
59         this.dataStoreMetrics = new DataStoreMetrics(metricProvider, getClass());
60     }
61
62     @Deprecated
63     public AsyncDataTreeChangeListenerBase(Class<T> clazz, Class<K> eventClazz) {
64         this.clazz = Preconditions.checkNotNull(clazz, "Class can not be null!");
65         this.dataTreeChangeHandlerExecutor = newThreadPoolExecutor(clazz);
66     }
67
68     private static ExecutorService newThreadPoolExecutor(Class<?> clazz) {
69         return Executors.newSingleThreadExecutor(
70                 // class name first so it shows up in logs' prefix, but fixed length
71                 clazz.getName() + "_AsyncDataTreeChangeListenerBase-DataTreeChangeHandler", LOG);
72     }
73
74     @Override
75     public void addBeforeListener(DataTreeChangeListener<T> listener) {
76         chainingDelegate.addBeforeListener(listener);
77     }
78
79     @Override
80     public void addAfterListener(DataTreeChangeListener<T> listener) {
81         chainingDelegate.addAfterListener(listener);
82     }
83
84     @Override
85     public void onDataTreeChanged(Collection<DataTreeModification<T>> changes) {
86         if (changes == null || changes.isEmpty()) {
87             return;
88         }
89
90         DataTreeChangeHandler dataTreeChangeHandler = new DataTreeChangeHandler(changes);
91         dataTreeChangeHandlerExecutor.execute(dataTreeChangeHandler);
92     }
93
94     public void registerListener(LogicalDatastoreType dsType, final DataBroker db) {
95         final DataTreeIdentifier<T> treeId = new DataTreeIdentifier<>(dsType, getWildCardPath());
96         listenerRegistration = db.registerDataTreeChangeListener(treeId, getDataTreeChangeListener());
97     }
98
99     */
100 /**
101      * Subclasses override this and place initialization logic here, notably
102      * calls to registerListener(). Note that the overriding method MUST repeat
103      * the PostConstruct annotation, because JSR 250 specifies that lifecycle
104      * methods "are called unless a subclass of the declaring class overrides
105      * the method without repeating the annotation".  (The blueprint-maven-plugin
106      * would gen. XML which calls PostConstruct annotated methods even if they are
107      * in a subclass without repeating the annotation, but this is wrong and not
108      * JSR 250 compliant, and while working in BP, then causes issues e.g. when
109      * wiring with Guice for tests, so do always repeat it.)
110      *//*
111
112     @PostConstruct
113     protected void init() {
114     }
115
116     public void deregisterListener() {
117         if (listenerRegistration != null) {
118             try {
119                 listenerRegistration.close();
120             } finally {
121                 listenerRegistration = null;
122             }
123         }
124     }
125
126     @Override
127     @PreDestroy
128     public void close() {
129         dataTreeChangeHandlerExecutor.shutdownNow();
130         deregisterListener();
131     }
132
133     protected abstract InstanceIdentifier<T> getWildCardPath();
134
135     protected abstract void remove(InstanceIdentifier<T> key, T dataObjectModification);
136
137     protected abstract void update(InstanceIdentifier<T> key,
138             T dataObjectModificationBefore, T dataObjectModificationAfter);
139
140     protected abstract void add(InstanceIdentifier<T> key, T dataObjectModification);
141
142     protected abstract K getDataTreeChangeListener();
143
144     public class DataTreeChangeHandler implements Runnable {
145         private final Collection<DataTreeModification<T>> changes;
146
147         public DataTreeChangeHandler(Collection<DataTreeModification<T>> changes) {
148             chainingDelegate.notifyBeforeOnDataTreeChanged(changes);
149             this.changes = changes;
150         }
151
152         @Override
153         public void run() {
154             for (DataTreeModification<T> change : changes) {
155                 final InstanceIdentifier<T> key = change.getRootPath().getRootIdentifier();
156                 final DataObjectModification<T> mod = change.getRootNode();
157
158                 switch (mod.getModificationType()) {
159                     case DELETE:
160                         if (dataStoreMetrics != null) {
161                             dataStoreMetrics.incrementDeleted();
162                         }
163                         remove(key, mod.getDataBefore());
164                         break;
165                     case SUBTREE_MODIFIED:
166                         if (dataStoreMetrics != null) {
167                             dataStoreMetrics.incrementUpdated();
168                         }
169                         update(key, mod.getDataBefore(), mod.getDataAfter());
170                         break;
171                     case WRITE:
172                         if (mod.getDataBefore() == null) {
173                             if (dataStoreMetrics != null) {
174                                 dataStoreMetrics.incrementAdded();
175                             }
176                             add(key, mod.getDataAfter());
177                         } else {
178                             if (dataStoreMetrics != null) {
179                                 dataStoreMetrics.incrementUpdated();
180                             }
181                             update(key, mod.getDataBefore(), mod.getDataAfter());
182                         }
183                         break;
184                     default:
185                         // FIXME: May be not a good idea to throw.
186                         throw new IllegalArgumentException("Unhandled modification type " + mod.getModificationType());
187                 }
188             }
189             chainingDelegate.notifyAfterOnDataTreeChanged(changes);
190         }
191     }
192 }
193 */