Merge "BUG-190 Simplify reconnect logic in protocol-framework."
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / messages / DataChanged.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, 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
9 package org.opendaylight.controller.cluster.datastore.messages;
10
11 import org.opendaylight.controller.cluster.datastore.node.NormalizedNodeToNodeCodec;
12 import org.opendaylight.controller.cluster.datastore.utils.InstanceIdentifierUtils;
13 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
14 import org.opendaylight.controller.protobuff.messages.common.NormalizedNodeMessages;
15 import org.opendaylight.controller.protobuff.messages.datachange.notification.DataChangeListenerMessages;
16 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
17 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
18 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
19
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27
28 public class DataChanged implements SerializableMessage {
29     public static final Class SERIALIZABLE_CLASS =
30         DataChangeListenerMessages.DataChanged.class;
31     final private SchemaContext schemaContext;
32     private final AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>>
33         change;
34
35
36
37     public DataChanged(SchemaContext schemaContext,
38         AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> change) {
39         this.change = change;
40         this.schemaContext = schemaContext;
41     }
42
43
44     public AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> getChange() {
45         return change;
46     }
47
48
49     private NormalizedNodeMessages.Node convertToNodeTree(
50         NormalizedNode<?, ?> normalizedNode) {
51
52         return new NormalizedNodeToNodeCodec(schemaContext)
53             .encode(YangInstanceIdentifier.builder().build(), normalizedNode)
54             .getNormalizedNode();
55
56     }
57
58     private Iterable<NormalizedNodeMessages.InstanceIdentifier> convertToRemovePaths(
59         Set<YangInstanceIdentifier> removedPaths) {
60         final Set<NormalizedNodeMessages.InstanceIdentifier> removedPathInstanceIds = new HashSet<>();
61         for (YangInstanceIdentifier id : removedPaths) {
62             removedPathInstanceIds.add(InstanceIdentifierUtils.toSerializable(id));
63         }
64         return new Iterable<NormalizedNodeMessages.InstanceIdentifier>() {
65             public Iterator<NormalizedNodeMessages.InstanceIdentifier> iterator() {
66                 return removedPathInstanceIds.iterator();
67             }
68         };
69
70     }
71
72     private NormalizedNodeMessages.NodeMap convertToNodeMap(
73         Map<YangInstanceIdentifier, NormalizedNode<?, ?>> data) {
74         NormalizedNodeToNodeCodec normalizedNodeToNodeCodec =
75             new NormalizedNodeToNodeCodec(schemaContext);
76         NormalizedNodeMessages.NodeMap.Builder nodeMapBuilder =
77             NormalizedNodeMessages.NodeMap.newBuilder();
78         NormalizedNodeMessages.NodeMapEntry.Builder builder =
79             NormalizedNodeMessages.NodeMapEntry.newBuilder();
80         for (Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> entry : data
81             .entrySet()) {
82
83
84             NormalizedNodeMessages.InstanceIdentifier instanceIdentifier =
85                 InstanceIdentifierUtils.toSerializable(entry.getKey());
86
87             builder.setInstanceIdentifierPath(instanceIdentifier)
88                 .setNormalizedNode(normalizedNodeToNodeCodec
89                     .encode(entry.getKey(), entry.getValue())
90                     .getNormalizedNode());
91             nodeMapBuilder.addMapEntries(builder.build());
92         }
93         return nodeMapBuilder.build();
94     }
95
96
97     @Override
98     public Object toSerializable() {
99         return DataChangeListenerMessages.DataChanged.newBuilder()
100             .addAllRemovedPaths(convertToRemovePaths(change.getRemovedPaths()))
101             .setCreatedData(convertToNodeMap(change.getCreatedData()))
102             .setOriginalData(convertToNodeMap(change.getOriginalData()))
103             .setUpdatedData(convertToNodeMap(change.getUpdatedData()))
104             .setOriginalSubTree(convertToNodeTree(change.getOriginalSubtree()))
105             .setUpdatedSubTree(convertToNodeTree(change.getUpdatedSubtree()))
106             .build();
107     }
108
109     public static DataChanged fromSerialize(SchemaContext sc, Object message,
110         YangInstanceIdentifier pathId) {
111         DataChangeListenerMessages.DataChanged dataChanged =
112             (DataChangeListenerMessages.DataChanged) message;
113         DataChangedEvent event = new DataChangedEvent(sc);
114         if (dataChanged.getCreatedData() != null && dataChanged.getCreatedData()
115             .isInitialized()) {
116             event.setCreatedData(dataChanged.getCreatedData());
117         }
118         if (dataChanged.getOriginalData() != null && dataChanged
119             .getOriginalData().isInitialized()) {
120             event.setOriginalData(dataChanged.getOriginalData());
121         }
122
123         if (dataChanged.getUpdatedData() != null && dataChanged.getUpdatedData()
124             .isInitialized()) {
125             event.setUpdateData(dataChanged.getUpdatedData());
126         }
127
128         if (dataChanged.getOriginalSubTree() != null && dataChanged
129             .getOriginalSubTree().isInitialized()) {
130             event.setOriginalSubtree(dataChanged.getOriginalSubTree(), pathId);
131         }
132
133         if (dataChanged.getUpdatedSubTree() != null && dataChanged
134             .getUpdatedSubTree().isInitialized()) {
135             event.setUpdatedSubtree(dataChanged.getOriginalSubTree(), pathId);
136         }
137
138         if (dataChanged.getRemovedPathsList() != null && !dataChanged
139             .getRemovedPathsList().isEmpty()) {
140             event.setRemovedPaths(dataChanged.getRemovedPathsList());
141         }
142
143         return new DataChanged(sc, event);
144
145     }
146
147     static class DataChangedEvent implements
148         AsyncDataChangeEvent<YangInstanceIdentifier, NormalizedNode<?, ?>> {
149         private final SchemaContext schemaContext;
150         private Map<YangInstanceIdentifier, NormalizedNode<?, ?>> createdData;
151         private final NormalizedNodeToNodeCodec nodeCodec;
152         private Map<YangInstanceIdentifier, NormalizedNode<?, ?>> updatedData;
153         private Map<YangInstanceIdentifier, NormalizedNode<?, ?>> originalData;
154         private NormalizedNode<?, ?> originalSubTree;
155         private NormalizedNode<?, ?> updatedSubTree;
156         private Set<YangInstanceIdentifier> removedPathIds;
157
158         DataChangedEvent(SchemaContext schemaContext) {
159             this.schemaContext = schemaContext;
160             nodeCodec = new NormalizedNodeToNodeCodec(schemaContext);
161         }
162
163         @Override
164         public Map<YangInstanceIdentifier, NormalizedNode<?, ?>> getCreatedData() {
165             if(createdData == null){
166                 return Collections.emptyMap();
167             }
168             return createdData;
169         }
170
171         DataChangedEvent setCreatedData(
172             NormalizedNodeMessages.NodeMap nodeMap) {
173             this.createdData = convertNodeMapToMap(nodeMap);
174             return this;
175         }
176
177         private Map<YangInstanceIdentifier, NormalizedNode<?, ?>> convertNodeMapToMap(
178             NormalizedNodeMessages.NodeMap nodeMap) {
179             Map<YangInstanceIdentifier, NormalizedNode<?, ?>> mapEntries =
180                 new HashMap<YangInstanceIdentifier, NormalizedNode<?, ?>>();
181             for (NormalizedNodeMessages.NodeMapEntry nodeMapEntry : nodeMap
182                 .getMapEntriesList()) {
183                 YangInstanceIdentifier id = InstanceIdentifierUtils
184                     .fromSerializable(nodeMapEntry.getInstanceIdentifierPath());
185                 mapEntries.put(id,
186                     nodeCodec.decode(id, nodeMapEntry.getNormalizedNode()));
187             }
188             return mapEntries;
189         }
190
191
192         @Override
193         public Map<YangInstanceIdentifier, NormalizedNode<?, ?>> getUpdatedData() {
194             if(updatedData == null){
195                 return Collections.emptyMap();
196             }
197             return updatedData;
198         }
199
200         DataChangedEvent setUpdateData(NormalizedNodeMessages.NodeMap nodeMap) {
201             this.updatedData = convertNodeMapToMap(nodeMap);
202             return this;
203         }
204
205         @Override
206         public Set<YangInstanceIdentifier> getRemovedPaths() {
207             if (removedPathIds == null) {
208                 return Collections.emptySet();
209             }
210             return removedPathIds;
211         }
212
213         public DataChangedEvent setRemovedPaths(List<NormalizedNodeMessages.InstanceIdentifier> removedPaths) {
214             Set<YangInstanceIdentifier> removedIds = new HashSet<>();
215             for (NormalizedNodeMessages.InstanceIdentifier path : removedPaths) {
216                 removedIds.add(InstanceIdentifierUtils.fromSerializable(path));
217             }
218             this.removedPathIds = removedIds;
219             return this;
220         }
221
222         @Override
223         public Map<YangInstanceIdentifier, NormalizedNode<?, ?>> getOriginalData() {
224             if (originalData == null) {
225                 Collections.emptyMap();
226             }
227             return originalData;
228         }
229
230         DataChangedEvent setOriginalData(
231             NormalizedNodeMessages.NodeMap nodeMap) {
232             this.originalData = convertNodeMapToMap(nodeMap);
233             return this;
234         }
235
236         @Override
237         public NormalizedNode<?, ?> getOriginalSubtree() {
238             return originalSubTree;
239         }
240
241         DataChangedEvent setOriginalSubtree(NormalizedNodeMessages.Node node,
242             YangInstanceIdentifier instanceIdentifierPath) {
243             originalSubTree = nodeCodec.decode(instanceIdentifierPath, node);
244             return this;
245         }
246
247         @Override
248         public NormalizedNode<?, ?> getUpdatedSubtree() {
249             return updatedSubTree;
250         }
251
252         DataChangedEvent setUpdatedSubtree(NormalizedNodeMessages.Node node,
253             YangInstanceIdentifier instanceIdentifierPath) {
254             updatedSubTree = nodeCodec.decode(instanceIdentifierPath, node);
255             return this;
256         }
257
258
259     }
260
261
262
263 }