MDSAL-API Migration
[genius.git] / mdsalutil / mdsalutil-api / src / main / java / org / opendaylight / genius / datastoreutils / listeners / DataTreeEventCallbackRegistrar.java
1 /*
2  * Copyright (c) 2017 Red Hat, Inc. 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 package org.opendaylight.genius.datastoreutils.listeners;
9
10 import static org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
11
12 import com.google.common.annotations.Beta;
13 import java.time.Duration;
14 import java.util.function.BiConsumer;
15 import java.util.function.BiFunction;
16 import java.util.function.Consumer;
17 import java.util.function.Function;
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
20 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
21 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
22 import org.opendaylight.yangtools.yang.binding.DataObject;
23 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
24
25 /**
26  * Service to register callbacks for data tree changes for a fixed instance.
27  *
28  * <p>The current implementation assumes that the expected instance will eventually be added, updated or deleted; if
29  * that never happens in the first place, then an internal data structure could fill up and theoretically lead to OOM
30  * problems if you do not specify a timeout.  Likewise, if {@link NextAction#CALL_AGAIN} is used but no next event
31  * matching path ever occurs.  In the "Full Sync Upgrade" scenario, for which this utility was originally created, this
32  * is not a problem, as we are sure the subsequent changes are about to happen (just out of originally expected order).
33  *
34  * @author Josh original idea and design feedback
35  * @author Michael Vorburger.ch API design and first implementation
36  * @author Tom Pantelis review and feedback on concurrency issue in implementation
37  */
38 @Beta // we may still change this API
39 @NonNullByDefault
40 public interface DataTreeEventCallbackRegistrar {
41
42     enum NextAction {
43         /**
44          * When the callback function returns this, then it is unregistered and will
45          * never be invoked anymore.
46          */
47         UNREGISTER,
48
49         /**
50          * When the callback function returns this, then it will be called again for
51          * add, update OR remove on the given store &amp; path.
52          */
53         CALL_AGAIN
54     }
55
56     <T extends DataObject> void onAdd(LogicalDatastoreType store, InstanceIdentifier<T> path,
57             Function<T, NextAction> callback,
58             Duration timeoutDuration, Consumer<DataTreeIdentifier<T>> timedOutCallback);
59
60     <T extends DataObject> void onAdd(LogicalDatastoreType store, InstanceIdentifier<T> path,
61             Function<T, NextAction> callback);
62
63     default <T extends DataObject> void onAdd(LogicalDatastoreType store, InstanceIdentifier<T> path,
64             Consumer<T> callback) {
65         onAdd(store, path, t -> {
66             callback.accept(t);
67             return UNREGISTER;
68         });
69     }
70
71     default <T extends DataObject> void onAdd(LogicalDatastoreType store, InstanceIdentifier<T> path,
72             Consumer<T> callback, Duration timeoutDuration, Consumer<DataTreeIdentifier<T>> timedOutCallback) {
73         onAdd(store, path, t -> {
74             callback.accept(t);
75             return UNREGISTER;
76         }, timeoutDuration, timedOutCallback);
77     }
78
79
80     <T extends DataObject> void onUpdate(LogicalDatastoreType store, InstanceIdentifier<T> path,
81             BiFunction<T, T, NextAction> callback,
82             Duration timeoutDuration, Consumer<DataTreeIdentifier<T>> timedOutCallback);
83
84     <T extends DataObject> void onUpdate(LogicalDatastoreType store, InstanceIdentifier<T> path,
85             BiFunction<T, T, NextAction> callback);
86
87     default <T extends DataObject> void onUpdate(LogicalDatastoreType store, InstanceIdentifier<T> path,
88             BiConsumer<T, T> callback) {
89         onUpdate(store, path, (t1, t2) -> {
90             callback.accept(t1, t2);
91             return UNREGISTER;
92         });
93     }
94
95     default <T extends DataObject> void onUpdate(LogicalDatastoreType store, InstanceIdentifier<T> path,
96             BiConsumer<T, T> callback,
97             Duration timeoutDuration, Consumer<DataTreeIdentifier<T>> timedOutCallback) {
98         onUpdate(store, path, (t1, t2) -> {
99             callback.accept(t1, t2);
100             return UNREGISTER;
101         }, timeoutDuration, timedOutCallback);
102     }
103
104
105     <T extends DataObject> void onAddOrUpdate(LogicalDatastoreType store, InstanceIdentifier<T> path,
106             BiFunction<@Nullable T, T, NextAction> callback,
107             Duration timeoutDuration, Consumer<DataTreeIdentifier<T>> timedOutCallback);
108
109     /**
110      * Call back when expected instance was added or updated, with NextAction support.
111      * @param store the expected data store
112      * @param path the path to watch for changes on
113      * @param callback the callback as {@link BiFunction}, where the first argument is the data before the update
114      *             or null in case of an add, the second argument is the data after the update (or add; never null),
115      *             and the returned value determines whether to keep listening for changes or not anymore.
116      */
117     <T extends DataObject> void onAddOrUpdate(LogicalDatastoreType store, InstanceIdentifier<T> path,
118                                               BiFunction<@Nullable T, T, NextAction> callback);
119
120     /**
121      * Call back when expected instance was added or updated, with implicit {@link NextAction#UNREGISTER}.
122      * See {@link #onAddOrUpdate(LogicalDatastoreType, InstanceIdentifier, BiFunction)} for more details.
123      * @param <T>
124      *            DataObject subclass
125      */
126     default <T extends DataObject> void onAddOrUpdate(LogicalDatastoreType store, InstanceIdentifier<T> path,
127                                                  BiConsumer<@Nullable T, T> callback) {
128         onAddOrUpdate(store, path, (t1, t2) -> {
129             callback.accept(t1, t2);
130             return UNREGISTER;
131         });
132     }
133
134     default <T extends DataObject> void onAddOrUpdate(LogicalDatastoreType store, InstanceIdentifier<T> path,
135             BiConsumer<@Nullable T, T> callback,
136             Duration timeoutDuration, Consumer<DataTreeIdentifier<T>> timedOutCallback) {
137         onAddOrUpdate(store, path, (t1, t2) -> {
138             callback.accept(t1, t2);
139             return UNREGISTER;
140         }, timeoutDuration, timedOutCallback);
141     }
142
143
144     <T extends DataObject> void onRemove(LogicalDatastoreType store, InstanceIdentifier<T> path,
145             Function<T, NextAction> callback,
146             Duration timeoutDuration, Consumer<DataTreeIdentifier<T>> timedOutCallback);
147
148     <T extends DataObject> void onRemove(LogicalDatastoreType store, InstanceIdentifier<T> path,
149             Function<T, NextAction> callback);
150
151     default <T extends DataObject> void onRemove(LogicalDatastoreType store, InstanceIdentifier<T> path,
152             Consumer<T> callback) {
153         onRemove(store, path, t -> {
154             callback.accept(t);
155             return UNREGISTER;
156         });
157     }
158
159     default <T extends DataObject> void onRemove(LogicalDatastoreType store, InstanceIdentifier<T> path,
160             Consumer<T> callback,
161             Duration timeoutDuration, Consumer<DataTreeIdentifier<T>> timedOutCallback) {
162         onRemove(store, path, t -> {
163             callback.accept(t);
164             return UNREGISTER;
165         }, timeoutDuration, timedOutCallback);
166     }
167
168 }