Bug 8346 - Conflicting modification for vpnNextHops.
[netvirt.git] / vpnservice / vpnmanager / vpnmanager-impl / src / main / java / org / opendaylight / netvirt / vpnmanager / AbstractDataChangeListener.java
1 /*
2  * Copyright (c) 2015 - 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 package org.opendaylight.netvirt.vpnmanager;
9
10 import com.google.common.base.Preconditions;
11 import java.util.Collections;
12 import java.util.Map;
13 import java.util.Set;
14 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
15 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
16 import org.opendaylight.yangtools.yang.binding.DataObject;
17 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20
21 /**
22  * AbstractDataChangeListener implemented basic {@link DataChangeListener} processing for
23  * VPN related Data Objects.
24  */
25 public abstract class AbstractDataChangeListener<T extends DataObject> implements DataChangeListener {
26
27     protected final Class<T> clazz;
28
29     private static final Logger LOG = LoggerFactory.getLogger(AbstractDataChangeListener.class);
30
31     /**
32      * Creates an instance.
33      *
34      * @param clazz The class for which the data change event is received.
35      */
36     public AbstractDataChangeListener(Class<T> clazz) {
37         this.clazz = Preconditions.checkNotNull(clazz, "Class can not be null!");
38     }
39
40     @Override
41     // TODO Clean up the exception handling
42     @SuppressWarnings("checkstyle:IllegalCatch")
43     public void onDataChanged(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changeEvent) {
44         try {
45             Preconditions.checkNotNull(changeEvent, "Async ChangeEvent can not be null!");
46
47             /* All DataObjects for create */
48             final Map<InstanceIdentifier<?>, DataObject> createdData = changeEvent.getCreatedData() != null
49                     ? changeEvent.getCreatedData() : Collections.emptyMap();
50             /* All DataObjects for remove */
51             final Set<InstanceIdentifier<?>> removeData = changeEvent.getRemovedPaths() != null
52                     ? changeEvent.getRemovedPaths() : Collections.emptySet();
53             /* All DataObjects for updates */
54             final Map<InstanceIdentifier<?>, DataObject> updateData = changeEvent.getUpdatedData() != null
55                     ? changeEvent.getUpdatedData() : Collections.emptyMap();
56             /* All Original DataObjects */
57             final Map<InstanceIdentifier<?>, DataObject> originalData = changeEvent.getOriginalData() != null
58                     ? changeEvent.getOriginalData() : Collections.emptyMap();
59
60             this.createData(createdData);
61             this.updateData(updateData, originalData);
62             this.removeData(removeData, originalData);
63         } catch (Throwable e) {
64             LOG.error("failed to handle dcn ", e);
65         }
66     }
67
68     @SuppressWarnings("unchecked")
69     private void createData(final Map<InstanceIdentifier<?>, DataObject> createdData) {
70         for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : createdData.entrySet()) {
71             InstanceIdentifier<?> key = entry.getKey();
72             if (clazz.equals(key.getTargetType())) {
73                 DataObject value = entry.getValue();
74                 if (value != null) {
75                     this.add(key.firstIdentifierOf(clazz), (T) value);
76                 }
77             }
78         }
79     }
80
81     @SuppressWarnings("unchecked")
82     private void updateData(final Map<InstanceIdentifier<?>, DataObject> updateData,
83             final Map<InstanceIdentifier<?>, DataObject> originalData) {
84         for (Map.Entry<InstanceIdentifier<?>, DataObject> entry : updateData.entrySet()) {
85             InstanceIdentifier<?> key = entry.getKey();
86             if (clazz.equals(key.getTargetType())) {
87                 InstanceIdentifier<T> updateKeyIdent = key.firstIdentifierOf(clazz);
88                 final DataObject value = entry.getValue();
89                 final DataObject original = originalData.get(key);
90                 if (value != null && original != null) {
91                     this.update(updateKeyIdent, (T) original, (T) value);
92                 }
93             }
94         }
95     }
96
97     @SuppressWarnings("unchecked")
98     private void removeData(final Set<InstanceIdentifier<?>> removeData,
99         final Map<InstanceIdentifier<?>, DataObject> originalData) {
100
101         for (InstanceIdentifier<?> key : removeData) {
102             if (clazz.equals(key.getTargetType())) {
103                 final InstanceIdentifier<T> ident = key.firstIdentifierOf(clazz);
104                 final DataObject removeValue = originalData.get(key);
105                 this.remove(ident, (T) removeValue);
106             }
107         }
108     }
109
110     protected abstract void remove(InstanceIdentifier<T> identifier, T del);
111
112     protected abstract void update(InstanceIdentifier<T> identifier, T original, T update);
113
114     protected abstract void add(InstanceIdentifier<T> identifier, T add);
115
116 }
117
118