Ensure termination points are correctly deleted
[unimgr.git] / impl / src / main / java / org / opendaylight / unimgr / impl / UnimgrUtils.java
1 /*
2  * Copyright (c) 2015 CableLabs 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.unimgr.impl;
9
10 import java.net.InetAddress;
11 import java.net.UnknownHostException;
12 import java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.HashSet;
15 import java.util.List;
16 import java.util.Map;
17 import java.util.Map.Entry;
18 import java.util.Set;
19 import java.util.UUID;
20
21 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
22 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
23 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
24 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
25 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
26 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
27 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
28 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
29 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentationBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.Evc;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.EvcAugmentation;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.EvcAugmentationBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.Uni;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.UniAugmentation;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.UniAugmentationBuilder;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.evc.UniDest;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.evc.UniDestBuilder;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.evc.UniDestKey;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.evc.UniSource;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.evc.UniSourceBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.unimgr.rev151012.evc.UniSourceKey;
67 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
68 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
69 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
70 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
71 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
72 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
73 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.LinkBuilder;
74 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
75 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
76 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
77 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
78 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
79 import org.opendaylight.yangtools.yang.binding.DataObject;
80 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
81 import org.slf4j.Logger;
82 import org.slf4j.LoggerFactory;
83
84 import com.google.common.base.Optional;
85 import com.google.common.collect.ImmutableBiMap;
86 import com.google.common.collect.Lists;
87 import com.google.common.util.concurrent.CheckedFuture;
88
89 public class UnimgrUtils {
90
91     private static final Logger LOG = LoggerFactory.getLogger(UnimgrUtils.class);
92
93     public static void createBridgeNode(DataBroker dataBroker,
94                                         Node ovsdbNode,
95                                         UniAugmentation uni,
96                                         String bridgeName) {
97         LOG.info("Creating a bridge on node {}", ovsdbNode.getNodeId().getValue());
98         InstanceIdentifier<Node> ovsdbNodeIid = uni.getOvsdbNodeRef().getValue().firstIdentifierOf(Node.class);
99         if (ovsdbNodeIid != null) {
100             NodeBuilder bridgeNodeBuilder = new NodeBuilder();
101             InstanceIdentifier<Node> bridgeIid = UnimgrMapper.createOvsdbBridgeNodeIid(ovsdbNode,
102                                                                                        bridgeName);
103             NodeId bridgeNodeId = new NodeId(ovsdbNode.getNodeId()
104                                            + UnimgrConstants.DEFAULT_BRIDGE_NODE_ID_SUFFIX
105                                            + bridgeName);
106             bridgeNodeBuilder.setNodeId(bridgeNodeId);
107             OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
108             ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
109             ovsdbBridgeAugmentationBuilder.setProtocolEntry(UnimgrUtils.createMdsalProtocols());
110             OvsdbNodeRef ovsdbNodeRef = new OvsdbNodeRef(ovsdbNodeIid);
111             ovsdbBridgeAugmentationBuilder.setManagedBy(ovsdbNodeRef);
112             bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
113             WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
114             transaction.put(LogicalDatastoreType.CONFIGURATION, bridgeIid, bridgeNodeBuilder.build());
115             transaction.submit();
116         } else {
117             LOG.info("OvsdbNodeRef is null");
118         }
119     }
120
121     public static void createBridgeNode(DataBroker dataBroker,
122                                         InstanceIdentifier<Node> ovsdbNodeIid,
123                                         UniAugmentation uni,
124                                         String bridgeName) {
125         LOG.info("Creating a bridge on node {}", ovsdbNodeIid);
126         if (ovsdbNodeIid != null) {
127             NodeBuilder bridgeNodeBuilder = new NodeBuilder();
128             Optional<Node> optionalOvsdbNode = UnimgrUtils.readNode(dataBroker,
129                                                                     LogicalDatastoreType.OPERATIONAL,
130                                                                     ovsdbNodeIid);
131             if (optionalOvsdbNode.isPresent()) {
132                 Node ovsdbNode = optionalOvsdbNode.get();
133                 InstanceIdentifier<Node> bridgeIid = UnimgrMapper.createOvsdbBridgeNodeIid(ovsdbNode,
134                                                                                            bridgeName);
135                 NodeId bridgeNodeId = new NodeId(ovsdbNode.getNodeId().getValue()
136                                                + UnimgrConstants.DEFAULT_BRIDGE_NODE_ID_SUFFIX
137                                                + bridgeName);
138                 bridgeNodeBuilder.setNodeId(bridgeNodeId);
139                 OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
140                 ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
141                 ovsdbBridgeAugmentationBuilder.setProtocolEntry(UnimgrUtils.createMdsalProtocols());
142                 OvsdbNodeRef ovsdbNodeRef = new OvsdbNodeRef(ovsdbNodeIid);
143                 ovsdbBridgeAugmentationBuilder.setManagedBy(ovsdbNodeRef);
144                 bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class,
145                                                   ovsdbBridgeAugmentationBuilder.build());
146                 WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
147                 transaction.put(LogicalDatastoreType.CONFIGURATION,
148                                 bridgeIid,
149                                 bridgeNodeBuilder.build());
150                 transaction.submit();
151             }
152         } else {
153             LOG.info("OvsdbNodeRef is null");
154         }
155     }
156
157     public static List<ControllerEntry> createControllerEntries(String targetString) {
158         List<ControllerEntry> controllerEntries = new ArrayList<ControllerEntry>();
159         ControllerEntryBuilder controllerEntryBuilder = new ControllerEntryBuilder();
160         controllerEntryBuilder.setTarget(new Uri(targetString));
161         controllerEntries.add(controllerEntryBuilder.build());
162         return controllerEntries;
163     }
164
165     public static void createGreTunnel(DataBroker dataBroker,
166                                        Uni source,
167                                        Uni destination,
168                                        Node bridgeNode,
169                                        String bridgeName,
170                                        String portName) {
171         InstanceIdentifier<TerminationPoint> tpIid =
172                                                  UnimgrMapper.getTerminationPointIid(bridgeNode,
173                                                                                      portName);
174         OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder =
175                                                      new OvsdbTerminationPointAugmentationBuilder();
176         tpAugmentationBuilder.setName(portName);
177         ArrayList<Options> options = Lists.newArrayList();
178         OptionsKey optionKey = new OptionsKey("remote_ip");
179         Options destinationIp = new OptionsBuilder()
180                                         .setOption(destination.getIpAddress().getIpv4Address().getValue())
181                                         .setKey(optionKey).setValue(destination.getIpAddress().getIpv4Address().getValue())
182                                         .build();
183         options.add(destinationIp);
184         tpAugmentationBuilder.setOptions(options);
185         tpAugmentationBuilder.setInterfaceType(SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.get("gre"));
186         TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
187         tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
188         tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
189         WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
190         transaction.put(LogicalDatastoreType.CONFIGURATION,
191                         tpIid,
192                         tpBuilder.build());
193         transaction.submit();
194     }
195
196     public static List<ProtocolEntry> createMdsalProtocols() {
197         List<ProtocolEntry> protocolList = new ArrayList<ProtocolEntry>();
198         ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
199                 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
200         protocolList.add(new ProtocolEntryBuilder().
201                 setProtocol((Class<? extends OvsdbBridgeProtocolBase>) mapper.get("OpenFlow13")).build());
202         return protocolList;
203     }
204
205     public static OvsdbBridgeAugmentation createOvsdbBridgeAugmentation(Uni uni) throws Exception {
206         OvsdbNodeRef ovsdbNodeRef = uni.getOvsdbNodeRef();
207         if (ovsdbNodeRef != null && ovsdbNodeRef.getValue() != null) {
208             UUID bridgeUuid = UUID.randomUUID();
209             OvsdbBridgeAugmentation ovsdbBridge = new OvsdbBridgeAugmentationBuilder()
210                                                         .setBridgeName(
211                                                                 new OvsdbBridgeName(UnimgrConstants.DEFAULT_BRIDGE_NAME))
212                                                         .setManagedBy(ovsdbNodeRef)
213                                                         .setBridgeUuid(
214                                                                 new Uuid(bridgeUuid.toString()))
215                                                         .build();
216             return ovsdbBridge;
217         } else {
218             throw new Exception("Ovsdb Node Reference does not exist !");
219         }
220     }
221
222     public static void createOvsdbNode(DataBroker dataBroker,
223                                        NodeId ovsdbNodeId,
224                                        Uni uni) {
225         InstanceIdentifier<Node> ovsdbNodeIid = UnimgrMapper.getOvsdbNodeIid(uni.getIpAddress());
226         try {
227             NodeKey ovsdbNodeKey = new NodeKey(ovsdbNodeId);
228             Node nodeData = new NodeBuilder()
229                                     .setNodeId(ovsdbNodeId)
230                                     .setKey(ovsdbNodeKey)
231                                     .addAugmentation(OvsdbNodeAugmentation.class,
232                                                      UnimgrUtils.createOvsdbNodeAugmentation(uni))
233                                     .build();
234             // Submit the node to the datastore
235             WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
236             transaction.put(LogicalDatastoreType.CONFIGURATION, ovsdbNodeIid, nodeData);
237             transaction.submit();
238             LOG.info("Created and submitted a new OVSDB node {}", nodeData.getNodeId());
239         } catch (Exception e) {
240             LOG.error("Exception while creating OvsdbNodeAugmentation, " + "Uni is null. Node Id: {}", ovsdbNodeId);
241         }
242     }
243
244     public static Node createOvsdbNode(DataBroker dataBroker,
245                                        UniAugmentation uni) {
246         NodeId ovsdbNodeId = new NodeId(createOvsdbNodeId(uni.getIpAddress()));
247         try {
248             InstanceIdentifier<Node> ovsdbNodeIid = UnimgrMapper.getOvsdbNodeIid(ovsdbNodeId);
249             NodeKey ovsdbNodeKey = new NodeKey(ovsdbNodeId);
250             Node nodeData = new NodeBuilder()
251                                     .setNodeId(ovsdbNodeId)
252                                     .setKey(ovsdbNodeKey)
253                                     .addAugmentation(OvsdbNodeAugmentation.class,
254                                                      UnimgrUtils.createOvsdbNodeAugmentation(uni))
255                                     .build();
256             // Submit the node to the datastore
257             WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
258             transaction.put(LogicalDatastoreType.CONFIGURATION, ovsdbNodeIid, nodeData);
259             transaction.submit();
260             LOG.info("Created and submitted a new OVSDB node {}", nodeData.getNodeId());
261             return nodeData;
262         } catch (Exception e) {
263             LOG.error("Exception while creating OvsdbNodeAugmentation, " + "Uni is null. Node Id: {}", ovsdbNodeId);
264         }
265         return null;
266     }
267
268     public static OvsdbNodeAugmentation createOvsdbNodeAugmentation(Uni uni) {
269         ConnectionInfo connectionInfos = new ConnectionInfoBuilder()
270                                                 .setRemoteIp(uni.getIpAddress())
271                                                 .setRemotePort(new PortNumber(UnimgrConstants.OVSDB_PORT))
272                                                 .build();
273         OvsdbNodeAugmentation ovsdbNode = new OvsdbNodeAugmentationBuilder()
274                                                 .setConnectionInfo(connectionInfos).build();
275         return ovsdbNode;
276     }
277
278     public static NodeId createOvsdbNodeId(IpAddress ipAddress) {
279         String nodeId = UnimgrConstants.OVSDB_PREFIX
280                         + ipAddress.getIpv4Address().getValue().toString()
281                         + ":"
282                         + UnimgrConstants.OVSDB_PORT;
283         return new NodeId(nodeId);
284     }
285
286     public static OvsdbTerminationPointAugmentation createOvsdbTerminationPointAugmentation(Uni uni) {
287         // we will use nodeId to set interface port id
288         VlanId vlanID = new VlanId(1);
289         OvsdbTerminationPointAugmentation terminationPoint = new OvsdbTerminationPointAugmentationBuilder()
290                                                                      .setName(UnimgrConstants.DEFAULT_INTERNAL_IFACE)
291                                                                      .setVlanTag(vlanID)
292                                                                      .setVlanMode(VlanMode.Access)
293                                                                      .build();
294         return terminationPoint;
295     }
296
297     public static void createTerminationPointNode(DataBroker dataBroker,
298                                                   Uni uni,
299                                                   Node bridgeNode,
300                                                   String bridgeName,
301                                                   String portName,
302                                                   String type) {
303         InstanceIdentifier<TerminationPoint> tpIid = UnimgrMapper
304                                                         .getTerminationPointIid(bridgeNode,
305                                                                                 portName);
306         OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder =
307                                                      new OvsdbTerminationPointAugmentationBuilder();
308         tpAugmentationBuilder.setName(portName);
309         if (type != null) {
310             tpAugmentationBuilder.setInterfaceType(SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP.get(type));
311         }
312         TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
313         tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
314         tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class,
315                                   tpAugmentationBuilder.build());
316         WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
317         transaction.put(LogicalDatastoreType.CONFIGURATION,
318                         tpIid,
319                         tpBuilder.build());
320         transaction.submit();
321     }
322
323     public <D extends org.opendaylight.yangtools.yang.binding.DataObject> boolean delete(
324             DataBroker dataBroker,
325             final LogicalDatastoreType store,
326             final InstanceIdentifier<D> path)  {
327         boolean result = false;
328         final WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
329         transaction.delete(store, path);
330         CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
331         try {
332             future.checkedGet();
333             result = true;
334         } catch (TransactionCommitFailedException e) {
335             LOG.warn("Failed to delete {} ", path, e);
336         }
337         return result;
338     }
339
340     public static CheckedFuture<Void,
341                                 TransactionCommitFailedException>
342                                 deleteTerminationPoint(DataBroker dataBroker,
343                                                        TerminationPoint terminationPoint,
344                                                        Node ovsdbNode) {
345         InstanceIdentifier<TerminationPoint> terminationPointPath =
346                                                  InstanceIdentifier
347                                                      .create(NetworkTopology.class)
348                                                      .child(Topology.class,
349                                                              new TopologyKey(UnimgrConstants.OVSDB_TOPOLOGY_ID))
350                                                      .child(Node.class,
351                                                             ovsdbNode.getKey())
352                                                      .child(TerminationPoint.class,
353                                                             terminationPoint.getKey());
354         final WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
355         transaction.delete(LogicalDatastoreType.CONFIGURATION, terminationPointPath);
356         transaction.delete(LogicalDatastoreType.OPERATIONAL, terminationPointPath);
357         transaction.submit();
358         CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
359         return future;
360     }
361
362     public static CheckedFuture<Void,
363                                 TransactionCommitFailedException>
364                                 deleteNode(DataBroker dataBroker,
365                                            InstanceIdentifier<?> genericNode,
366                                            LogicalDatastoreType store) {
367         LOG.info("Received a request to delete node {}", genericNode);
368         WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
369         transaction.delete(store, genericNode);
370         return transaction.submit();
371     }
372
373     public static void deletePath(DataBroker dataBroker, LogicalDatastoreType dataStoreType, InstanceIdentifier<?> iid) {
374         WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
375         transaction.delete(dataStoreType, iid);
376         CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
377         try {
378             future.checkedGet();
379         } catch (TransactionCommitFailedException e) {
380             LOG.warn("Failed to delete iidNode {} {}", e.getMessage(), iid);
381         }
382     }
383
384     public static void deletePath(DataBroker dataBroker, InstanceIdentifier<?> iid) {
385         WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
386         transaction.delete(LogicalDatastoreType.OPERATIONAL, iid);
387         transaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
388         CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
389         try {
390             future.checkedGet();
391         } catch (TransactionCommitFailedException e) {
392             LOG.warn("Failed to delete iidNode {} {}", e.getMessage(), iid);
393         }
394     }
395
396     public static <T extends DataObject> Map<InstanceIdentifier<T>,T> extract(
397             Map<InstanceIdentifier<?>, DataObject> changes, Class<T> klazz) {
398         Map<InstanceIdentifier<T>,T> result = new HashMap<InstanceIdentifier<T>,T>();
399         if (changes != null && changes.entrySet() != null) {
400             for (Entry<InstanceIdentifier<?>, DataObject> created : changes.entrySet()) {
401                 if (klazz.isInstance(created.getValue())) {
402                     @SuppressWarnings("unchecked")
403                     T value = (T) created.getValue();
404                     Class<?> type = created.getKey().getTargetType();
405                     if (type.equals(klazz)) {
406                         @SuppressWarnings("unchecked") // Actually checked above
407                         InstanceIdentifier<T> iid = (InstanceIdentifier<T>) created.getKey();
408                         result.put(iid, value);
409                     }
410                 }
411             }
412         }
413         return result;
414     }
415
416     public static <T extends DataObject> Map<InstanceIdentifier<T>,T> extractOriginal(
417             AsyncDataChangeEvent<InstanceIdentifier<?>,DataObject> changes,Class<T> klazz) {
418         return extract(changes.getOriginalData(),klazz);
419     }
420
421     public static <T extends DataObject> Set<InstanceIdentifier<T>> extractRemoved(
422             AsyncDataChangeEvent<InstanceIdentifier<?>,DataObject> changes,Class<T> klazz) {
423         Set<InstanceIdentifier<T>> result = new HashSet<InstanceIdentifier<T>>();
424         if (changes != null && changes.getRemovedPaths() != null) {
425             for (InstanceIdentifier<?> iid : changes.getRemovedPaths()) {
426                 if (iid.getTargetType().equals(klazz)) {
427                     @SuppressWarnings("unchecked") // Actually checked above
428                     InstanceIdentifier<T> iidn = (InstanceIdentifier<T>)iid;
429                     result.add(iidn);
430                 }
431             }
432         }
433         return result;
434     }
435
436     public static Optional<Node> findOvsdbNode(DataBroker dataBroker,
437                                                UniAugmentation uni) {
438         List<Node> ovsdbNodes = getOvsdbNodes(dataBroker);
439         Optional<Node> optionalOvsdb;
440         if (!ovsdbNodes.isEmpty()) {
441             for (Node ovsdbNode : ovsdbNodes) {
442                 OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode
443                                                                   .getAugmentation(OvsdbNodeAugmentation.class);
444                 if (ovsdbNodeAugmentation.getConnectionInfo()
445                                          .getRemoteIp()
446                                          .getIpv4Address()
447                         .equals(uni.getIpAddress().getIpv4Address())) {
448                     LOG.info("Found ovsdb node");
449                     optionalOvsdb = Optional.of(ovsdbNode);
450                     return optionalOvsdb;
451                 }
452             }
453         }
454         return Optional.absent();
455     }
456
457     public static Optional<Node> findUniNode(DataBroker dataBroker,
458                                              IpAddress ipAddress) {
459         List<Node> uniNodes = getUniNodes(dataBroker);
460         if (!uniNodes.isEmpty()) {
461             for (Node uniNode : uniNodes) {
462                 UniAugmentation uniAugmentation = uniNode.getAugmentation(UniAugmentation.class);
463                 if (uniAugmentation.getIpAddress().equals(ipAddress)) {
464                     LOG.info("Found Uni node");
465                     return Optional.of(uniNode);
466                 }
467             }
468         }
469         return Optional.absent();
470     }
471
472     public static ConnectionInfo getConnectionInfo(DataBroker dataBroker,
473                                                    NodeId ovsdbNodeId) {
474         InstanceIdentifier<Node> nodeIid = UnimgrMapper.getOvsdbNodeIid(ovsdbNodeId);
475         Optional<Node> node = readNode(dataBroker,
476                                        LogicalDatastoreType.OPERATIONAL,
477                                        nodeIid);
478         if (node.isPresent()) {
479             Node ovsdbNode = node.get();
480             OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode
481                                                               .getAugmentation(OvsdbNodeAugmentation.class);
482             ConnectionInfo connectionInfo = ovsdbNodeAugmentation.getConnectionInfo();
483             return connectionInfo;
484         } else {
485             return null;
486         }
487     }
488
489     public static List<Link> getEvcLinks(DataBroker dataBroker,
490                                          IpAddress ipAddress) {
491         List<Link> evcLinks = new ArrayList<>();
492         InstanceIdentifier<Topology> evcTopology = UnimgrMapper.getEvcTopologyIid();
493         Topology topology = UnimgrUtils.read(dataBroker,
494                                              LogicalDatastoreType.OPERATIONAL,
495                                              evcTopology);
496         if (topology != null && topology.getLink() != null) {
497             for (Link link : topology.getLink()) {
498                 EvcAugmentation evcAugmentation = link.getAugmentation(EvcAugmentation.class);
499                 if (evcAugmentation != null) {
500                     evcLinks.add(link);
501                 }
502             }
503         }
504         return evcLinks;
505     }
506
507     public static IpAddress getLocalIp() {
508         String ip;
509         try {
510             ip = InetAddress.getLocalHost().getHostAddress();
511             Ipv4Address ipv4 = new Ipv4Address(ip);
512             IpAddress ipAddress = new IpAddress(ipv4);
513             return ipAddress;
514         } catch (UnknownHostException e) {
515             LOG.info("Unable to retrieve controller's ip address, using loopback.");
516         }
517         return new IpAddress(UnimgrConstants.LOCAL_IP);
518     }
519
520     public static List<Node> getOvsdbNodes(DataBroker dataBroker) {
521         List<Node> ovsdbNodes = new ArrayList<>();
522         InstanceIdentifier<Topology> ovsdbTopoIdentifier = UnimgrMapper.getOvsdbTopologyIid();
523         Topology topology = UnimgrUtils.read(dataBroker,
524                                              LogicalDatastoreType.OPERATIONAL,
525                                              ovsdbTopoIdentifier);
526         if (topology != null && topology.getNode() != null) {
527             for (Node node : topology.getNode()) {
528                 OvsdbNodeAugmentation ovsdbNodeAugmentation = node.getAugmentation(OvsdbNodeAugmentation.class);
529                 if (ovsdbNodeAugmentation != null) {
530                     ovsdbNodes.add(node);
531                 }
532             }
533         }
534         return ovsdbNodes;
535     }
536
537     public static List<Node> getUniNodes(DataBroker dataBroker) {
538         List<Node> uniNodes = new ArrayList<>();
539         InstanceIdentifier<Topology> topologyInstanceIdentifier = UnimgrMapper.getUniTopologyIid();
540         Topology topology = read(dataBroker,
541                                  LogicalDatastoreType.CONFIGURATION,
542                                  topologyInstanceIdentifier);
543         if (topology != null && topology.getNode() != null) {
544             for (Node node : topology.getNode()) {
545                 UniAugmentation uniAugmentation = node.getAugmentation(UniAugmentation.class);
546                 if (uniAugmentation != null) {
547                     uniNodes.add(node);
548                 }
549             }
550         }
551         return uniNodes;
552     }
553
554     public static List<Node> getUniNodes(DataBroker dataBroker,
555                                          LogicalDatastoreType store) {
556         List<Node> uniNodes = new ArrayList<>();
557         InstanceIdentifier<Topology> topologyInstanceIdentifier = UnimgrMapper.getUniTopologyIid();
558         Topology topology = read(dataBroker,
559                                  store,
560                                  topologyInstanceIdentifier);
561         if (topology != null && topology.getNode() != null) {
562             for (Node node : topology.getNode()) {
563                 UniAugmentation uniAugmentation = node.getAugmentation(UniAugmentation.class);
564                 if (uniAugmentation != null) {
565                     uniNodes.add(node);
566                 }
567             }
568         }
569         return uniNodes;
570     }
571
572     public static <D extends org.opendaylight.yangtools.yang.binding.DataObject> D read(
573             DataBroker dataBroker,
574             final LogicalDatastoreType store,
575             final InstanceIdentifier<D> path)  {
576         D result = null;
577         final ReadOnlyTransaction transaction = dataBroker.newReadOnlyTransaction();
578         Optional<D> optionalDataObject;
579         CheckedFuture<Optional<D>, ReadFailedException> future = transaction.read(store, path);
580         try {
581             optionalDataObject = future.checkedGet();
582             if (optionalDataObject.isPresent()) {
583                 result = optionalDataObject.get();
584             } else {
585                 LOG.debug("{}: Failed to read {}",
586                         Thread.currentThread().getStackTrace()[1], path);
587             }
588         } catch (ReadFailedException e) {
589             LOG.warn("Failed to read {} ", path, e);
590         }
591         transaction.close();
592         return result;
593     }
594
595     @Deprecated
596     public static final Optional<Node> readNode(DataBroker dataBroker,
597                                                 InstanceIdentifier<?> genericNode) {
598         ReadTransaction read = dataBroker.newReadOnlyTransaction();
599         InstanceIdentifier<Node> nodeIid = genericNode.firstIdentifierOf(Node.class);
600         CheckedFuture<Optional<Node>, ReadFailedException> nodeFuture =
601                                                               read.read(LogicalDatastoreType.OPERATIONAL,
602                                                                         nodeIid);
603         try {
604             return nodeFuture.checkedGet();
605         } catch (ReadFailedException e) {
606             LOG.info("Unable to read node with Iid {}", nodeIid);
607         }
608         return Optional.absent();
609     }
610
611     public static final Optional<Link> readLink(DataBroker dataBroker,
612                                                 LogicalDatastoreType store,
613                                                 InstanceIdentifier<?> genericNode) {
614         ReadTransaction read = dataBroker.newReadOnlyTransaction();
615         InstanceIdentifier<Link> linkIid = genericNode.firstIdentifierOf(Link.class);
616         CheckedFuture<Optional<Link>, ReadFailedException> linkFuture = read.read(store, linkIid);
617         try {
618             return linkFuture.checkedGet();
619         } catch (ReadFailedException e) {
620             LOG.info("Unable to read node with Iid {}", linkIid);
621         }
622         return Optional.absent();
623     }
624
625     public static final Optional<Node> readNode(DataBroker dataBroker,
626                                                 LogicalDatastoreType store,
627                                                 InstanceIdentifier<?> genericNode) {
628         ReadTransaction read = dataBroker.newReadOnlyTransaction();
629         InstanceIdentifier<Node> nodeIid = genericNode.firstIdentifierOf(Node.class);
630         CheckedFuture<Optional<Node>, ReadFailedException> nodeFuture = read
631                 .read(store, nodeIid);
632         try {
633             return nodeFuture.checkedGet();
634         } catch (ReadFailedException e) {
635             LOG.info("Unable to read node with Iid {}", nodeIid);
636         }
637         return Optional.absent();
638     }
639
640     public static void updateUniNode(LogicalDatastoreType dataStore,
641                                      InstanceIdentifier<?> uniKey,
642                                      UniAugmentation uni,
643                                      Node ovsdbNode,
644                                      DataBroker dataBroker) {
645         InstanceIdentifier<Node> ovsdbNodeIid = UnimgrMapper.getOvsdbNodeIid(ovsdbNode.getNodeId());
646         OvsdbNodeRef ovsdbNodeRef = new OvsdbNodeRef(ovsdbNodeIid);
647         UniAugmentationBuilder updatedUniBuilder = new UniAugmentationBuilder(uni);
648         if (ovsdbNodeRef != null) {
649             updatedUniBuilder.setOvsdbNodeRef(ovsdbNodeRef);
650         }
651         Optional<Node> optionalNode = readNode(dataBroker,
652                                                LogicalDatastoreType.CONFIGURATION,
653                                                uniKey);
654         if (optionalNode.isPresent()) {
655             Node node = optionalNode.get();
656             WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
657             NodeBuilder nodeBuilder = new NodeBuilder();
658             nodeBuilder.setKey(node.getKey());
659             nodeBuilder.setNodeId(node.getNodeId());
660             nodeBuilder.addAugmentation(UniAugmentation.class, updatedUniBuilder.build());
661             transaction.put(dataStore, uniKey.firstIdentifierOf(Node.class), nodeBuilder.build());
662             transaction.submit();
663         }
664     }
665
666     public static void updateUniNode(LogicalDatastoreType dataStore,
667                                      InstanceIdentifier<?> uniKey,
668                                      UniAugmentation uni,
669                                      InstanceIdentifier<?> ovsdbNodeIid,
670                                      DataBroker dataBroker) {
671         OvsdbNodeRef ovsdbNodeRef = new OvsdbNodeRef(ovsdbNodeIid);
672         UniAugmentationBuilder updatedUniBuilder = new UniAugmentationBuilder(uni);
673         if (ovsdbNodeRef != null) {
674             updatedUniBuilder.setOvsdbNodeRef(ovsdbNodeRef);
675         }
676         Optional<Node> optionalNode = readNode(dataBroker,
677                                                LogicalDatastoreType.CONFIGURATION,
678                                                uniKey);
679         if (optionalNode.isPresent()) {
680             Node node = optionalNode.get();
681             WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
682             NodeBuilder nodeBuilder = new NodeBuilder();
683             nodeBuilder.setKey(node.getKey());
684             nodeBuilder.setNodeId(node.getNodeId());
685             nodeBuilder.addAugmentation(UniAugmentation.class, updatedUniBuilder.build());
686             transaction.put(dataStore, uniKey.firstIdentifierOf(Node.class), nodeBuilder.build());
687             transaction.submit();
688         }
689     }
690
691     public static void updateEvcNode(LogicalDatastoreType dataStore,
692                                      InstanceIdentifier<?> evcKey,
693                                      EvcAugmentation evcAugmentation,
694                                      InstanceIdentifier<?> sourceUniIid,
695                                      InstanceIdentifier<?> destinationUniIid,
696                                      DataBroker dataBroker) {
697         EvcAugmentationBuilder updatedEvcBuilder = new EvcAugmentationBuilder(evcAugmentation);
698         if (sourceUniIid != null && destinationUniIid != null) {
699             List<UniSource> sourceList = new ArrayList<UniSource>();
700             UniSourceKey sourceKey = evcAugmentation.getUniSource().iterator().next().getKey();
701             short sourceOrder = evcAugmentation.getUniSource().iterator().next().getOrder();
702             IpAddress sourceIp = evcAugmentation.getUniSource().iterator().next().getIpAddress();
703             UniSource uniSource = new UniSourceBuilder()
704                                           .setOrder(sourceOrder)
705                                           .setKey(sourceKey)
706                                           .setIpAddress(sourceIp)
707                                           .setUni(sourceUniIid)
708                                           .build();
709             sourceList.add(uniSource);
710             updatedEvcBuilder.setUniSource(sourceList);
711
712             List<UniDest> destinationList = new ArrayList<UniDest>();
713             UniDestKey destKey = evcAugmentation.getUniDest().iterator().next().getKey();
714             short destOrder = evcAugmentation.getUniDest().iterator().next().getOrder();
715             IpAddress destIp = evcAugmentation.getUniDest().iterator().next().getIpAddress();
716             UniDest uniDest = new UniDestBuilder()
717                                       .setIpAddress(destIp)
718                                       .setOrder(destOrder)
719                                       .setKey(destKey)
720                                       .setUni(destinationUniIid)
721                                       .build();
722             destinationList.add(uniDest);
723             updatedEvcBuilder.setUniDest(destinationList);
724             Optional<Link> optionalEvcLink = readLink(dataBroker,
725                                                       LogicalDatastoreType.CONFIGURATION,
726                                                       evcKey);
727             if (optionalEvcLink.isPresent()) {
728                 Link link = optionalEvcLink.get();
729                 WriteTransaction transaction = dataBroker.newWriteOnlyTransaction();
730                 LinkBuilder linkBuilder = new LinkBuilder();
731                 linkBuilder.setKey(link.getKey());
732                 linkBuilder.setLinkId(link.getLinkId());
733                 linkBuilder.addAugmentation(EvcAugmentation.class, updatedEvcBuilder.build());
734                 transaction.put(dataStore, evcKey.firstIdentifierOf(Link.class), linkBuilder.build());
735                 transaction.submit();
736             }
737         } else {
738             LOG.info("Invalid instance identifiers for sourceUni and destUni.");
739         }
740     }
741 }