Merge "Adding integration tests for Security Groups (fixed and default SG)"
[ovsdb.git] / utils / southbound-utils / src / main / java / org / opendaylight / ovsdb / utils / southbound / utils / SouthboundUtils.java
1 /*
2  * Copyright (c) 2015 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
9 package org.opendaylight.ovsdb.utils.southbound.utils;
10
11 import com.google.common.collect.ImmutableBiMap;
12 import java.net.InetAddress;
13 import java.net.UnknownHostException;
14 import java.util.ArrayList;
15
16 import java.util.List;
17 import java.util.Map;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
20 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
21 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.*;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsKey;
40 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
41 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
42 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
43 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
44 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
45 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
49 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
50 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
51 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
52 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
55
56 public class SouthboundUtils {
57     private static final Logger LOG = LoggerFactory.getLogger(SouthboundUtils.class);
58     private static final int OVSDB_UPDATE_TIMEOUT = 1000;
59     private static final String DEFAULT_OPENFLOW_PORT = "6653";
60     private static final String OPENFLOW_CONNECTION_PROTOCOL = "tcp";
61     private MdsalUtils mdsalUtils;
62     public static final TopologyId OVSDB_TOPOLOGY_ID = new TopologyId(new Uri("ovsdb:1"));
63
64     public SouthboundUtils(MdsalUtils mdsalUtils) {
65         this.mdsalUtils = mdsalUtils;
66     }
67
68     public static final ImmutableBiMap<String, Class<? extends InterfaceTypeBase>> OVSDB_INTERFACE_TYPE_MAP
69             = new ImmutableBiMap.Builder<String, Class<? extends InterfaceTypeBase>>()
70             .put("internal", InterfaceTypeInternal.class)
71             .put("vxlan", InterfaceTypeVxlan.class)
72             .put("patch", InterfaceTypePatch.class)
73             .put("system", InterfaceTypeSystem.class)
74             .put("tap", InterfaceTypeTap.class)
75             .put("geneve", InterfaceTypeGeneve.class)
76             .put("gre", InterfaceTypeGre.class)
77             .put("ipsec_gre", InterfaceTypeIpsecGre.class)
78             .put("gre64", InterfaceTypeGre64.class)
79             .put("ipsec_gre64", InterfaceTypeIpsecGre64.class)
80             .put("lisp", InterfaceTypeLisp.class)
81             .put("dpdk", InterfaceTypeDpdk.class)
82             .put("dpdkr", InterfaceTypeDpdkr.class)
83             .put("dpdkvhost", InterfaceTypeDpdkvhost.class)
84             .put("dpdkvhostuser", InterfaceTypeDpdkvhostuser.class)
85             .build();
86
87     public static NodeId createNodeId(IpAddress ip, PortNumber port) {
88         String uriString = SouthboundConstants.OVSDB_URI_PREFIX + "://"
89                 + String.valueOf(ip.getValue()) + ":" + port.getValue();
90         Uri uri = new Uri(uriString);
91         return new NodeId(uri);
92     }
93
94     public static Node createNode(ConnectionInfo key) {
95         NodeBuilder nodeBuilder = new NodeBuilder();
96         nodeBuilder.setNodeId(createNodeId(key.getRemoteIp(), key.getRemotePort()));
97         nodeBuilder.addAugmentation(OvsdbNodeAugmentation.class, createOvsdbAugmentation(key));
98         return nodeBuilder.build();
99     }
100
101     public static OvsdbNodeAugmentation createOvsdbAugmentation(ConnectionInfo key) {
102         OvsdbNodeAugmentationBuilder ovsdbNodeBuilder = new OvsdbNodeAugmentationBuilder();
103         ovsdbNodeBuilder.setConnectionInfo(key);
104         return ovsdbNodeBuilder.build();
105     }
106
107     public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key) {
108         return createInstanceIdentifier(key.getRemoteIp(), key.getRemotePort());
109     }
110
111     public static InstanceIdentifier<Node> createInstanceIdentifier(IpAddress ip, PortNumber port) {
112         InstanceIdentifier<Node> path = InstanceIdentifier
113                 .create(NetworkTopology.class)
114                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID))
115                 .child(Node.class,createNodeKey(ip,port));
116         LOG.debug("Created ovsdb path: {}",path);
117         return path;
118     }
119
120     public static InstanceIdentifier<Node> createInstanceIdentifier(ConnectionInfo key,OvsdbBridgeName bridgeName) {
121         return SouthboundMapper.createInstanceIdentifier(createManagedNodeId(key, bridgeName));
122     }
123
124     public InstanceIdentifier<TerminationPoint> createTerminationPointInstanceIdentifier(Node node, String portName){
125
126         InstanceIdentifier<TerminationPoint> terminationPointPath = InstanceIdentifier
127                 .create(NetworkTopology.class)
128                 .child(Topology.class, new TopologyKey(OVSDB_TOPOLOGY_ID))
129                 .child(Node.class,node.getKey())
130                 .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
131
132         LOG.debug("Termination point InstanceIdentifier generated : {}",terminationPointPath);
133         return terminationPointPath;
134     }
135
136     public static NodeKey createNodeKey(IpAddress ip, PortNumber port) {
137         return new NodeKey(createNodeId(ip, port));
138     }
139
140     public static NodeId createManagedNodeId(ConnectionInfo key, OvsdbBridgeName bridgeName) {
141         return createManagedNodeId(key.getRemoteIp(), key.getRemotePort(), bridgeName);
142     }
143
144     public static NodeId createManagedNodeId(IpAddress ip, PortNumber port, OvsdbBridgeName bridgeName) {
145         return new NodeId(createNodeId(ip,port).getValue()
146                 + "/" + SouthboundConstants.BRIDGE_URI_PREFIX + "/" + bridgeName.getValue());
147     }
148
149     public static NodeId createManagedNodeId(InstanceIdentifier<Node> iid) {
150         NodeKey nodeKey = iid.firstKeyOf(Node.class, NodeKey.class);
151         return nodeKey.getNodeId();
152     }
153
154     public static ConnectionInfo getConnectionInfo(final String addressStr, final String portStr) {
155         InetAddress inetAddress = null;
156         try {
157             inetAddress = InetAddress.getByName(addressStr);
158         } catch (UnknownHostException e) {
159             LOG.warn("Could not allocate InetAddress");
160         }
161
162         IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
163         PortNumber port = new PortNumber(Integer.parseInt(portStr));
164
165         LOG.info("connectionInfo: {}", new ConnectionInfoBuilder()
166                 .setRemoteIp(address)
167                 .setRemotePort(port)
168                 .build());
169         return new ConnectionInfoBuilder()
170                 .setRemoteIp(address)
171                 .setRemotePort(port)
172                 .build();
173     }
174
175     public static String connectionInfoToString(final ConnectionInfo connectionInfo) {
176         return String.valueOf(
177                 connectionInfo.getRemoteIp().getValue()) + ":" + connectionInfo.getRemotePort().getValue();
178     }
179
180     public boolean addOvsdbNode(final ConnectionInfo connectionInfo) {
181         boolean result = mdsalUtils.put(LogicalDatastoreType.CONFIGURATION,
182                 createInstanceIdentifier(connectionInfo),
183                 createNode(connectionInfo));
184         try {
185             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
186         } catch (InterruptedException e) {
187             LOG.warn("Interrupted while waiting after adding OVSDB node {}", connectionInfoToString(connectionInfo), e);
188         }
189         return result;
190     }
191
192     public Node getOvsdbNode(final ConnectionInfo connectionInfo) {
193         return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
194                 createInstanceIdentifier(connectionInfo));
195     }
196
197     public boolean deleteOvsdbNode(final ConnectionInfo connectionInfo) {
198         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
199                 createInstanceIdentifier(connectionInfo));
200         try {
201             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
202         } catch (InterruptedException e) {
203             LOG.warn("Interrupted while waiting after deleting OVSDB node {}", connectionInfoToString(connectionInfo),
204                     e);
205         }
206         return result;
207     }
208
209     public Node connectOvsdbNode(final ConnectionInfo connectionInfo) {
210         addOvsdbNode(connectionInfo);
211         Node node = getOvsdbNode(connectionInfo);
212         LOG.info("Connected to {}", connectionInfoToString(connectionInfo));
213         return node;
214     }
215
216     public boolean disconnectOvsdbNode(final ConnectionInfo connectionInfo) {
217         deleteOvsdbNode(connectionInfo);
218         LOG.info("Disconnected from {}", connectionInfoToString(connectionInfo));
219         return true;
220     }
221
222     public List<ControllerEntry> createControllerEntry(String controllerTarget) {
223         List<ControllerEntry> controllerEntriesList = new ArrayList<>();
224         controllerEntriesList.add(new ControllerEntryBuilder()
225                 .setTarget(new Uri(controllerTarget))
226                 .build());
227         return controllerEntriesList;
228     }
229
230     /**
231      * Extract the <code>store</code> type data store contents for the particular bridge identified by
232      * <code>bridgeName</code>.
233      *
234      * @param connectionInfo address for the node
235      * @param bridgeName name of the bridge
236      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
237      * @return <code>store</code> type data store contents
238      */
239     public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
240                                               LogicalDatastoreType store) {
241         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = null;
242         Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
243         if (bridgeNode != null) {
244             ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
245         }
246         return ovsdbBridgeAugmentation;
247     }
248
249     /**
250      * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
251      * identified by <code>bridgeName</code>
252      *
253      * @param connectionInfo address for the node
254      * @param bridgeName name of the bridge
255      * @see <code>NetvirtIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
256      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
257      */
258     public OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
259         return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
260     }
261
262     /**
263      * Extract the node contents from <code>store</code> type data store for the
264      * bridge identified by <code>bridgeName</code>.
265      *
266      * @param connectionInfo address for the node
267      * @param bridgeName name of the bridge
268      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
269      * @return <code>store</code> type data store contents
270      */
271     public Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
272         InstanceIdentifier<Node> bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
273         return mdsalUtils.read(store, bridgeIid);
274     }
275
276     public boolean deleteBridge(final ConnectionInfo connectionInfo, final String bridgeName) {
277
278         boolean result = mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION,
279                 createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName)));
280         try {
281             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
282         } catch (InterruptedException e) {
283             LOG.warn("Interrupted while waiting after deleting bridge {}", bridgeName, e);
284         }
285         return result;
286     }
287
288     public List<ProtocolEntry> createMdsalProtocols() {
289         List<ProtocolEntry> protocolList = new ArrayList<>();
290         ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
291                 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
292         protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
293         return protocolList;
294     }
295
296     /*
297      * base method for adding test bridges.  Other helper methods used to create bridges should utilize this method.
298      *
299      * @param connectionInfo
300      * @param bridgeIid if passed null, one is created
301      * @param bridgeName cannot be null
302      * @param bridgeNodeId if passed null, one is created based on <code>bridgeIid</code>
303      * @param setProtocolEntries toggles whether default protocol entries are set for the bridge
304      * @param failMode toggles whether default fail mode is set for the bridge
305      * @param setManagedBy toggles whether to setManagedBy for the bridge
306      * @param dpType if passed null, this parameter is ignored
307      * @param externalIds if passed null, this parameter is ignored
308      * @param otherConfig if passed null, this parameter is ignored
309      * @return success of bridge addition
310      * @throws InterruptedException
311      */
312     public boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
313                              final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
314                              final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
315                              final Class<? extends DatapathTypeBase> dpType,
316                              final List<BridgeExternalIds> externalIds,
317                              final List<ControllerEntry> controllerEntries,
318                              final List<BridgeOtherConfigs> otherConfigs,
319                              final String dpid) throws InterruptedException {
320
321         NodeBuilder bridgeNodeBuilder = new NodeBuilder();
322         if (bridgeIid == null) {
323             bridgeIid = createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
324         }
325         if (bridgeNodeId == null) {
326             bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
327         }
328         bridgeNodeBuilder.setNodeId(bridgeNodeId);
329         OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
330         ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
331         if (setProtocolEntries) {
332             ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
333         }
334         if (failMode != null) {
335             ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
336         }
337         if (setManagedBy) {
338             setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
339         }
340         if (dpType != null) {
341             ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
342         }
343         if (externalIds != null) {
344             ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
345         }
346         if (controllerEntries != null) {
347             ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
348         }
349         if (otherConfigs != null) {
350             ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
351         }
352         if (dpid != null && !dpid.isEmpty()) {
353             DatapathId datapathId = new DatapathId(dpid);
354             ovsdbBridgeAugmentationBuilder.setDatapathId(datapathId);
355         }
356         bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
357         LOG.debug("Built with the intent to store bridge data {}",
358                 ovsdbBridgeAugmentationBuilder.toString());
359         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
360                 bridgeIid, bridgeNodeBuilder.build());
361         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
362         return result;
363     }
364
365     public boolean addBridge(final ConnectionInfo connectionInfo, InstanceIdentifier<Node> bridgeIid,
366                              final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
367                              final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
368                              final Class<? extends DatapathTypeBase> dpType,
369                              final List<BridgeExternalIds> externalIds,
370                              final List<ControllerEntry> controllerEntries,
371                              final List<BridgeOtherConfigs> otherConfigs) throws InterruptedException {
372         return addBridge(connectionInfo, bridgeIid, bridgeName, bridgeNodeId, setProtocolEntries,
373                 failMode, setManagedBy, dpType, externalIds, controllerEntries,
374                 otherConfigs, null);
375     }
376
377     public boolean addBridge(final ConnectionInfo connectionInfo, final String bridgeName)
378             throws InterruptedException {
379
380         return addBridge(connectionInfo, null, bridgeName, null, true,
381                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null);
382     }
383
384     private void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
385                               final ConnectionInfo connectionInfo) {
386         InstanceIdentifier<Node> connectionNodePath = createInstanceIdentifier(connectionInfo);
387         ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
388     }
389
390     public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName,
391                                        String type, Map<String, String> options,
392                                        Map<String, String> externalIds) {
393         InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(bridgeNode, portName);
394         OvsdbTerminationPointAugmentationBuilder tpAugmentationBuilder = new OvsdbTerminationPointAugmentationBuilder();
395
396         tpAugmentationBuilder.setName(portName);
397         if (type != null) {
398             tpAugmentationBuilder.setInterfaceType(OVSDB_INTERFACE_TYPE_MAP.get(type));
399         }
400
401         if (options != null && options.size() > 0) {
402             List<Options> optionsList = new ArrayList<>();
403             for (Map.Entry<String, String> entry : options.entrySet()) {
404                 OptionsBuilder optionsBuilder = new OptionsBuilder();
405                 optionsBuilder.setKey(new OptionsKey(entry.getKey()));
406                 optionsBuilder.setOption(entry.getKey());
407                 optionsBuilder.setValue(entry.getValue());
408                 optionsList.add(optionsBuilder.build());
409             }
410             tpAugmentationBuilder.setOptions(optionsList);
411         }
412
413         if (externalIds != null && externalIds.size() > 0) {
414             List<InterfaceExternalIds> externalIdsList = new ArrayList<>();
415             for (Map.Entry<String, String> entry : externalIds.entrySet()) {
416                 InterfaceExternalIdsBuilder interfaceExternalIdsBuilder = new InterfaceExternalIdsBuilder();
417                 interfaceExternalIdsBuilder.setKey(new InterfaceExternalIdsKey(entry.getKey()));
418                 interfaceExternalIdsBuilder.setExternalIdKey(entry.getKey());
419                 interfaceExternalIdsBuilder.setExternalIdValue(entry.getValue());
420                 externalIdsList.add(interfaceExternalIdsBuilder.build());
421             }
422             tpAugmentationBuilder.setInterfaceExternalIds(externalIdsList);
423         }
424
425         TerminationPointBuilder tpBuilder = new TerminationPointBuilder();
426         tpBuilder.setKey(InstanceIdentifier.keyOf(tpIid));
427         tpBuilder.addAugmentation(OvsdbTerminationPointAugmentation.class, tpAugmentationBuilder.build());
428         /* TODO SB_MIGRATION should this be merge or mdsalUtils.put */
429         return mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpIid, tpBuilder.build());
430     }
431
432     public TerminationPoint readTerminationPoint(Node bridgeNode, String bridgeName, String portName) {
433         InstanceIdentifier<TerminationPoint> tpIid = createTerminationPointInstanceIdentifier(
434                 bridgeNode, portName);
435         return mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, tpIid);
436     }
437
438     public Boolean addTerminationPoint(Node bridgeNode, String bridgeName, String portName, String type) {
439         return addTerminationPoint(bridgeNode, bridgeName, portName, type, null, null);
440     }
441
442     public Boolean addTunnelTerminationPoint(Node bridgeNode, String bridgeName, String portName, String type,
443                                              Map<String, String> options) {
444         return addTerminationPoint(bridgeNode, bridgeName, portName, type, options, null);
445     }
446 }