Support for LearntVpnVipToPort in netvirt
[unimgr.git] / netvirt / src / main / java / org / opendaylight / unimgr / mef / netvirt / DataWaitListener.java
1 /*
2  * Copyright (c) 2016 Hewlett Packard Enterprise, Co. 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.unimgr.mef.netvirt;
10
11 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
12 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
13 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
14 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
15 import org.opendaylight.unimgr.api.UnimgrDataTreeChangeListener;
16 import org.opendaylight.yangtools.concepts.ListenerRegistration;
17 import org.opendaylight.yangtools.yang.binding.DataObject;
18 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
19 import org.slf4j.Logger;
20 import org.slf4j.LoggerFactory;
21
22 import com.google.common.base.Optional;
23
24 @SuppressWarnings("rawtypes")
25 public class DataWaitListener<D extends DataObject> extends UnimgrDataTreeChangeListener<D> {
26     private static final Logger Log = LoggerFactory.getLogger(DataWaitListener.class);
27     InstanceIdentifier<D> objectIdentifierId;
28     private ListenerRegistration<DataWaitListener> dataWaitListenerRegistration;
29     private Boolean dataAvailable = false;
30     private final Object lockDataAvailable = new Object();
31     private int maxRetries;
32     LogicalDatastoreType logicalDatastoreType;
33     DataWaitGetter<D> getData;
34     private final long waitMillisec = 1000;
35
36     public DataWaitListener(final DataBroker dataBroker, final InstanceIdentifier<D> objectIdentifierId,
37             int maxRetiries, LogicalDatastoreType logicalDatastoreType, final DataWaitGetter<D> getData) {
38         super(dataBroker);
39         this.objectIdentifierId = objectIdentifierId;
40         this.maxRetries = maxRetiries;
41         this.logicalDatastoreType = logicalDatastoreType;
42         this.getData = getData;
43         registerListener();
44     }
45
46     @SuppressWarnings("unchecked")
47     public void registerListener() {
48         try {
49             final DataTreeIdentifier<D> dataTreeIid = new DataTreeIdentifier<D>(logicalDatastoreType,
50                     objectIdentifierId);
51             dataWaitListenerRegistration = dataBroker.registerDataTreeChangeListener(dataTreeIid, this);
52             Log.info("DataWaitListener created and registered");
53         } catch (final Exception e) {
54             Log.error("DataWaitListener DataChange listener registration failed !", e);
55             throw new IllegalStateException("DataWaitListener registration Listener failed.", e);
56         }
57     }
58
59     @Override
60     public void close() throws Exception {
61         dataWaitListenerRegistration.close();
62     }
63
64     @Override
65     public void add(DataTreeModification<D> newDataObject) {
66         if (newDataObject.getRootPath() != null && newDataObject.getRootNode() != null) {
67             Log.info("data {} created", newDataObject.getRootNode().getIdentifier());
68         }
69         synchronized (lockDataAvailable) {
70             lockDataAvailable.notifyAll();
71         }
72     }
73
74     @Override
75     public void remove(DataTreeModification<D> removedDataObject) {
76         if (removedDataObject.getRootPath() != null && removedDataObject.getRootNode() != null) {
77             Log.info("data {} deleted", removedDataObject.getRootNode().getIdentifier());
78         }
79         synchronized (lockDataAvailable) {
80             lockDataAvailable.notifyAll();
81         }
82     }
83
84     @Override
85     public void update(DataTreeModification<D> modifiedDataObject) {
86         if (modifiedDataObject.getRootPath() != null && modifiedDataObject.getRootNode() != null) {
87             Log.info("data {} updated", modifiedDataObject.getRootNode().getIdentifier());
88         }
89         synchronized (lockDataAvailable) {
90             lockDataAvailable.notifyAll();
91         }
92     }
93
94     private boolean dataAvailable() {
95         if (getData() != null) {
96             return true;
97         }
98         return false;
99     }
100
101     public boolean waitForData() {
102         return waitForData(maxRetries);
103     }
104
105     public boolean waitForClean() {
106         return waitForClean(maxRetries);
107     }
108
109     public Object getData() {
110         Optional<D> objectInstance = MdsalUtils.read(dataBroker, logicalDatastoreType, objectIdentifierId);
111         if (!objectInstance.isPresent()) {
112             Log.debug("Data for {} doesn't exist, waiting more", objectIdentifierId);
113             return null;
114         }
115         return getData.get(objectInstance.get());
116     }
117
118     public boolean waitForData(int retry) {
119         synchronized (lockDataAvailable) {
120             dataAvailable = dataAvailable();
121             if (dataAvailable == true) {
122                 return true;
123             } else if (retry <= 0) {
124                 return false;
125             }
126             safeWaitLock();
127         }
128         return waitForData(--retry);
129     }
130
131     public boolean waitForClean(int retry) {
132         synchronized (lockDataAvailable) {
133             dataAvailable = dataAvailable();
134             if (dataAvailable == false) {
135                 return true;
136             } else if (retry <= 0) {
137                 return false;
138             }
139             safeWaitLock();
140         }
141         return waitForClean(--retry);
142     }
143
144     private void safeWaitLock() {
145         try {
146             lockDataAvailable.wait(waitMillisec);
147         } catch (InterruptedException e1) {
148         }
149     }
150 }