Upgrade ietf-{inet,yang}-types to 2013-07-15
[ovsdb.git] / southbound / southbound-it / src / test / java / org / opendaylight / ovsdb / southbound / it / SouthboundIT.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 package org.opendaylight.ovsdb.southbound.it;
9
10 import static org.junit.Assert.assertNotNull;
11 import static org.junit.Assert.fail;
12 import static org.ops4j.pax.exam.CoreOptions.composite;
13 import static org.ops4j.pax.exam.CoreOptions.maven;
14 import static org.ops4j.pax.exam.CoreOptions.propagateSystemProperties;
15 import static org.ops4j.pax.exam.CoreOptions.vmOption;
16 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.editConfigurationFilePut;
17 import static org.ops4j.pax.exam.karaf.options.KarafDistributionOption.keepRuntimeFolder;
18
19 import java.lang.annotation.Annotation;
20 import java.lang.reflect.Method;
21 import java.net.InetAddress;
22 import java.net.UnknownHostException;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Properties;
28 import java.util.Set;
29
30 import javax.annotation.Nullable;
31 import javax.inject.Inject;
32
33 import org.junit.After;
34 import org.junit.Assert;
35 import org.junit.Assume;
36 import org.junit.Before;
37 import org.junit.Ignore;
38 import org.junit.Test;
39 import org.junit.internal.AssumptionViolatedException;
40 import org.junit.runner.RunWith;
41 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
42 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
43 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
44 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
45 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
46 import org.opendaylight.controller.mdsal.it.base.AbstractMdsalTestBase;
47 import org.opendaylight.ovsdb.lib.OvsdbClient;
48 import org.opendaylight.ovsdb.lib.notation.Version;
49 import org.opendaylight.ovsdb.lib.schema.DatabaseSchema;
50 import org.opendaylight.ovsdb.southbound.SouthboundConstants;
51 import org.opendaylight.ovsdb.southbound.SouthboundMapper;
52 import org.opendaylight.ovsdb.southbound.SouthboundProvider;
53 import org.opendaylight.ovsdb.southbound.SouthboundUtil;
54 import org.opendaylight.ovsdb.utils.mdsal.utils.MdsalUtils;
55 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
56 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
57 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
58 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Uri;
59 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.InterfaceTypeBase;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentationBuilder;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeName;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeProtocolBase;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbFailModeBase;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeAugmentation;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbNodeRef;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbPortInterfaceAttributes.VlanMode;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentationBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.QosTypeBase;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIds;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeExternalIdsBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigsBuilder;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntry;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ControllerEntryBuilder;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntry;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.ProtocolEntryBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Autoattach;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachBuilder;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.AutoattachKey;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfoBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.DatapathTypeEntry;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.InterfaceTypeEntryBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagedNodeEntry;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.OpenvswitchOtherConfigs;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntries;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesBuilder;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QosEntriesKey;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.Queues;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesBuilder;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.QueuesKey;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIds;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.AutoattachExternalIdsBuilder;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.Mappings;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.autoattach.MappingsBuilder;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIds;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosExternalIdsBuilder;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfig;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QosOtherConfigBuilder;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueList;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueListBuilder;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.qos.entries.QueueListKey;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIds;
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesExternalIdsBuilder;
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfig;
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.queues.QueuesOtherConfigBuilder;
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIds;
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceExternalIdsBuilder;
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldp;
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceLldpBuilder;
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigs;
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.InterfaceOtherConfigsBuilder;
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Options;
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.OptionsBuilder;
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIds;
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortExternalIdsBuilder;
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigs;
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.PortOtherConfigsBuilder;
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.Trunks;
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.port._interface.attributes.TrunksBuilder;
126 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
127 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
128 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
129 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
130 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
131 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
132 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
133 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
134 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
135 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
136 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
137 import org.opendaylight.yangtools.concepts.Builder;
138 import org.opendaylight.yangtools.yang.binding.DataObject;
139 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
140 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
141 import org.ops4j.pax.exam.Configuration;
142 import org.ops4j.pax.exam.Option;
143 import org.ops4j.pax.exam.junit.PaxExam;
144 import org.ops4j.pax.exam.karaf.options.LogLevelOption;
145 import org.ops4j.pax.exam.options.MavenUrlReference;
146 import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
147 import org.ops4j.pax.exam.spi.reactors.PerClass;
148 import org.osgi.framework.BundleContext;
149 import org.slf4j.Logger;
150 import org.slf4j.LoggerFactory;
151
152 import com.google.common.collect.ImmutableBiMap;
153 import com.google.common.collect.ImmutableList;
154 import com.google.common.collect.Lists;
155 import com.google.common.collect.Sets;
156
157 /**
158  * Integration tests for southbound-impl
159  *
160  * @author Sam Hague (shague@redhat.com)
161  */
162 @RunWith(PaxExam.class)
163 @ExamReactorStrategy(PerClass.class)
164 public class SouthboundIT extends AbstractMdsalTestBase {
165     private static final String NETDEV_DP_TYPE = "netdev";
166     private static final Logger LOG = LoggerFactory.getLogger(SouthboundIT.class);
167     private static final int OVSDB_UPDATE_TIMEOUT = 1000;
168     private static final int OVSDB_ROUNDTRIP_TIMEOUT = 10000;
169     private static final String FORMAT_STR = "%s_%s_%d";
170     private static final Version AUTOATTACH_FROM_VERSION = Version.fromString("7.11.2");
171     private static final Version IF_INDEX_FROM_VERSION = Version.fromString("7.2.1");
172     private static String addressStr;
173     private static int portNumber;
174     private static String connectionType;
175     private static boolean setup = false;
176     private static MdsalUtils mdsalUtils = null;
177     private static Node ovsdbNode;
178     private static int testMethodsRemaining;
179     private static DataBroker dataBroker;
180     private static Version schemaVersion;
181     private static OvsdbClient ovsdbClient;
182     private static DatabaseSchema dbSchema;
183
184     @Inject
185     private BundleContext bundleContext;
186
187     private static final NotifyingDataChangeListener CONFIGURATION_LISTENER =
188             new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION);
189     private static final NotifyingDataChangeListener OPERATIONAL_LISTENER =
190             new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL);
191
192     private static class NotifyingDataChangeListener implements DataChangeListener {
193         private final LogicalDatastoreType type;
194         private final Set<InstanceIdentifier<?>> createdIids = new HashSet<>();
195         private final Set<InstanceIdentifier<?>> removedIids = new HashSet<>();
196         private final Set<InstanceIdentifier<?>> updatedIids = new HashSet<>();
197         private final InstanceIdentifier<?> iid;
198         private final int RETRY_WAIT = 100;
199
200         private NotifyingDataChangeListener(LogicalDatastoreType type) {
201             this.type = type;
202             this.iid = null;
203         }
204
205         private NotifyingDataChangeListener(LogicalDatastoreType type, InstanceIdentifier<?> iid) {
206             this.type = type;
207             this.iid = iid;
208         }
209
210         @Override
211         public void onDataChanged(
212                 AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> asyncDataChangeEvent) {
213             LOG.info("{} DataChanged: created {}", type, asyncDataChangeEvent.getCreatedData().keySet());
214             LOG.info("{} DataChanged: removed {}", type, asyncDataChangeEvent.getRemovedPaths());
215             LOG.info("{} DataChanged: updated {}", type, asyncDataChangeEvent.getUpdatedData().keySet());
216             createdIids.addAll(asyncDataChangeEvent.getCreatedData().keySet());
217             removedIids.addAll(asyncDataChangeEvent.getRemovedPaths());
218             updatedIids.addAll(asyncDataChangeEvent.getUpdatedData().keySet());
219             // Handled managed iids
220             for (DataObject obj : asyncDataChangeEvent.getCreatedData().values()) {
221                 if (obj instanceof ManagedNodeEntry) {
222                     ManagedNodeEntry managedNodeEntry = (ManagedNodeEntry) obj;
223                     LOG.info("{} DataChanged: created managed {}", managedNodeEntry.getBridgeRef().getValue());
224                     createdIids.add(managedNodeEntry.getBridgeRef().getValue());
225                 }
226             }
227             synchronized(this) {
228                 notifyAll();
229             }
230         }
231
232         public boolean isCreated(InstanceIdentifier<?> iid) {
233             return createdIids.remove(iid);
234         }
235
236         public boolean isRemoved(InstanceIdentifier<?> iid) {
237             return removedIids.remove(iid);
238         }
239
240         public boolean isUpdated(InstanceIdentifier<?> iid) {
241             return updatedIids.remove(iid);
242         }
243
244         public void clear() {
245             createdIids.clear();
246             removedIids.clear();
247             updatedIids.clear();
248         }
249
250         public void registerDataChangeListener() {
251             dataBroker.registerDataChangeListener(type, iid, this, AsyncDataBroker.DataChangeScope.SUBTREE);
252         }
253
254         public void waitForCreation(long timeout) throws InterruptedException {
255             synchronized (this) {
256                 long _start = System.currentTimeMillis();
257                 LOG.info("Waiting for {} DataChanged creation on {}", type, iid);
258                 while (!isCreated(iid) && (System.currentTimeMillis() - _start) < timeout) {
259                     wait(RETRY_WAIT);
260                 }
261                 LOG.info("Woke up, waited {}ms for creation of {}", (System.currentTimeMillis() - _start), iid);
262             }
263         }
264
265         public void waitForDeletion(long timeout) throws InterruptedException {
266             synchronized (this) {
267                 long _start = System.currentTimeMillis();
268                 LOG.info("Waiting for {} DataChanged deletion on {}", type, iid);
269                 while (!isRemoved(iid) && (System.currentTimeMillis() - _start) < timeout) {
270                     wait(RETRY_WAIT);
271                 }
272                 LOG.info("Woke up, waited {}ms for deletion of {}", (System.currentTimeMillis() - _start), iid);
273             }
274         }
275
276         public void waitForUpdate(long timeout) throws InterruptedException {
277             synchronized (this) {
278                 long _start = System.currentTimeMillis();
279                 LOG.info("Waiting for {} DataChanged update on {}", type, iid);
280                 while (!isUpdated(iid) && (System.currentTimeMillis() - _start) < timeout) {
281                     wait(RETRY_WAIT);
282                 }
283                 LOG.info("Woke up, waited {}ms for update of {}", (System.currentTimeMillis() - _start), iid);
284             }
285         }
286
287     }
288
289     @Configuration
290     public Option[] config() {
291         Option[] options = super.config();
292         Option[] propertyOptions = getPropertiesOptions();
293         Option[] otherOptions = getOtherOptions();
294         Option[] combinedOptions = new Option[options.length + propertyOptions.length + otherOptions.length];
295         System.arraycopy(options, 0, combinedOptions, 0, options.length);
296         System.arraycopy(propertyOptions, 0, combinedOptions, options.length, propertyOptions.length);
297         System.arraycopy(otherOptions, 0, combinedOptions, options.length + propertyOptions.length,
298                 otherOptions.length);
299         return combinedOptions;
300     }
301
302     private Option[] getOtherOptions() {
303         return new Option[] {
304                 vmOption("-javaagent:../jars/org.jacoco.agent.jar=destfile=../../jacoco-it.exec"),
305                 keepRuntimeFolder()
306         };
307     }
308
309     @Override
310     public String getKarafDistro() {
311         return maven()
312                 .groupId("org.opendaylight.ovsdb")
313                 .artifactId("southbound-karaf")
314                 .versionAsInProject()
315                 .type("zip")
316                 .getURL();
317     }
318
319     @Override
320     public MavenUrlReference getFeatureRepo() {
321         return maven()
322                 .groupId("org.opendaylight.ovsdb")
323                 .artifactId("southbound-features")
324                 .classifier("features")
325                 .type("xml")
326                 .versionAsInProject();
327     }
328
329     @Override
330     public String getFeatureName() {
331         return "odl-ovsdb-southbound-test";
332     }
333
334     protected String usage() {
335         return "Integration Test needs a valid connection configuration as follows :\n"
336                 + "active connection : mvn -Dovsdbserver.ipaddress=x.x.x.x -Dovsdbserver.port=yyyy verify\n"
337                 + "passive connection : mvn -Dovsdbserver.connection=passive verify\n";
338     }
339
340     @Override
341     public Option getLoggingOption() {
342         return composite(
343                 editConfigurationFilePut(SouthboundITConstants.ORG_OPS4J_PAX_LOGGING_CFG,
344                         "log4j.logger.org.opendaylight.ovsdb",
345                         LogLevelOption.LogLevel.TRACE.name()),
346                 super.getLoggingOption());
347     }
348
349     private Option[] getPropertiesOptions() {
350         Properties props = new Properties(System.getProperties());
351         String addressStr = props.getProperty(SouthboundITConstants.SERVER_IPADDRESS,
352                 SouthboundITConstants.DEFAULT_SERVER_IPADDRESS);
353         String portStr = props.getProperty(SouthboundITConstants.SERVER_PORT,
354                 SouthboundITConstants.DEFAULT_SERVER_PORT);
355         String connectionType = props.getProperty(SouthboundITConstants.CONNECTION_TYPE,
356                 SouthboundITConstants.CONNECTION_TYPE_ACTIVE);
357
358         LOG.info("getPropertiesOptions: Using the following properties: mode= {}, ip:port= {}:{}",
359                 connectionType, addressStr, portStr);
360
361         return new Option[] {
362                 propagateSystemProperties(
363                         SouthboundITConstants.SERVER_IPADDRESS,
364                         SouthboundITConstants.SERVER_PORT,
365                         SouthboundITConstants.CONNECTION_TYPE),
366                 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
367                         SouthboundITConstants.SERVER_IPADDRESS, addressStr),
368                 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
369                         SouthboundITConstants.SERVER_PORT, portStr),
370                 editConfigurationFilePut(SouthboundITConstants.CUSTOM_PROPERTIES,
371                         SouthboundITConstants.CONNECTION_TYPE, connectionType),
372         };
373     }
374
375     @Before
376     @Override
377     public void setup() throws InterruptedException {
378         if (setup) {
379             LOG.info("Skipping setup, already initialized");
380             return;
381         }
382
383         try {
384             super.setup();
385         } catch (Exception e) {
386             LOG.warn("Failed to setup test", e);
387         }
388         //dataBroker = getSession().getSALService(DataBroker.class);
389         Thread.sleep(3000);
390         dataBroker = SouthboundProvider.getDb();
391         Assert.assertNotNull("db should not be null", dataBroker);
392
393         addressStr = bundleContext.getProperty(SouthboundITConstants.SERVER_IPADDRESS);
394         String portStr = bundleContext.getProperty(SouthboundITConstants.SERVER_PORT);
395         try {
396             portNumber = Integer.parseInt(portStr);
397         } catch (NumberFormatException e) {
398             fail("Invalid port number " + portStr + System.lineSeparator() + usage());
399         }
400         connectionType = bundleContext.getProperty(SouthboundITConstants.CONNECTION_TYPE);
401
402         LOG.info("setUp: Using the following properties: mode= {}, ip:port= {}:{}",
403                 connectionType, addressStr, portNumber);
404         if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_ACTIVE)) {
405             if (addressStr == null) {
406                 fail(usage());
407             }
408         }
409
410         mdsalUtils = new MdsalUtils(dataBroker);
411         final ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
412         final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
413         dataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
414                 iid, CONFIGURATION_LISTENER, AsyncDataBroker.DataChangeScope.SUBTREE);
415         dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
416                 iid, OPERATIONAL_LISTENER, AsyncDataBroker.DataChangeScope.SUBTREE);
417
418         ovsdbNode = connectOvsdbNode(connectionInfo);
419         try {
420             ovsdbClient = SouthboundIntegrationTestUtils.getTestConnection(this);
421             assertNotNull("Invalid Client. Check connection params", ovsdbClient);
422
423             dbSchema = ovsdbClient.getSchema(SouthboundIntegrationTestUtils.OPEN_VSWITCH_SCHEMA).get();
424             assertNotNull("Invalid dbSchema.", dbSchema);
425             schemaVersion = dbSchema.getVersion();
426             LOG.info("{} schema version = {}", SouthboundIntegrationTestUtils.OPEN_VSWITCH_SCHEMA, schemaVersion);
427         } catch (Exception e) {
428             fail("Error accessing schemaVersion in SouthboundIT setUp()." + usage());
429         }
430
431         // Let's count the test methods (we need to use this instead of @AfterClass on teardown() since the latter is
432         // useless with pax-exam)
433         for (Method method : getClass().getMethods()) {
434             boolean testMethod = false;
435             boolean ignoreMethod = false;
436             for (Annotation annotation : method.getAnnotations()) {
437                 if (Test.class.equals(annotation.annotationType())) {
438                     testMethod = true;
439                 }
440                 if (Ignore.class.equals(annotation.annotationType())) {
441                     ignoreMethod = true;
442                 }
443             }
444             if (testMethod && !ignoreMethod) {
445                 testMethodsRemaining++;
446             }
447         }
448         LOG.info("{} test methods to run", testMethodsRemaining);
449
450         setup = true;
451     }
452
453     @After
454     public void teardown() {
455         testMethodsRemaining--;
456         LOG.info("{} test methods remaining", testMethodsRemaining);
457         if (testMethodsRemaining == 0) {
458             try {
459                 disconnectOvsdbNode(getConnectionInfo(addressStr, portNumber));
460             } catch (InterruptedException e) {
461                 LOG.warn("Interrupted while disconnecting", e);
462             }
463         }
464     }
465
466     /**
467      * Test passive connection mode. The southbound starts in a listening mode waiting for connections on port
468      * 6640. This test will wait for incoming connections for {@link SouthboundITConstants#CONNECTION_INIT_TIMEOUT} ms.
469      *
470      * @throws InterruptedException
471      */
472     @Test
473     public void testPassiveNode() throws InterruptedException {
474         if (connectionType.equalsIgnoreCase(SouthboundITConstants.CONNECTION_TYPE_PASSIVE)) {
475             //Wait for CONNECTION_INIT_TIMEOUT for the Passive connection to be initiated by the ovsdb-server.
476             Thread.sleep(SouthboundITConstants.CONNECTION_INIT_TIMEOUT);
477         }
478     }
479
480     private static ConnectionInfo getConnectionInfo(final String addressStr, final int portNumber) {
481         InetAddress inetAddress = null;
482         try {
483             inetAddress = InetAddress.getByName(addressStr);
484         } catch (UnknownHostException e) {
485             fail("Could not resolve " + addressStr + ": " + e);
486         }
487
488         IpAddress address = SouthboundMapper.createIpAddress(inetAddress);
489         PortNumber port = new PortNumber(portNumber);
490
491         final ConnectionInfo connectionInfo = new ConnectionInfoBuilder()
492                 .setRemoteIp(address)
493                 .setRemotePort(port)
494                 .build();
495         LOG.info("connectionInfo: {}", connectionInfo);
496         return connectionInfo;
497     }
498
499     @Test
500     public void testNetworkTopology() throws InterruptedException {
501         NetworkTopology networkTopology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION,
502                 InstanceIdentifier.create(NetworkTopology.class));
503         Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.CONFIGURATION,
504                 networkTopology);
505
506         networkTopology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
507                 InstanceIdentifier.create(NetworkTopology.class));
508         Assert.assertNotNull("NetworkTopology could not be found in " + LogicalDatastoreType.OPERATIONAL,
509                 networkTopology);
510     }
511
512     @Test
513     public void testOvsdbTopology() throws InterruptedException {
514         InstanceIdentifier<Topology> path = InstanceIdentifier
515                 .create(NetworkTopology.class)
516                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
517
518         Topology topology = mdsalUtils.read(LogicalDatastoreType.CONFIGURATION, path);
519         Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.CONFIGURATION,
520                 topology);
521
522         topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, path);
523
524         Assert.assertNotNull("Topology could not be found in " + LogicalDatastoreType.OPERATIONAL,
525                 topology);
526     }
527
528     private Node connectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
529         final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
530         Assert.assertTrue(
531                 mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, iid, SouthboundUtils.createNode(connectionInfo)));
532         waitForOperationalCreation(iid);
533         Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
534         Assert.assertNotNull(node);
535         LOG.info("Connected to {}", SouthboundUtils.connectionInfoToString(connectionInfo));
536         return node;
537     }
538
539     private void waitForOperationalCreation(InstanceIdentifier<Node> iid) throws InterruptedException {
540         synchronized (OPERATIONAL_LISTENER) {
541             long _start = System.currentTimeMillis();
542             LOG.info("Waiting for OPERATIONAL DataChanged creation on {}", iid);
543             while (!OPERATIONAL_LISTENER.isCreated(
544                     iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
545                 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
546             }
547             LOG.info("Woke up, waited {} for creation of {}", (System.currentTimeMillis() - _start), iid);
548         }
549     }
550
551     private static void waitForOperationalDeletion(InstanceIdentifier<Node> iid) throws InterruptedException {
552         synchronized (OPERATIONAL_LISTENER) {
553             long _start = System.currentTimeMillis();
554             LOG.info("Waiting for OPERATIONAL DataChanged deletion on {}", iid);
555             while (!OPERATIONAL_LISTENER.isRemoved(
556                     iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
557                 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
558             }
559             LOG.info("Woke up, waited {} for deletion of {}", (System.currentTimeMillis() - _start), iid);
560         }
561     }
562
563     private void waitForOperationalUpdate(InstanceIdentifier<Node> iid) throws InterruptedException {
564         synchronized (OPERATIONAL_LISTENER) {
565             long _start = System.currentTimeMillis();
566             LOG.info("Waiting for OPERATIONAL DataChanged update on {}", iid);
567             while (!OPERATIONAL_LISTENER.isUpdated(
568                     iid) && (System.currentTimeMillis() - _start) < OVSDB_ROUNDTRIP_TIMEOUT) {
569                 OPERATIONAL_LISTENER.wait(OVSDB_UPDATE_TIMEOUT);
570             }
571             LOG.info("Woke up, waited {} for update of {}", (System.currentTimeMillis() - _start), iid);
572         }
573     }
574
575     private static void disconnectOvsdbNode(final ConnectionInfo connectionInfo) throws InterruptedException {
576         final InstanceIdentifier<Node> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
577         Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
578         waitForOperationalDeletion(iid);
579         Node node = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, iid);
580         Assert.assertNull(node);
581         LOG.info("Disconnected from {}", SouthboundUtils.connectionInfoToString(connectionInfo));
582     }
583
584     @Test
585     public void testAddDeleteOvsdbNode() throws InterruptedException {
586         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
587         // At this point we're connected, disconnect and reconnect (the connection will be removed at the very end)
588         disconnectOvsdbNode(connectionInfo);
589         connectOvsdbNode(connectionInfo);
590     }
591
592     @Test
593     public void testDpdkSwitch() throws InterruptedException {
594         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
595         List<DatapathTypeEntry> datapathTypeEntries = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class)
596                 .getDatapathTypeEntry();
597         if (datapathTypeEntries == null) {
598             LOG.info("DPDK not supported on this node.");
599         } else {
600             for (DatapathTypeEntry dpTypeEntry : datapathTypeEntries) {
601                 Class<? extends DatapathTypeBase> dpType = dpTypeEntry.getDatapathType();
602                 String dpTypeStr = SouthboundConstants.DATAPATH_TYPE_MAP.get(dpType);
603                 LOG.info("dp type is {}", dpTypeStr);
604                 if (dpTypeStr.equals(NETDEV_DP_TYPE)) {
605                     LOG.info("Found a DPDK node; adding a corresponding netdev device");
606                     InstanceIdentifier<Node> bridgeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo,
607                             new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
608                     NodeId bridgeNodeId = SouthboundUtils.createManagedNodeId(bridgeIid);
609                     try (TestBridge testBridge = new TestBridge(connectionInfo, bridgeIid,
610                             SouthboundITConstants.BRIDGE_NAME, bridgeNodeId, false, null, true, dpType, null, null,
611                             null)) {
612                         // Verify that the device is netdev
613                         OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
614                         Assert.assertNotNull(bridge);
615                         Assert.assertEquals(dpType, bridge.getDatapathType());
616
617                         // Add port for all dpdk interface types (dpdkvhost not supported in existing dpdk ovs)
618                         List<String> dpdkTypes = new ArrayList<String>();
619                         dpdkTypes.add("dpdk");
620                         dpdkTypes.add("dpdkr");
621                         dpdkTypes.add("dpdkvhostuser");
622                         //dpdkTypes.add("dpdkvhost");
623
624                         for (String dpdkType : dpdkTypes) {
625                             String testPortname = "test"+dpdkType+"port";
626                             LOG.info("DPDK portname and type is {}, {}", testPortname, dpdkType);
627                             Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
628                                     .get(dpdkType);
629                             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationpointBuilder =
630                                     createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(testPortname,
631                                             dpdkIfType);
632                             Assert.assertTrue(
633                                     addTerminationPoint(bridgeNodeId, testPortname, ovsdbTerminationpointBuilder));
634                         }
635
636                         // Verify that all DPDK ports are created
637                         InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
638                         Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL,
639                                 terminationPointIid);
640                         Assert.assertNotNull(terminationPointNode);
641
642                         // Verify that each termination point has the specific DPDK ifType
643                         for (String dpdkType : dpdkTypes) {
644                             String testPortname = "test"+dpdkType+"port";
645                             Class<? extends InterfaceTypeBase> dpdkIfType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
646                                     .get(dpdkType);
647                             List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
648                             for (TerminationPoint terminationPoint : terminationPoints) {
649                                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation = terminationPoint
650                                         .getAugmentation(OvsdbTerminationPointAugmentation.class);
651                                 if (ovsdbTerminationPointAugmentation.getName().equals(testPortname)) {
652                                     Class<? extends InterfaceTypeBase> opPort = ovsdbTerminationPointAugmentation
653                                             .getInterfaceType();
654                                     Assert.assertEquals(dpdkIfType, opPort);
655                                 }
656                             }
657                         }
658                     }
659                 }
660                 break;
661             }
662         }
663     }
664
665     @Test
666     public void testOvsdbNodeOvsVersion() throws InterruptedException {
667         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
668         Assert.assertNotNull(ovsdbNodeAugmentation);
669         assertNotNull(ovsdbNodeAugmentation.getOvsVersion());
670     }
671
672     @Test
673     public void testOpenVSwitchOtherConfig() throws InterruptedException {
674         OvsdbNodeAugmentation ovsdbNodeAugmentation = ovsdbNode.getAugmentation(OvsdbNodeAugmentation.class);
675         Assert.assertNotNull(ovsdbNodeAugmentation);
676         List<OpenvswitchOtherConfigs> otherConfigsList = ovsdbNodeAugmentation.getOpenvswitchOtherConfigs();
677         if (otherConfigsList != null) {
678             for (OpenvswitchOtherConfigs otherConfig : otherConfigsList) {
679                 if (otherConfig.getOtherConfigKey().equals("local_ip")) {
680                     LOG.info("local_ip: {}", otherConfig.getOtherConfigValue());
681                     break;
682                 } else {
683                     LOG.info("other_config {}:{}", otherConfig.getOtherConfigKey(), otherConfig.getOtherConfigValue());
684                 }
685             }
686         } else {
687             LOG.info("other_config is not present");
688         }
689     }
690
691     @Test
692     public void testOvsdbBridgeControllerInfo() throws InterruptedException {
693         ConnectionInfo connectionInfo = getConnectionInfo(addressStr,portNumber);
694         String controllerTarget = SouthboundUtil.getControllerTarget(ovsdbNode);
695         assertNotNull("Failed to get controller target", controllerTarget);
696         List<ControllerEntry> setControllerEntry = createControllerEntry(controllerTarget);
697         Uri setUri = new Uri(controllerTarget);
698         try (TestBridge testBridge = new TestBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME,null, true,
699                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null,
700                 setControllerEntry, null)) {
701             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
702             Assert.assertNotNull("bridge was not found: " + SouthboundITConstants.BRIDGE_NAME,  bridge);
703             Assert.assertNotNull("ControllerEntry was not found: " + setControllerEntry.iterator().next(),
704                     bridge.getControllerEntry());
705             List<ControllerEntry> getControllerEntries = bridge.getControllerEntry();
706             for (ControllerEntry entry : getControllerEntries) {
707                 if (entry.getTarget() != null) {
708                     Assert.assertEquals(setUri.toString(), entry.getTarget().toString());
709                 }
710             }
711         }
712     }
713
714     private List<ControllerEntry> createControllerEntry(String controllerTarget) {
715         List<ControllerEntry> controllerEntriesList = new ArrayList<>();
716         controllerEntriesList.add(new ControllerEntryBuilder()
717                 .setTarget(new Uri(controllerTarget))
718                 .build());
719         return controllerEntriesList;
720     }
721
722     private static void setManagedBy(final OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder,
723                               final ConnectionInfo connectionInfo) {
724         InstanceIdentifier<Node> connectionNodePath = SouthboundUtils.createInstanceIdentifier(connectionInfo);
725         ovsdbBridgeAugmentationBuilder.setManagedBy(new OvsdbNodeRef(connectionNodePath));
726     }
727
728     private static List<ProtocolEntry> createMdsalProtocols() {
729         List<ProtocolEntry> protocolList = new ArrayList<>();
730         ImmutableBiMap<String, Class<? extends OvsdbBridgeProtocolBase>> mapper =
731                 SouthboundConstants.OVSDB_PROTOCOL_MAP.inverse();
732         protocolList.add(new ProtocolEntryBuilder().setProtocol(mapper.get("OpenFlow13")).build());
733         return protocolList;
734     }
735
736     private OvsdbTerminationPointAugmentationBuilder createGenericOvsdbTerminationPointAugmentationBuilder() {
737         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationPointAugmentationBuilder =
738                 new OvsdbTerminationPointAugmentationBuilder();
739         ovsdbTerminationPointAugmentationBuilder.setInterfaceType(
740                 new InterfaceTypeEntryBuilder()
741                         .setInterfaceType(
742                                 SouthboundMapper.createInterfaceType("internal"))
743                         .build().getInterfaceType());
744         return ovsdbTerminationPointAugmentationBuilder;
745     }
746
747     private OvsdbTerminationPointAugmentationBuilder createGenericDpdkOvsdbTerminationPointAugmentationBuilder(
748             final String portName) {
749         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
750                 createGenericOvsdbTerminationPointAugmentationBuilder();
751         ovsdbTerminationBuilder.setName(portName);
752         Class<? extends InterfaceTypeBase> ifType = SouthboundConstants.OVSDB_INTERFACE_TYPE_MAP
753                 .get("dpdk");
754         ovsdbTerminationBuilder.setInterfaceType(ifType);
755         return ovsdbTerminationBuilder;
756     }
757
758     private OvsdbTerminationPointAugmentationBuilder createSpecificDpdkOvsdbTerminationPointAugmentationBuilder(
759             String testPortname,Class<? extends InterfaceTypeBase> dpdkIfType) {
760         OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
761                 createGenericOvsdbTerminationPointAugmentationBuilder();
762         ovsdbTerminationBuilder.setName(testPortname);
763         ovsdbTerminationBuilder.setInterfaceType(dpdkIfType);
764         return ovsdbTerminationBuilder;
765     }
766
767     private boolean addTerminationPoint(final NodeId bridgeNodeId, final String portName,
768                                         final OvsdbTerminationPointAugmentationBuilder
769                                                 ovsdbTerminationPointAugmentationBuilder)
770             throws InterruptedException {
771
772         InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(bridgeNodeId);
773         NodeBuilder portNodeBuilder = new NodeBuilder();
774         NodeId portNodeId = SouthboundMapper.createManagedNodeId(portIid);
775         portNodeBuilder.setNodeId(portNodeId);
776         TerminationPointBuilder entry = new TerminationPointBuilder();
777         entry.setKey(new TerminationPointKey(new TpId(portName)));
778         entry.addAugmentation(
779                 OvsdbTerminationPointAugmentation.class,
780                 ovsdbTerminationPointAugmentationBuilder.build());
781         portNodeBuilder.setTerminationPoint(Lists.newArrayList(entry.build()));
782         boolean result = mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
783                 portIid, portNodeBuilder.build());
784         Thread.sleep(OVSDB_UPDATE_TIMEOUT);
785         return result;
786     }
787
788     private static class TestBridge implements AutoCloseable {
789         private final ConnectionInfo connectionInfo;
790         private final String bridgeName;
791
792         /**
793          * Creates a test bridge which can be automatically removed when no longer necessary.
794          *
795          * @param connectionInfo The connection information.
796          * @param bridgeIid The bridge identifier; if {@code null}, one is created based on {@code bridgeName}.
797          * @param bridgeName The bridge name; must be provided.
798          * @param bridgeNodeId The bridge node identifier; if {@code null}, one is created based on {@code bridgeIid}.
799          * @param setProtocolEntries {@code true} to set default protocol entries for the bridge.
800          * @param failMode The fail mode to set for the bridge.
801          * @param setManagedBy {@code true} to specify {@code setManagedBy} for the bridge.
802          * @param dpType The datapath type.
803          * @param externalIds The external identifiers if any.
804          * @param otherConfigs The other configuration items if any.
805          */
806         public TestBridge(final ConnectionInfo connectionInfo, @Nullable InstanceIdentifier<Node> bridgeIid,
807                                   final String bridgeName, NodeId bridgeNodeId, final boolean setProtocolEntries,
808                                   final Class<? extends OvsdbFailModeBase> failMode, final boolean setManagedBy,
809                                   @Nullable final Class<? extends DatapathTypeBase> dpType,
810                                   @Nullable final List<BridgeExternalIds> externalIds,
811                                   @Nullable final List<ControllerEntry> controllerEntries,
812                                   @Nullable final List<BridgeOtherConfigs> otherConfigs) {
813             this.connectionInfo = connectionInfo;
814             this.bridgeName = bridgeName;
815             NodeBuilder bridgeNodeBuilder = new NodeBuilder();
816             if (bridgeIid == null) {
817                 bridgeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
818             }
819             if (bridgeNodeId == null) {
820                 bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
821             }
822             bridgeNodeBuilder.setNodeId(bridgeNodeId);
823             OvsdbBridgeAugmentationBuilder ovsdbBridgeAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
824             ovsdbBridgeAugmentationBuilder.setBridgeName(new OvsdbBridgeName(bridgeName));
825             if (setProtocolEntries) {
826                 ovsdbBridgeAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
827             }
828             ovsdbBridgeAugmentationBuilder.setFailMode(failMode);
829             if (setManagedBy) {
830                 setManagedBy(ovsdbBridgeAugmentationBuilder, connectionInfo);
831             }
832             ovsdbBridgeAugmentationBuilder.setDatapathType(dpType);
833             ovsdbBridgeAugmentationBuilder.setBridgeExternalIds(externalIds);
834             ovsdbBridgeAugmentationBuilder.setControllerEntry(controllerEntries);
835             ovsdbBridgeAugmentationBuilder.setBridgeOtherConfigs(otherConfigs);
836             bridgeNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class, ovsdbBridgeAugmentationBuilder.build());
837             LOG.debug("Built with the intent to store bridge data {}", ovsdbBridgeAugmentationBuilder.toString());
838             Assert.assertTrue(
839                     mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid, bridgeNodeBuilder.build()));
840             try {
841                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
842             } catch (InterruptedException e) {
843                 LOG.warn("Sleep interrupted while waiting for bridge creation (bridge {})", bridgeName, e);
844             }
845         }
846
847         public TestBridge(final ConnectionInfo connectionInfo, final String bridgeName) {
848             this(connectionInfo, null, bridgeName, null, true,
849                     SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null, null);
850         }
851
852         @Override
853         public void close() {
854             final InstanceIdentifier<Node> iid =
855                     SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
856             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
857             try {
858                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
859             } catch (InterruptedException e) {
860                 LOG.warn("Sleep interrupted while waiting for bridge deletion (bridge {})", bridgeName, e);
861             }
862         }
863     }
864
865     private static class TestAutoAttach implements AutoCloseable {
866         private final ConnectionInfo connectionInfo;
867         private final Uri autoattachId;
868         private final Uri bridgeId;
869
870         public TestAutoAttach (final ConnectionInfo connectionInfo,
871                 final Uri autoattachId,
872                 final Uri bridgeId,
873                 @Nullable final String systemName,
874                 @Nullable final String systemDescription,
875                 @Nullable final List<Mappings> mappings,
876                 @Nullable final List<AutoattachExternalIds> externalIds) {
877             this.connectionInfo = connectionInfo;
878             this.autoattachId = autoattachId;
879             this.bridgeId = bridgeId;
880
881             Autoattach aaEntry = new AutoattachBuilder()
882                     .setAutoattachId(autoattachId)
883                     .setBridgeId(bridgeId)
884                     .setSystemName(systemName)
885                     .setSystemDescription(systemDescription)
886                     .setMappings(mappings)
887                     .setAutoattachExternalIds(externalIds)
888                     .build();
889             InstanceIdentifier<Autoattach> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
890                     .augmentation(OvsdbNodeAugmentation.class)
891                     .child(Autoattach.class, aaEntry.getKey());
892             final NotifyingDataChangeListener aaOperationalListener =
893                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, iid);
894             aaOperationalListener.registerDataChangeListener();
895
896             Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, iid, aaEntry));
897             try {
898                 aaOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT);
899             } catch (InterruptedException e) {
900                 LOG.warn("Sleep interrupted while waiting for queue {}", iid, e);
901             }
902         }
903         @Override
904         public void close() {
905             final InstanceIdentifier<Autoattach> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
906                     .augmentation(OvsdbNodeAugmentation.class)
907                     .child(Autoattach.class, new AutoattachKey(this.autoattachId));
908             final NotifyingDataChangeListener aaOperationalListener =
909                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, iid);
910             aaOperationalListener.registerDataChangeListener();
911
912             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
913             try {
914                 aaOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT);
915             } catch (InterruptedException e) {
916                 LOG.warn("Sleep interrupted while waiting for qos deletion (qos {})", iid, e);
917             }
918         }
919     }
920
921     @Test
922     public void testCRUDAutoAttach() throws InterruptedException {
923         final boolean isOldSchema = schemaVersion.compareTo(AUTOATTACH_FROM_VERSION) < 0;
924
925         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
926         String testAutoattachId = new String("testAutoattachEntry");
927         String testSystemName = new String("testSystemName");
928         String testSystemDescription = new String("testSystemDescription");
929         String testAutoattachExternalKey = new String("testAutoattachExternalKey");
930         String testAutoattachExternalValue = new String("testAutoattachExternalValue");
931
932         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
933             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
934             Assert.assertNotNull(bridge);
935
936             // CREATE: Create Autoattach table
937             NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
938                     connectionInfo, bridge.getBridgeName()));
939             String bridgeId = nodeId.getValue();
940             try(TestAutoAttach testAutoattach = new TestAutoAttach(connectionInfo, new Uri(testAutoattachId),
941                     new Uri(bridgeId), testSystemName, testSystemDescription, null, null)) {
942                 // READ: Read md-sal operational datastore to see if the AutoAttach table was created
943                 // and if Bridge table was updated with AutoAttach Uuid
944                 OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
945                         LogicalDatastoreType.OPERATIONAL);
946                 Autoattach operAa = getAutoAttach(ovsdbNodeAugmentation, new Uri(testAutoattachId));
947
948                 // skip tests after verifying that Autoattach doesn't break with unsupported schema
949                 Assume.assumeFalse(isOldSchema);
950
951                 // FIXME: Remove once CRUD is supported
952                 Assume.assumeFalse(operAa == null);
953
954                 Assert.assertNotNull(operAa);
955                 Assert.assertEquals(testSystemName, operAa.getSystemName());
956                 bridge = getBridge(connectionInfo);
957                 Uuid aaUuid = new Uuid(operAa.getAutoattachUuid().getValue());
958                 Assert.assertEquals(aaUuid, bridge.getAutoAttach());
959
960                 // UPDATE: Update mappings column of AutoAttach table that was created
961                 List<Mappings> mappings = ImmutableList.of(new MappingsBuilder().setMappingsKey(100L).setMappingsValue(200).build());
962                 Autoattach updatedAa = new AutoattachBuilder()
963                         .setAutoattachId(new Uri(testAutoattachId))
964                         .setMappings(mappings)
965                         .build();
966                 InstanceIdentifier<Autoattach> iid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
967                         .augmentation(OvsdbNodeAugmentation.class)
968                         .child(Autoattach.class, updatedAa.getKey());
969                 final NotifyingDataChangeListener aaOperationalListener =
970                         new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, iid);
971                 aaOperationalListener.registerDataChangeListener();
972                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, iid, updatedAa));
973                 aaOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
974
975                 // UPDATE: Update external_ids column of AutoAttach table that was created
976                 List<AutoattachExternalIds> externalIds = new ArrayList<>();
977                 externalIds.add(new AutoattachExternalIdsBuilder()
978                         .setAutoattachExternalIdKey(testAutoattachExternalKey)
979                         .setAutoattachExternalIdValue(testAutoattachExternalValue)
980                         .build());
981                 updatedAa = new AutoattachBuilder()
982                         .setAutoattachId(new Uri(testAutoattachId))
983                         .setAutoattachExternalIds(externalIds)
984                         .build();
985                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, iid, updatedAa));
986                 aaOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
987
988                 // READ: Read the updated AutoAttach table for latest mappings and external_ids column value
989                 ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
990                         LogicalDatastoreType.OPERATIONAL);
991                 operAa = getAutoAttach(ovsdbNodeAugmentation, new Uri(testAutoattachId));
992                 Assert.assertNotNull(operAa);
993                 List<Mappings> operMappingsList = operAa.getMappings();
994                 for (Mappings operMappings: operMappingsList) {
995                     Assert.assertEquals(mappings.get(operMappingsList.indexOf(operMappings)).getMappingsKey(), operMappings.getMappingsKey());
996                     Assert.assertEquals(mappings.get(operMappingsList.indexOf(operMappings)).getMappingsValue(), operMappings.getMappingsValue());
997                 }
998                 List<AutoattachExternalIds> operExternalIds = operAa.getAutoattachExternalIds();
999                 externalIds.add(new AutoattachExternalIdsBuilder()
1000                         .setAutoattachExternalIdKey(SouthboundConstants.AUTOATTACH_ID_EXTERNAL_ID_KEY)
1001                         .setAutoattachExternalIdValue(operAa.getAutoattachId().getValue())
1002                         .build());
1003                 for (AutoattachExternalIds operExternalId : operExternalIds) {
1004                     Assert.assertEquals(externalIds.get(operExternalIds.indexOf(operExternalId)).getAutoattachExternalIdKey(),
1005                             operExternalId.getAutoattachExternalIdKey());
1006                     Assert.assertEquals(externalIds.get(operExternalIds.indexOf(operExternalId)).getAutoattachExternalIdValue(),
1007                             operExternalId.getAutoattachExternalIdValue());
1008                 }
1009
1010                 // DELETE: Delete AutoAttach table
1011                 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, iid));
1012                 aaOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
1013                 ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
1014                         LogicalDatastoreType.OPERATIONAL);
1015                 operAa = getAutoAttach(ovsdbNodeAugmentation, new Uri(testAutoattachId));
1016                 Assert.assertNull(operAa);
1017             } catch (AssumptionViolatedException e) {
1018                 LOG.warn("Skipped test for Autoattach due to unsupported schema", e);
1019             } catch (Exception e) {
1020                 fail("Unexpected exception in CRUD test for Autoattach table for schema:" + schemaVersion.toString() +". " + e);
1021             }
1022         }
1023     }
1024
1025     private Autoattach getAutoAttach(OvsdbNodeAugmentation ovsdbNodeAugmentation, Uri uri) {
1026         if (ovsdbNodeAugmentation.getAutoattach() != null
1027                 && !ovsdbNodeAugmentation.getAutoattach().isEmpty()) {
1028             for (Autoattach aa : ovsdbNodeAugmentation.getAutoattach()) {
1029                 if (aa.getKey().getAutoattachId().equals(uri)) {
1030                     return aa;
1031                 }
1032             }
1033         }
1034         return null;
1035     }
1036
1037     private static class TestQos implements AutoCloseable {
1038         private final ConnectionInfo connectionInfo;
1039         private final Uri qosId;
1040
1041         /**
1042          * Creates a test qos entry which can be automatically removed when no longer necessary.
1043          *
1044          * @param connectionInfo The connection information.
1045          * @param qosId The Qos identifier.
1046          * @param qosType The qos type.
1047          * @param externalIds The external identifiers if any.
1048          * @param otherConfigs The other configuration items if any.
1049          */
1050         public TestQos(final ConnectionInfo connectionInfo,
1051                                   final Uri qosId,
1052                                   final Class<? extends QosTypeBase> qosType,
1053                                   @Nullable final List<QosExternalIds> externalIds,
1054                                   @Nullable final List<QosOtherConfig> otherConfigs) {
1055             this.connectionInfo = connectionInfo;
1056             this.qosId = qosId;
1057
1058             QosEntries qosEntry = new QosEntriesBuilder()
1059                 .setQosId(qosId)
1060                 .setQosType(qosType)
1061                 .setQosExternalIds(externalIds)
1062                 .setQosOtherConfig(otherConfigs)
1063                 .build();
1064             InstanceIdentifier<QosEntries> qeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
1065                     .augmentation(OvsdbNodeAugmentation.class)
1066                     .child(QosEntries.class, qosEntry.getKey());
1067             final NotifyingDataChangeListener qosOperationalListener =
1068                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qeIid);
1069             qosOperationalListener.registerDataChangeListener();
1070
1071             Assert.assertTrue(
1072                     mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1073                     qeIid, qosEntry));
1074
1075             try {
1076                 qosOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT);
1077             } catch (InterruptedException e) {
1078                 LOG.warn("Sleep interrupted while waiting for queue {}", qeIid, e);
1079             }
1080
1081         }
1082
1083         @Override
1084         public void close() {
1085             final InstanceIdentifier<QosEntries> qeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
1086                     .augmentation(OvsdbNodeAugmentation.class)
1087                     .child(QosEntries.class, new QosEntriesKey(this.qosId));
1088             final NotifyingDataChangeListener qosOperationalListener =
1089                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qeIid);
1090             qosOperationalListener.registerDataChangeListener();
1091
1092             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qeIid));
1093             try {
1094                 qosOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT);
1095             } catch (InterruptedException e) {
1096                 LOG.warn("Sleep interrupted while waiting for qos deletion (qos {})", qeIid, e);
1097             }
1098         }
1099     }
1100
1101     private static class TestQueue implements AutoCloseable {
1102         private final ConnectionInfo connectionInfo;
1103         private final Uri queueId;
1104
1105         /**
1106          * Creates a test queue entry which can be automatically removed when no longer necessary.
1107          *
1108          * @param connectionInfo The connection information.
1109          * @param queueId The Queue identifier.
1110          * @param queueDscp The queue dscp value.
1111          * @param externalIds The external identifiers if any.
1112          * @param otherConfigs The other configuration items if any.
1113          */
1114         public TestQueue(final ConnectionInfo connectionInfo,
1115                                   final Uri queueId,
1116                                   final Short queueDscp,
1117                                   @Nullable final List<QueuesExternalIds> externalIds,
1118                                   @Nullable final List<QueuesOtherConfig> otherConfigs) {
1119             this.connectionInfo = connectionInfo;
1120             this.queueId = queueId;
1121
1122             Queues queue = new QueuesBuilder()
1123                 .setQueueId(queueId)
1124                 .setDscp(queueDscp)
1125                 .setQueuesExternalIds(externalIds)
1126                 .setQueuesOtherConfig(otherConfigs)
1127                 .build();
1128             InstanceIdentifier<Queues> qIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
1129                     .augmentation(OvsdbNodeAugmentation.class)
1130                     .child(Queues.class, queue.getKey());
1131             final NotifyingDataChangeListener queueOperationalListener =
1132                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qIid);
1133             queueOperationalListener.registerDataChangeListener();
1134
1135             Assert.assertTrue(
1136                     mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1137                     qIid, queue));
1138
1139             try {
1140                 queueOperationalListener.waitForCreation(OVSDB_ROUNDTRIP_TIMEOUT);
1141             } catch (InterruptedException e) {
1142                 LOG.warn("Sleep interrupted while waiting for queue {}", queueId, e);
1143             }
1144         }
1145
1146         @Override
1147         public void close() {
1148             InstanceIdentifier<Queues> qIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
1149                     .augmentation(OvsdbNodeAugmentation.class)
1150                     .child(Queues.class, new QueuesKey(this.queueId));
1151             final NotifyingDataChangeListener queueOperationalListener =
1152                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qIid);
1153             queueOperationalListener.registerDataChangeListener();
1154
1155             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qIid));
1156             try {
1157                 queueOperationalListener.waitForDeletion(OVSDB_ROUNDTRIP_TIMEOUT);
1158             } catch (InterruptedException e) {
1159                 LOG.warn("Sleep interrupted while waiting for queue deletion (queue {})", queueId, e);
1160             }
1161         }
1162     }
1163
1164     private OvsdbNodeAugmentation getOvsdbNode(ConnectionInfo connectionInfo, LogicalDatastoreType store) {
1165         InstanceIdentifier<Node> nodeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
1166         Node node = mdsalUtils.read(store, nodeIid);
1167         Assert.assertNotNull(node);
1168         OvsdbNodeAugmentation ovsdbNodeAugmentation = node.getAugmentation(OvsdbNodeAugmentation.class);
1169         Assert.assertNotNull(ovsdbNodeAugmentation);
1170         return ovsdbNodeAugmentation;
1171     }
1172
1173     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo) {
1174         return getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1175     }
1176
1177     /**
1178      * Extract the <code>store</code> type data store contents for the particular bridge identified by
1179      * <code>bridgeName</code>.
1180      *
1181      * @param connectionInfo the connection information
1182      * @param bridgeName the bridge name
1183      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
1184      * @return <code>store</code> type data store contents
1185      */
1186     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName,
1187                                               LogicalDatastoreType store) {
1188         Node bridgeNode = getBridgeNode(connectionInfo, bridgeName, store);
1189         Assert.assertNotNull(bridgeNode);
1190         OvsdbBridgeAugmentation ovsdbBridgeAugmentation = bridgeNode.getAugmentation(OvsdbBridgeAugmentation.class);
1191         Assert.assertNotNull(ovsdbBridgeAugmentation);
1192         return ovsdbBridgeAugmentation;
1193     }
1194
1195     /**
1196      * extract the <code>LogicalDataStoreType.OPERATIONAL</code> type data store contents for the particular bridge
1197      * identified by <code>bridgeName</code>
1198      *
1199      * @param connectionInfo the connection information
1200      * @param bridgeName the bridge name
1201      * @see <code>SouthboundIT.getBridge(ConnectionInfo, String, LogicalDatastoreType)</code>
1202      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
1203      */
1204     private OvsdbBridgeAugmentation getBridge(ConnectionInfo connectionInfo, String bridgeName) {
1205         return getBridge(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
1206     }
1207
1208     /**
1209      * Extract the node contents from <code>store</code> type data store for the
1210      * bridge identified by <code>bridgeName</code>
1211      *
1212      * @param connectionInfo the connection information
1213      * @param bridgeName the bridge name
1214      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
1215      * @return <code>store</code> type data store contents
1216      */
1217     private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store) {
1218         InstanceIdentifier<Node> bridgeIid =
1219                 SouthboundUtils.createInstanceIdentifier(connectionInfo, new OvsdbBridgeName(bridgeName));
1220         return mdsalUtils.read(store, bridgeIid);
1221     }
1222
1223     /**
1224      * Extract the node contents from <code>LogicalDataStoreType.OPERATIONAL</code> data store for the
1225      * bridge identified by <code>bridgeName</code>
1226      *
1227      * @param connectionInfo the connection information
1228      * @param bridgeName the bridge name
1229      * @return <code>LogicalDatastoreType.OPERATIONAL</code> type data store contents
1230      */
1231     private Node getBridgeNode(ConnectionInfo connectionInfo, String bridgeName) {
1232         return getBridgeNode(connectionInfo, bridgeName, LogicalDatastoreType.OPERATIONAL);
1233     }
1234
1235     @Test
1236     public void testAddDeleteBridge() throws InterruptedException {
1237         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1238
1239         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1240             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1241             Assert.assertNotNull(bridge);
1242             LOG.info("bridge: {}", bridge);
1243         }
1244     }
1245
1246     private InstanceIdentifier<Node> getTpIid(ConnectionInfo connectionInfo, OvsdbBridgeAugmentation bridge) {
1247         return SouthboundUtils.createInstanceIdentifier(connectionInfo, bridge.getBridgeName());
1248     }
1249
1250     /**
1251      * Extracts the <code>TerminationPointAugmentation</code> for the <code>index</code> <code>TerminationPoint</code>
1252      * on <code>bridgeName</code>
1253      *
1254      * @param connectionInfo the connection information
1255      * @param bridgeName the bridge name
1256      * @param store defined by the <code>LogicalDatastoreType</code> enumeration
1257      * @param index the index we're interested in
1258      * @return the augmentation (or {@code null} if none)
1259      */
1260     private OvsdbTerminationPointAugmentation getOvsdbTerminationPointAugmentation(
1261             ConnectionInfo connectionInfo, String bridgeName, LogicalDatastoreType store, int index) {
1262
1263         List<TerminationPoint> tpList = getBridgeNode(connectionInfo, bridgeName, store).getTerminationPoint();
1264         if (tpList == null) {
1265             return null;
1266         }
1267         return tpList.get(index).getAugmentation(OvsdbTerminationPointAugmentation.class);
1268     }
1269
1270     @Test
1271     public void testCRUDTerminationPointIfIndex() throws InterruptedException {
1272         final boolean isOldSchema = schemaVersion.compareTo(IF_INDEX_FROM_VERSION) < 0;
1273         Assume.assumeFalse(isOldSchema);
1274         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1275
1276         // Test create ifIndex
1277         try (TestBridge testBridge = new TestBridge(connectionInfo, null, SouthboundITConstants.BRIDGE_NAME, null, true,
1278                 SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"),
1279                 true, SouthboundMapper.createDatapathType("netdev"), null, null, null)) {
1280             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1281             Assert.assertNotNull(bridge);
1282             LOG.info("bridge: {}", bridge);
1283             NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1284                     connectionInfo, bridge.getBridgeName()));
1285             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1286                     createGenericOvsdbTerminationPointAugmentationBuilder();
1287             String portName = "testIfIndex";
1288             ovsdbTerminationBuilder.setName(portName);
1289
1290             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1291             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1292             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1293             Assert.assertNotNull(terminationPointNode);
1294
1295             // Test read ifIndex
1296             List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1297             for (TerminationPoint terminationPoint : terminationPoints) {
1298                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1299                         terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1300                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1301                     Long ifIndex = ovsdbTerminationPointAugmentation.getIfindex();
1302                     Assert.assertNotNull(ifIndex);
1303                     LOG.info("ifIndex: {} for the port:{}", ifIndex, portName);
1304                 }
1305             }
1306         }
1307     }
1308
1309     @Test
1310     public void testCRDTerminationPointOfPort() throws InterruptedException {
1311         final Long OFPORT_EXPECTED = 45002L;
1312
1313         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1314
1315         // CREATE
1316         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1317             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1318             Assert.assertNotNull(bridge);
1319             LOG.info("bridge: {}", bridge);
1320             NodeId nodeId = SouthboundMapper.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1321                     connectionInfo, bridge.getBridgeName()));
1322             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1323                     createGenericOvsdbTerminationPointAugmentationBuilder();
1324             String portName = "testOfPort";
1325             ovsdbTerminationBuilder.setName(portName);
1326
1327             ovsdbTerminationBuilder.setOfport(OFPORT_EXPECTED);
1328             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1329             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1330             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1331             Assert.assertNotNull(terminationPointNode);
1332
1333             // READ
1334             List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1335             for (TerminationPoint terminationPoint : terminationPoints) {
1336                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1337                         terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1338                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1339                     Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
1340                     // if ephemeral port 45002 is in use, ofPort is set to 1
1341                     Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(1L));
1342                     LOG.info("ofPort: {}", ofPort);
1343                 }
1344             }
1345
1346             // UPDATE- Not Applicable.  From the OpenVSwitch Documentation:
1347             //   "A client should ideally set this column’s value in the same database transaction that it uses to create
1348             //   the interface."
1349
1350             // DELETE handled by TestBridge
1351         }
1352     }
1353
1354     @Test
1355     public void testCRDTerminationPointOfPortRequest() throws InterruptedException {
1356         final Long OFPORT_EXPECTED = 45008L;
1357         final Long OFPORT_INPUT = 45008L;
1358
1359         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1360
1361         // CREATE
1362         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1363             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1364             Assert.assertNotNull(bridge);
1365             NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1366                     connectionInfo, bridge.getBridgeName()));
1367             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1368                     createGenericOvsdbTerminationPointAugmentationBuilder();
1369             String portName = "testOfPortRequest";
1370             ovsdbTerminationBuilder.setName(portName);
1371             Integer ofPortRequestExpected = OFPORT_EXPECTED.intValue();
1372             ovsdbTerminationBuilder.setOfport(OFPORT_INPUT);
1373             ovsdbTerminationBuilder.setOfportRequest(ofPortRequestExpected);
1374             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1375             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1376             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1377             Assert.assertNotNull(terminationPointNode);
1378
1379             // READ
1380             List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1381             for (TerminationPoint terminationPoint : terminationPoints) {
1382                 OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1383                         terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1384                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1385                     Long ofPort = ovsdbTerminationPointAugmentation.getOfport();
1386                     // if ephemeral port 45008 is in use, ofPort is set to 1
1387                     Assert.assertTrue(ofPort.equals(OFPORT_EXPECTED) || ofPort.equals(1L));
1388                     LOG.info("ofPort: {}", ofPort);
1389
1390                     Integer ofPortRequest = ovsdbTerminationPointAugmentation.getOfportRequest();
1391                     Assert.assertTrue(ofPortRequest.equals(ofPortRequestExpected));
1392                     LOG.info("ofPortRequest: {}", ofPortRequest);
1393                 }
1394             }
1395
1396             // UPDATE- Not Applicable.  From the OpenVSwitch documentation:
1397             //   "A client should ideally set this column’s value in the same database transaction that it uses to
1398             //   create the interface. "
1399
1400             // DELETE handled by TestBridge
1401         }
1402     }
1403
1404     private <T> void assertExpectedExist(List<T> expected, List<T> test) {
1405         if (expected != null && test != null) {
1406             for (T exp : expected) {
1407                 Assert.assertTrue("The retrieved values don't contain " + exp, test.contains(exp));
1408             }
1409         }
1410     }
1411
1412     private interface SouthboundTerminationPointHelper<T> {
1413         void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<T> values);
1414         List<T> readValues(OvsdbTerminationPointAugmentation augmentation);
1415     }
1416
1417     /*
1418      * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
1419      *
1420      * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1421      */
1422     private <T> void testCRUDTerminationPoint(
1423             KeyValueBuilder<T> builder, String prefix, SouthboundTerminationPointHelper<T> helper)
1424             throws InterruptedException {
1425         final int TERMINATION_POINT_TEST_INDEX = 0;
1426
1427         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1428
1429         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
1430         // the update has been performed.
1431         List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
1432         List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
1433
1434         for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
1435             for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
1436                 String testBridgeAndPortName = String.format("%s_%s", prefix, updateToTestCase.name);
1437
1438                 // CREATE: Create the test bridge
1439                 try (TestBridge testBridge = new TestBridge(connectionInfo, null, testBridgeAndPortName, null, true,
1440                         SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"), true, null, null, null,
1441                         null)) {
1442                     NodeId testBridgeNodeId = SouthboundUtils.createManagedNodeId(
1443                             SouthboundUtils.createInstanceIdentifier(connectionInfo,
1444                                     new OvsdbBridgeName(testBridgeAndPortName)));
1445                     OvsdbTerminationPointAugmentationBuilder tpCreateAugmentationBuilder =
1446                             createGenericOvsdbTerminationPointAugmentationBuilder();
1447                     tpCreateAugmentationBuilder.setName(testBridgeAndPortName);
1448                     helper.writeValues(tpCreateAugmentationBuilder, updateFromTestCase.inputValues);
1449                     Assert.assertTrue(
1450                             addTerminationPoint(testBridgeNodeId, testBridgeAndPortName, tpCreateAugmentationBuilder));
1451
1452                     // READ: Read the test port and ensure changes are propagated to the CONFIGURATION data store,
1453                     // then repeat for OPERATIONAL data store
1454                     OvsdbTerminationPointAugmentation updateFromConfigurationTerminationPointAugmentation =
1455                             getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1456                                     LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1457                     if (updateFromConfigurationTerminationPointAugmentation != null) {
1458                         List<T> updateFromConfigurationValues =
1459                                 helper.readValues(updateFromConfigurationTerminationPointAugmentation);
1460                         assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues);
1461                     }
1462                     OvsdbTerminationPointAugmentation updateFromOperationalTerminationPointAugmentation =
1463                             getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1464                                     LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1465                     if (updateFromOperationalTerminationPointAugmentation != null) {
1466                         List<T> updateFromOperationalValues =
1467                                 helper.readValues(updateFromOperationalTerminationPointAugmentation);
1468                         assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalValues);
1469                     }
1470
1471                     // UPDATE:  update the values
1472                     testBridgeNodeId = getBridgeNode(connectionInfo, testBridgeAndPortName).getNodeId();
1473                     OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1474                             new OvsdbTerminationPointAugmentationBuilder();
1475                     helper.writeValues(tpUpdateAugmentationBuilder, updateToTestCase.inputValues);
1476                     InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1477                     NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1478                     NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1479                     portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1480                     TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1481                     tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(testBridgeAndPortName)));
1482                     tpUpdateBuilder.addAugmentation(
1483                             OvsdbTerminationPointAugmentation.class,
1484                             tpUpdateAugmentationBuilder.build());
1485                     portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1486                     Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
1487                             portIid, portUpdateNodeBuilder.build()));
1488                     Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1489
1490                     // READ: the test port and ensure changes are propagated to the CONFIGURATION data store,
1491                     // then repeat for OPERATIONAL data store
1492                     OvsdbTerminationPointAugmentation updateToConfigurationTerminationPointAugmentation =
1493                             getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1494                                     LogicalDatastoreType.CONFIGURATION, TERMINATION_POINT_TEST_INDEX);
1495                     if (updateToConfigurationTerminationPointAugmentation != null) {
1496                         List<T> updateToConfigurationValues =
1497                                 helper.readValues(updateToConfigurationTerminationPointAugmentation);
1498                         assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues);
1499                         assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationValues);
1500                     }
1501                     OvsdbTerminationPointAugmentation updateToOperationalTerminationPointAugmentation =
1502                             getOvsdbTerminationPointAugmentation(connectionInfo, testBridgeAndPortName,
1503                                     LogicalDatastoreType.OPERATIONAL, TERMINATION_POINT_TEST_INDEX);
1504                     if (updateToOperationalTerminationPointAugmentation != null) {
1505                         List<T> updateToOperationalValues =
1506                                 helper.readValues(updateToOperationalTerminationPointAugmentation);
1507                         if (updateFromTestCase.expectedValues != null) {
1508                             assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues);
1509                             assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalValues);
1510                         }
1511                     }
1512
1513                     // DELETE handled by TestBridge
1514                 }
1515             }
1516         }
1517     }
1518
1519     /*
1520      * Tests the CRUD operations for <code>Port</code> <code>external_ids</code>.
1521      *
1522      * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1523      */
1524     @Test
1525     public void testCRUDTerminationPointPortExternalIds() throws InterruptedException {
1526         testCRUDTerminationPoint(new SouthboundPortExternalIdsBuilder(), "TPPortExternalIds",
1527                 new PortExternalIdsSouthboundHelper());
1528     }
1529
1530     /*
1531      * Tests the CRUD operations for <code>Interface</code> <code>external_ids</code>.
1532      *
1533      * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1534      */
1535     @Test
1536     public void testCRUDTerminationPointInterfaceExternalIds() throws InterruptedException {
1537         testCRUDTerminationPoint(new SouthboundInterfaceExternalIdsBuilder(), "TPInterfaceExternalIds",
1538                 new InterfaceExternalIdsSouthboundHelper());
1539     }
1540
1541     /*
1542      * Tests the CRUD operations for <code>Interface</code> <code>lldp</code>.
1543      *
1544      * @see <code>SouthboundIT.generateInterfaceLldpTestCases()</code> for specific test case information
1545      */
1546     @Test
1547     public void testCRUDTerminationPointInterfaceLldp() throws InterruptedException {
1548         testCRUDTerminationPoint(new SouthboundInterfaceLldpBuilder(), "TPInterfaceLldp",
1549                 new InterfaceLldpSouthboundHelper());
1550     }
1551
1552     /*
1553      * Tests the CRUD operations for <code>TerminationPoint</code> <code>options</code>.
1554      *
1555      * @see <code>SouthboundIT.generateTerminationPointOptions()</code> for specific test case information
1556      */
1557     @Test
1558     public void testCRUDTerminationPointOptions() throws InterruptedException {
1559         testCRUDTerminationPoint(new SouthboundOptionsBuilder(), "TPOptions", new OptionsSouthboundHelper());
1560     }
1561
1562     /*
1563      * Tests the CRUD operations for <code>Interface</code> <code>other_configs</code>.
1564      *
1565      * @see <code>SouthboundIT.generateInterfaceExternalIdsTestCases()</code> for specific test case information
1566      */
1567     @Test
1568     public void testCRUDTerminationPointInterfaceOtherConfigs() throws InterruptedException {
1569         testCRUDTerminationPoint(new SouthboundInterfaceOtherConfigsBuilder(), "TPInterfaceOtherConfigs",
1570                 new InterfaceOtherConfigsSouthboundHelper());
1571     }
1572
1573     /*
1574      * Tests the CRUD operations for <code>Port</code> <code>other_configs</code>.
1575      *
1576      * @see <code>SouthboundIT.generatePortExternalIdsTestCases()</code> for specific test case information
1577      */
1578     @Test
1579     public void testCRUDTerminationPointPortOtherConfigs() throws InterruptedException {
1580         testCRUDTerminationPoint(new SouthboundPortOtherConfigsBuilder(), "TPPortOtherConfigs",
1581                 new PortOtherConfigsSouthboundHelper());
1582     }
1583
1584     @Test
1585     public void testCRUDTerminationPoints() throws InterruptedException {
1586         String port1 = "vx1";
1587         String port2 = "vxlanport";
1588         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1589
1590         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1591             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1592             Assert.assertNotNull(bridge);
1593             NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1594                     connectionInfo, bridge.getBridgeName()));
1595             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1596                     createGenericOvsdbTerminationPointAugmentationBuilder();
1597
1598             // add and delete a single port
1599             String portName = port1;
1600             ovsdbTerminationBuilder.setName(portName);
1601             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1602             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1603             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1604             Assert.assertNotNull(terminationPointNode);
1605
1606             SouthboundUtils.createInstanceIdentifier(connectionInfo,
1607                     new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
1608             portName = port1;
1609             InstanceIdentifier<TerminationPoint> nodePath =
1610                     SouthboundUtils.createInstanceIdentifier(connectionInfo,
1611                             new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME))
1612                             .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
1613
1614             Assert.assertTrue("failed to delete port " + portName,
1615                     mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath));
1616             LOG.info("shague: waiting for delete {}", portName);
1617             Thread.sleep(1000);
1618             TerminationPoint terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath);
1619             Assert.assertNull(terminationPoint);
1620
1621             // add two ports, then delete them
1622             portName = port1;
1623             ovsdbTerminationBuilder.setName(portName);
1624             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1625             terminationPointIid = getTpIid(connectionInfo, bridge);
1626             terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1627             Assert.assertNotNull(terminationPointNode);
1628
1629             portName = port2;
1630             ovsdbTerminationBuilder.setName(portName);
1631             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1632             terminationPointIid = getTpIid(connectionInfo, bridge);
1633             terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1634             Assert.assertNotNull(terminationPointNode);
1635
1636             SouthboundUtils.createInstanceIdentifier(connectionInfo,
1637                     new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME));
1638             portName = port1;
1639             nodePath =
1640                     SouthboundUtils.createInstanceIdentifier(connectionInfo,
1641                             new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME))
1642                             .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
1643
1644             Assert.assertTrue("failed to delete port " + portName,
1645                     mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath));
1646             LOG.info("shague: waiting for delete {}", portName);
1647             Thread.sleep(1000);
1648             terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath);
1649             Assert.assertNull(terminationPoint);
1650
1651             portName = port2;
1652             nodePath = SouthboundUtils.createInstanceIdentifier(connectionInfo,
1653                     new OvsdbBridgeName(SouthboundITConstants.BRIDGE_NAME))
1654                     .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
1655
1656             Assert.assertTrue("failed to delete port " + portName,
1657                     mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, nodePath));
1658             LOG.info("shague: waiting for delete {}", portName);
1659             Thread.sleep(1000);
1660             terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, nodePath);
1661             Assert.assertNull(terminationPoint);
1662
1663             // DELETE handled by TestBridge
1664         }
1665     }
1666
1667     @Test
1668     public void testCRUDTerminationPointVlan() throws InterruptedException {
1669         final Integer CREATED_VLAN_ID = 4000;
1670         final Integer UPDATED_VLAN_ID = 4001;
1671
1672         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1673
1674         // CREATE
1675         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1676             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1677             Assert.assertNotNull(bridge);
1678             NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1679                     connectionInfo, bridge.getBridgeName()));
1680             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1681                     createGenericOvsdbTerminationPointAugmentationBuilder();
1682             String portName = "testTerminationPointVlanId";
1683             ovsdbTerminationBuilder.setName(portName);
1684             ovsdbTerminationBuilder.setVlanTag(new VlanId(CREATED_VLAN_ID));
1685             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1686             InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1687             Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1688             Assert.assertNotNull(terminationPointNode);
1689
1690             // READ
1691             List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1692             OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation;
1693             for (TerminationPoint terminationPoint : terminationPoints) {
1694                 ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
1695                         OvsdbTerminationPointAugmentation.class);
1696                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1697                     VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1698                     Assert.assertNotNull(actualVlanId);
1699                     Integer actualVlanIdInt = actualVlanId.getValue();
1700                     Assert.assertEquals(CREATED_VLAN_ID, actualVlanIdInt);
1701                 }
1702             }
1703
1704             // UPDATE
1705             NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1706             OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1707                     new OvsdbTerminationPointAugmentationBuilder();
1708             tpUpdateAugmentationBuilder.setVlanTag(new VlanId(UPDATED_VLAN_ID));
1709             InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1710             NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1711             NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1712             portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1713             TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1714             tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1715             tpUpdateBuilder.addAugmentation(
1716                     OvsdbTerminationPointAugmentation.class,
1717                     tpUpdateAugmentationBuilder.build());
1718             tpUpdateBuilder.setTpId(new TpId(portName));
1719             portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1720             Assert.assertTrue(
1721                     mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1722             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1723
1724             terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1725             terminationPoints = terminationPointNode.getTerminationPoint();
1726             for (TerminationPoint terminationPoint : terminationPoints) {
1727                 ovsdbTerminationPointAugmentation = terminationPoint.getAugmentation(
1728                         OvsdbTerminationPointAugmentation.class);
1729                 if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1730                     VlanId actualVlanId = ovsdbTerminationPointAugmentation.getVlanTag();
1731                     Assert.assertNotNull(actualVlanId);
1732                     Integer actualVlanIdInt = actualVlanId.getValue();
1733                     Assert.assertEquals(UPDATED_VLAN_ID, actualVlanIdInt);
1734                 }
1735             }
1736
1737             // DELETE handled by TestBridge
1738         }
1739     }
1740
1741     @Test
1742     public void testCRUDTerminationPointVlanModes() throws InterruptedException {
1743         final VlanMode UPDATED_VLAN_MODE = VlanMode.Access;
1744         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1745         VlanMode []vlanModes = VlanMode.values();
1746         for (VlanMode vlanMode : vlanModes) {
1747             // CREATE
1748             try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1749                 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1750                 Assert.assertNotNull(bridge);
1751                 NodeId nodeId = SouthboundUtils.createManagedNodeId(SouthboundUtils.createInstanceIdentifier(
1752                         connectionInfo, bridge.getBridgeName()));
1753                 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1754                         createGenericOvsdbTerminationPointAugmentationBuilder();
1755                 String portName = "testTerminationPointVlanMode" + vlanMode.toString();
1756                 ovsdbTerminationBuilder.setName(portName);
1757                 ovsdbTerminationBuilder.setVlanMode(vlanMode);
1758                 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1759                 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1760                 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1761                 Assert.assertNotNull(terminationPointNode);
1762
1763                 // READ
1764                 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1765                 for (TerminationPoint terminationPoint : terminationPoints) {
1766                     OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1767                             terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1768                     if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1769                         //test
1770                         Assert.assertTrue(ovsdbTerminationPointAugmentation.getVlanMode().equals(vlanMode));
1771                     }
1772                 }
1773
1774                 // UPDATE
1775                 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1776                 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1777                         new OvsdbTerminationPointAugmentationBuilder();
1778                 tpUpdateAugmentationBuilder.setVlanMode(UPDATED_VLAN_MODE);
1779                 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1780                 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1781                 NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1782                 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1783                 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1784                 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1785                 tpUpdateBuilder.addAugmentation(
1786                         OvsdbTerminationPointAugmentation.class,
1787                         tpUpdateAugmentationBuilder.build());
1788                 tpUpdateBuilder.setTpId(new TpId(portName));
1789                 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1790                 Assert.assertTrue(
1791                         mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1792                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1793
1794                 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1795                 terminationPoints = terminationPointNode.getTerminationPoint();
1796                 for (TerminationPoint terminationPoint : terminationPoints) {
1797                     OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1798                             terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1799                     if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1800                         //test
1801                         Assert.assertEquals(UPDATED_VLAN_MODE, ovsdbTerminationPointAugmentation.getVlanMode());
1802                     }
1803                 }
1804
1805                 // DELETE handled by TestBridge
1806             }
1807         }
1808     }
1809
1810     @SuppressWarnings("unchecked")
1811     private List<Set<Integer>> generateVlanSets() {
1812         int min = 0;
1813         int max = 4095;
1814         return Lists.newArrayList(
1815                 Collections.<Integer>emptySet(),
1816                 Sets.newHashSet(2222),
1817                 Sets.newHashSet(min, max, min + 1, max - 1, (max - min) / 2));
1818     }
1819
1820     private List<Trunks> buildTrunkList(Set<Integer> trunkSet) {
1821         List<Trunks> trunkList = Lists.newArrayList();
1822         for (Integer trunk : trunkSet) {
1823             TrunksBuilder trunkBuilder = new TrunksBuilder();
1824             trunkBuilder.setTrunk(new VlanId(trunk));
1825             trunkList.add(trunkBuilder.build());
1826         }
1827         return trunkList;
1828     }
1829
1830     @Test
1831     public void testCRUDTerminationPointVlanTrunks() throws InterruptedException {
1832         final List<Trunks> UPDATED_TRUNKS = buildTrunkList(Sets.newHashSet(2011));
1833         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1834         Iterable<Set<Integer>> vlanSets = generateVlanSets();
1835         int testCase = 0;
1836         for (Set<Integer> vlanSet : vlanSets) {
1837             ++testCase;
1838             // CREATE
1839             try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME)) {
1840                 OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1841                 Assert.assertNotNull(bridge);
1842                 NodeId nodeId = SouthboundUtils.createManagedNodeId(connectionInfo, bridge.getBridgeName());
1843                 OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1844                         createGenericOvsdbTerminationPointAugmentationBuilder();
1845                 String portName = "testTerminationPointVlanTrunks" + testCase;
1846                 ovsdbTerminationBuilder.setName(portName);
1847                 List<Trunks> trunks = buildTrunkList(vlanSet);
1848                 ovsdbTerminationBuilder.setTrunks(trunks);
1849                 Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1850                 InstanceIdentifier<Node> terminationPointIid = getTpIid(connectionInfo, bridge);
1851                 Node terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1852                 Assert.assertNotNull(terminationPointNode);
1853
1854                 // READ
1855                 List<TerminationPoint> terminationPoints = terminationPointNode.getTerminationPoint();
1856                 for (TerminationPoint terminationPoint : terminationPoints) {
1857                     OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1858                             terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1859                     if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1860                         List<Trunks> actualTrunks = ovsdbTerminationPointAugmentation.getTrunks();
1861                         for (Trunks trunk : trunks) {
1862                             Assert.assertTrue(actualTrunks.contains(trunk));
1863                         }
1864                     }
1865                 }
1866
1867
1868                 // UPDATE
1869                 NodeId testBridgeNodeId = getBridgeNode(connectionInfo, SouthboundITConstants.BRIDGE_NAME).getNodeId();
1870                 OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1871                         new OvsdbTerminationPointAugmentationBuilder();
1872                 tpUpdateAugmentationBuilder.setTrunks(UPDATED_TRUNKS);
1873                 InstanceIdentifier<Node> portIid = SouthboundMapper.createInstanceIdentifier(testBridgeNodeId);
1874                 NodeBuilder portUpdateNodeBuilder = new NodeBuilder();
1875                 NodeId portUpdateNodeId = SouthboundUtils.createManagedNodeId(portIid);
1876                 portUpdateNodeBuilder.setNodeId(portUpdateNodeId);
1877                 TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1878                 tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1879                 tpUpdateBuilder.addAugmentation(
1880                         OvsdbTerminationPointAugmentation.class,
1881                         tpUpdateAugmentationBuilder.build());
1882                 tpUpdateBuilder.setTpId(new TpId(portName));
1883                 portUpdateNodeBuilder.setTerminationPoint(Lists.newArrayList(tpUpdateBuilder.build()));
1884                 Assert.assertTrue(
1885                         mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, portIid, portUpdateNodeBuilder.build()));
1886                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1887
1888                 terminationPointNode = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, terminationPointIid);
1889                 terminationPoints = terminationPointNode.getTerminationPoint();
1890                 for (TerminationPoint terminationPoint : terminationPoints) {
1891                     OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1892                             terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1893                     if (ovsdbTerminationPointAugmentation.getName().equals(portName)) {
1894                         //test
1895                         Assert.assertEquals(UPDATED_TRUNKS, ovsdbTerminationPointAugmentation.getTrunks());
1896                     }
1897                 }
1898
1899                 // DELETE handled by TestBridge
1900             }
1901         }
1902     }
1903
1904     /*
1905      * Tests setting and deleting <code>qos</code> field in a <code>port</code>.
1906      */
1907     @Test
1908     public void testCRUDTerminationPointQos() throws InterruptedException {
1909         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1910         String testQosId = new String("testQosEntry");
1911
1912         // CREATE
1913         try (TestBridge testBridge = new TestBridge(connectionInfo, SouthboundITConstants.BRIDGE_NAME);
1914                 TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId),
1915                         SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HFSC), null, null)) {
1916             OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
1917                     LogicalDatastoreType.OPERATIONAL);
1918             QosEntries operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
1919             Assert.assertNotNull(operQos);
1920             Uuid qosUuid = new Uuid(operQos.getQosUuid().getValue());
1921
1922             OvsdbBridgeAugmentation bridge = getBridge(connectionInfo);
1923             Assert.assertNotNull(bridge);
1924             NodeId nodeId = SouthboundUtils.createManagedNodeId(connectionInfo, bridge.getBridgeName());
1925             OvsdbTerminationPointAugmentationBuilder ovsdbTerminationBuilder =
1926                     createGenericOvsdbTerminationPointAugmentationBuilder();
1927             String portName = "testTerminationPointQos";
1928             ovsdbTerminationBuilder.setName(portName);
1929             ovsdbTerminationBuilder.setQos(qosUuid);
1930             Assert.assertTrue(addTerminationPoint(nodeId, portName, ovsdbTerminationBuilder));
1931
1932             // READ and check that qos uuid has been added to the port
1933             InstanceIdentifier<TerminationPoint> tpEntryIid = getTpIid(connectionInfo, bridge)
1934                     .child(TerminationPoint.class, new TerminationPointKey(new TpId(portName)));
1935             TerminationPoint terminationPoint = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, tpEntryIid);
1936             Assert.assertNotNull(terminationPoint);
1937             OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentation =
1938                     terminationPoint.getAugmentation(OvsdbTerminationPointAugmentation.class);
1939             Assert.assertEquals(ovsdbTerminationPointAugmentation.getQos(), qosUuid);
1940
1941             // UPDATE - remove the qos entry from the port
1942             OvsdbTerminationPointAugmentationBuilder tpUpdateAugmentationBuilder =
1943                     new OvsdbTerminationPointAugmentationBuilder();
1944             tpUpdateAugmentationBuilder.setName(portName);
1945             TerminationPointBuilder tpUpdateBuilder = new TerminationPointBuilder();
1946             tpUpdateBuilder.setKey(new TerminationPointKey(new TpId(portName)));
1947             tpUpdateBuilder.addAugmentation(
1948                     OvsdbTerminationPointAugmentation.class,
1949                     tpUpdateAugmentationBuilder.build());
1950             tpUpdateBuilder.setTpId(new TpId(portName));
1951
1952             Assert.assertTrue(
1953                     mdsalUtils.put(LogicalDatastoreType.CONFIGURATION, tpEntryIid, tpUpdateBuilder.build()));
1954             Thread.sleep(OVSDB_UPDATE_TIMEOUT);
1955
1956             // READ and verify that qos uuid has been removed from port
1957             TerminationPoint terminationPointUpdate = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, tpEntryIid);
1958             Assert.assertNotNull(terminationPointUpdate);
1959             OvsdbTerminationPointAugmentation ovsdbTerminationPointAugmentationUpdate =
1960                     terminationPointUpdate.getAugmentation(OvsdbTerminationPointAugmentation.class);
1961             Assert.assertNull(ovsdbTerminationPointAugmentationUpdate.getQos());
1962
1963             // DELETE handled by TestBridge
1964         }
1965     }
1966
1967     @Test
1968     public void testGetOvsdbNodes() throws InterruptedException {
1969         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
1970         InstanceIdentifier<Topology> topologyPath = InstanceIdentifier
1971                 .create(NetworkTopology.class)
1972                 .child(Topology.class, new TopologyKey(SouthboundConstants.OVSDB_TOPOLOGY_ID));
1973
1974         Topology topology = mdsalUtils.read(LogicalDatastoreType.OPERATIONAL, topologyPath);
1975         InstanceIdentifier<Node> expectedNodeIid = SouthboundUtils.createInstanceIdentifier(connectionInfo);
1976         NodeId expectedNodeId = expectedNodeIid.firstKeyOf(Node.class, NodeKey.class).getNodeId();
1977         Node foundNode = null;
1978         Assert.assertNotNull("Expected to find topology: " + topologyPath, topology);
1979         Assert.assertNotNull("Expected to find some nodes" + topology.getNode());
1980         LOG.info("expectedNodeId: {}, getNode: {}", expectedNodeId, topology.getNode());
1981         for (Node node : topology.getNode()) {
1982             if (node.getNodeId().getValue().equals(expectedNodeId.getValue())) {
1983                 foundNode = node;
1984                 break;
1985             }
1986         }
1987         Assert.assertNotNull("Expected to find Node: " + expectedNodeId, foundNode);
1988     }
1989
1990     /*
1991      * @see <code>SouthboundIT.generateBridgeOtherConfigsTestCases()</code> for specific test case information.
1992      */
1993     @Test
1994     public void testCRUDBridgeOtherConfigs() throws InterruptedException {
1995         testCRUDBridge("BridgeOtherConfigs", new SouthboundBridgeOtherConfigsBuilder(),
1996                 new BridgeOtherConfigsSouthboundHelper());
1997     }
1998
1999     private interface SouthboundBridgeHelper<T> {
2000         void writeValues(OvsdbBridgeAugmentationBuilder builder, List<T> values);
2001         List<T> readValues(OvsdbBridgeAugmentation augmentation);
2002     }
2003
2004     private <T> void testCRUDBridge(String prefix, KeyValueBuilder<T> builder, SouthboundBridgeHelper<T> helper)
2005             throws InterruptedException {
2006         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2007         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
2008         // the update has been performed.
2009         List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
2010         List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
2011         for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
2012             for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
2013                 String testBridgeName = String.format("%s_%s", prefix, updateToTestCase.name);
2014
2015                 // CREATE: Create the test bridge
2016                 final OvsdbBridgeName ovsdbBridgeName = new OvsdbBridgeName(testBridgeName);
2017                 final InstanceIdentifier<Node> bridgeIid =
2018                         SouthboundUtils.createInstanceIdentifier(connectionInfo, ovsdbBridgeName);
2019                 final NodeId bridgeNodeId = SouthboundMapper.createManagedNodeId(bridgeIid);
2020                 final NodeBuilder bridgeCreateNodeBuilder = new NodeBuilder();
2021                 bridgeCreateNodeBuilder.setNodeId(bridgeNodeId);
2022                 OvsdbBridgeAugmentationBuilder bridgeCreateAugmentationBuilder = new OvsdbBridgeAugmentationBuilder();
2023                 bridgeCreateAugmentationBuilder.setBridgeName(ovsdbBridgeName);
2024                 bridgeCreateAugmentationBuilder.setProtocolEntry(createMdsalProtocols());
2025                 bridgeCreateAugmentationBuilder.setFailMode(
2026                         SouthboundConstants.OVSDB_FAIL_MODE_MAP.inverse().get("secure"));
2027                 setManagedBy(bridgeCreateAugmentationBuilder, connectionInfo);
2028                 helper.writeValues(bridgeCreateAugmentationBuilder, updateFromTestCase.inputValues);
2029                 bridgeCreateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class,
2030                         bridgeCreateAugmentationBuilder.build());
2031                 LOG.debug("Built with the intent to store bridge data {}", bridgeCreateAugmentationBuilder.toString());
2032                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
2033                         bridgeCreateNodeBuilder.build()));
2034                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2035
2036                 // READ: Read the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2037                 // then repeat for OPERATIONAL data store
2038                 List<T> updateFromConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName,
2039                         LogicalDatastoreType.CONFIGURATION));
2040                 assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationExternalIds);
2041                 List<T> updateFromOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName));
2042                 assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalExternalIds);
2043
2044                 // UPDATE:  update the values
2045                 final OvsdbBridgeAugmentationBuilder bridgeUpdateAugmentationBuilder =
2046                         new OvsdbBridgeAugmentationBuilder();
2047                 helper.writeValues(bridgeUpdateAugmentationBuilder, updateToTestCase.inputValues);
2048                 final NodeBuilder bridgeUpdateNodeBuilder = new NodeBuilder();
2049                 final Node bridgeNode = getBridgeNode(connectionInfo, testBridgeName);
2050                 bridgeUpdateNodeBuilder.setNodeId(bridgeNode.getNodeId());
2051                 bridgeUpdateNodeBuilder.setKey(bridgeNode.getKey());
2052                 bridgeUpdateNodeBuilder.addAugmentation(OvsdbBridgeAugmentation.class,
2053                         bridgeUpdateAugmentationBuilder.build());
2054                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION, bridgeIid,
2055                         bridgeUpdateNodeBuilder.build()));
2056                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2057
2058                 // READ: the test bridge and ensure changes are propagated to the CONFIGURATION data store,
2059                 // then repeat for OPERATIONAL data store
2060                 List<T> updateToConfigurationExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName,
2061                         LogicalDatastoreType.CONFIGURATION));
2062                 assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationExternalIds);
2063                 assertExpectedExist(updateFromTestCase.expectedValues, updateToConfigurationExternalIds);
2064                 List<T> updateToOperationalExternalIds = helper.readValues(getBridge(connectionInfo, testBridgeName));
2065                 if (updateFromTestCase.expectedValues != null) {
2066                     assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalExternalIds);
2067                     assertExpectedExist(updateFromTestCase.expectedValues, updateToOperationalExternalIds);
2068                 }
2069
2070                 // DELETE
2071                 Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, bridgeIid));
2072                 Thread.sleep(OVSDB_UPDATE_TIMEOUT);
2073             }
2074         }
2075     }
2076
2077     /*
2078      * @see <code>SouthboundIT.generateBridgeExternalIdsTestCases()</code> for specific test case information
2079      */
2080     @Test
2081     public void testCRUDBridgeExternalIds() throws InterruptedException {
2082         testCRUDBridge("BridgeExternalIds", new SouthboundBridgeExternalIdsBuilder(),
2083                 new BridgeExternalIdsSouthboundHelper());
2084     }
2085
2086     @Test
2087     public void testAddDeleteQos() throws InterruptedException {
2088         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2089         OvsdbNodeAugmentation ovsdbNodeAugmentation;
2090         Uri qosUri = new Uri("QOS-ROW");
2091         List<String> typeList = new ArrayList<String>();
2092         typeList.add(SouthboundConstants.QOS_LINUX_HTB);
2093         typeList.add(SouthboundConstants.QOS_LINUX_HFSC);
2094
2095         for (String qosType : typeList) {
2096             try (TestQos testQos = new TestQos(connectionInfo, qosUri, SouthboundMapper.createQosType(qosType), null, null)) {
2097                 ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2098                         LogicalDatastoreType.OPERATIONAL);
2099                 QosEntries operQosHtb = getQos(qosUri, ovsdbNodeAugmentation);
2100                 Assert.assertNotNull(operQosHtb);
2101             }
2102             ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2103                     LogicalDatastoreType.OPERATIONAL);
2104             QosEntries operQosHtb = getQos(qosUri, ovsdbNodeAugmentation);
2105             Assert.assertNull(operQosHtb);
2106         }
2107     }
2108
2109     @Test
2110     public void testAddDeleteQueue() throws InterruptedException {
2111         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2112         Uri queueUri = new Uri("QUEUE-A1");
2113
2114         try (TestQueue testQueue = new TestQueue(connectionInfo, queueUri, new Short("25"), null, null)) {
2115             OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2116                     LogicalDatastoreType.OPERATIONAL);
2117             Queues operQueue = getQueue(queueUri, ovsdbNodeAugmentation);
2118             Assert.assertNotNull(operQueue);
2119         }
2120         OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2121                 LogicalDatastoreType.OPERATIONAL);
2122         Queues operQueue = getQueue(queueUri, ovsdbNodeAugmentation);
2123         Assert.assertNull(operQueue);
2124     }
2125
2126     private static class SouthboundQueuesExternalIdsHelper implements SouthboundQueueHelper<QueuesExternalIds> {
2127         @Override
2128         public void writeValues(QueuesBuilder builder, List<QueuesExternalIds> values) {
2129             builder.setQueuesExternalIds(values);
2130         }
2131
2132         @Override
2133         public List<QueuesExternalIds> readValues(Queues queue) {
2134             return queue.getQueuesExternalIds();
2135         }
2136     }
2137
2138     private static class SouthboundQueuesOtherConfigHelper implements SouthboundQueueHelper<QueuesOtherConfig> {
2139         @Override
2140         public void writeValues(QueuesBuilder builder, List<QueuesOtherConfig> values) {
2141             builder.setQueuesOtherConfig(values);
2142         }
2143
2144         @Override
2145         public List<QueuesOtherConfig> readValues(Queues queue) {
2146             return queue.getQueuesOtherConfig();
2147         }
2148     }
2149
2150     private interface SouthboundQueueHelper<T> {
2151         void writeValues(QueuesBuilder builder, List<T> values);
2152         List<T> readValues(Queues queue);
2153     }
2154
2155     private Queues getQueue(Uri queueId, OvsdbNodeAugmentation node) {
2156         for (Queues queue : node.getQueues()) {
2157             if (queue.getKey().getQueueId().getValue().equals(queueId.getValue()))
2158                 return queue;
2159         }
2160         return null;
2161     }
2162
2163     private static class SouthboundQosExternalIdsHelper implements SouthboundQosHelper<QosExternalIds> {
2164         @Override
2165         public void writeValues(QosEntriesBuilder builder, List<QosExternalIds> values) {
2166             builder.setQosExternalIds(values);
2167         }
2168
2169         @Override
2170         public List<QosExternalIds> readValues(QosEntries qos) {
2171             return qos.getQosExternalIds();
2172         }
2173     }
2174
2175     private static class SouthboundQosOtherConfigHelper implements SouthboundQosHelper<QosOtherConfig> {
2176         @Override
2177         public void writeValues(QosEntriesBuilder builder, List<QosOtherConfig> values) {
2178             builder.setQosOtherConfig(values);
2179         }
2180
2181         @Override
2182         public List<QosOtherConfig> readValues(QosEntries qos) {
2183             return qos.getQosOtherConfig();
2184         }
2185     }
2186
2187     private interface SouthboundQosHelper<T> {
2188         void writeValues(QosEntriesBuilder builder, List<T> values);
2189         List<T> readValues(QosEntries qos);
2190     }
2191
2192     private QosEntries getQos(Uri qosId, OvsdbNodeAugmentation node) {
2193         for (QosEntries qos : node.getQosEntries()) {
2194             if (qos.getKey().getQosId().equals(qosId))
2195                 return qos;
2196         }
2197         return null;
2198     }
2199
2200     private <T> void testCRUDQueue(
2201             KeyValueBuilder<T> builder, String prefix, SouthboundQueueHelper<T> helper)
2202             throws InterruptedException {
2203
2204         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2205
2206         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
2207         // the update has been performed.
2208         List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
2209         List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
2210
2211         for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
2212             for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
2213                 String testQueueId = String.format("%s_%s", prefix, updateToTestCase.name);
2214
2215                 // CREATE: and update the test queue with starting values.
2216                 try (TestQueue testQueue = new TestQueue(connectionInfo, new Uri(testQueueId), new Short("45"), null, null)) {
2217                     QueuesBuilder queuesBuilder = new QueuesBuilder();
2218                     queuesBuilder.setQueueId(new Uri(testQueueId));
2219                     InstanceIdentifier<Queues> queueIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
2220                             .augmentation(OvsdbNodeAugmentation.class)
2221                             .child(Queues.class, queuesBuilder.build().getKey());
2222                     final NotifyingDataChangeListener queueConfigurationListener =
2223                             new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION, queueIid);
2224                     queueConfigurationListener.registerDataChangeListener();
2225                     final NotifyingDataChangeListener queueOperationalListener =
2226                             new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queueIid);
2227                     queueOperationalListener.registerDataChangeListener();
2228
2229                     helper.writeValues(queuesBuilder, updateFromTestCase.inputValues);
2230                     Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2231                             queueIid, queuesBuilder.build()));
2232                     queueConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2233
2234                     // READ: Read the test queue and ensure changes are propagated to the CONFIGURATION data store,
2235                     // then repeat for OPERATIONAL data store
2236                     OvsdbNodeAugmentation updateFromConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2237                             LogicalDatastoreType.CONFIGURATION);
2238                     Queues queueFromConfig = getQueue(new Uri(testQueueId), updateFromConfigurationOvsdbNodeAugmentation);
2239                     if (queueFromConfig != null) {
2240                         List<T> updateFromConfigurationValues =
2241                                 helper.readValues(queueFromConfig);
2242                         assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues);
2243                     }
2244
2245                     queueOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2246                     OvsdbNodeAugmentation updateFromOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2247                             LogicalDatastoreType.OPERATIONAL);
2248                     Queues queueFromOper = getQueue(new Uri(testQueueId), updateFromOperationalOvsdbNodeAugmentation);
2249                     if (queueFromOper != null) {
2250                         List<T> updateFromOperationalValues =
2251                                 helper.readValues(queueFromOper);
2252                         assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalValues);
2253                     }
2254
2255                     // UPDATE:  update the values
2256                     QueuesBuilder queuesUpdateBuilder = new QueuesBuilder();
2257                     queuesUpdateBuilder.setQueueId(new Uri(testQueueId));
2258                     helper.writeValues(queuesUpdateBuilder, updateToTestCase.inputValues);
2259                     Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2260                             queueIid, queuesUpdateBuilder.build()));
2261                     queueConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2262
2263                     // READ: the test queue and ensure changes are propagated to the CONFIGURATION data store,
2264                     // then repeat for OPERATIONAL data store
2265                     OvsdbNodeAugmentation updateToConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2266                             LogicalDatastoreType.CONFIGURATION);
2267                     Queues queueToConfig = getQueue(new Uri(testQueueId), updateToConfigurationOvsdbNodeAugmentation);
2268                     if (queueToConfig != null) {
2269                         List<T> updateToConfigurationValues =
2270                                 helper.readValues(queueToConfig);
2271                         assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues);
2272                     }
2273
2274                     queueOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2275                     OvsdbNodeAugmentation updateToOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2276                             LogicalDatastoreType.OPERATIONAL);
2277                     Queues queueToOper = getQueue(new Uri(testQueueId), updateToOperationalOvsdbNodeAugmentation);
2278                     if (queueToOper != null) {
2279                         List<T> updateToOperationalValues =
2280                                 helper.readValues(queueToOper);
2281                         assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues);
2282                     }
2283
2284                     // DELETE handled by TestQueue
2285                 }
2286             }
2287         }
2288     }
2289
2290     @Test
2291     public void testCRUDQueueExternalIds() throws InterruptedException {
2292         testCRUDQueue(new SouthboundQueuesExternalIdsBuilder(), "QueueExternalIds",
2293                 new SouthboundQueuesExternalIdsHelper());
2294     }
2295
2296     @Test
2297     public void testCRUDQueueOtherConfig() throws InterruptedException {
2298         testCRUDQueue(new SouthboundQueuesOtherConfigBuilder(), "QueueOtherConfig",
2299                 new SouthboundQueuesOtherConfigHelper());
2300     }
2301
2302     @Test
2303     public void testCRUDQueueDscp() throws InterruptedException {
2304         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2305         String testQueueId = "testQueueDscp";
2306
2307         // CREATE: and update the test queue with starting values.
2308         try (TestQueue testQueue = new TestQueue(connectionInfo, new Uri(testQueueId), new Short("0"), null, null)) {
2309             for (Short dscp = 1; dscp < 64; dscp++) {
2310                 QueuesBuilder queuesBuilder = new QueuesBuilder();
2311                 queuesBuilder.setQueueId(new Uri(testQueueId));
2312                 InstanceIdentifier<Queues> queueIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
2313                         .augmentation(OvsdbNodeAugmentation.class)
2314                         .child(Queues.class, queuesBuilder.build().getKey());
2315                 final NotifyingDataChangeListener queueOperationalListener =
2316                         new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queueIid);
2317                 queueOperationalListener.registerDataChangeListener();
2318
2319                 queuesBuilder.setDscp(dscp);
2320                 Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2321                         queueIid, queuesBuilder.build()));
2322                 queueOperationalListener.waitForUpdate(OVSDB_ROUNDTRIP_TIMEOUT);
2323
2324                 // READ: Read the test queue and ensure changes are propagated to the OPERATIONAL data store
2325                 // assumption is that CONFIGURATION was updated if OPERATIONAL is correct
2326                 OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2327                         LogicalDatastoreType.OPERATIONAL);
2328                 Queues operQueue = getQueue(new Uri(testQueueId), ovsdbNodeAugmentation);
2329                 Assert.assertNotNull(operQueue);
2330                 Short operDscp = operQueue.getDscp();
2331                 Assert.assertNotNull(operDscp);
2332                 Assert.assertEquals(dscp, operDscp);
2333             }
2334
2335             // DELETE handled by TestQueue
2336         }
2337
2338     }
2339
2340     private <T> void testCRUDQos(
2341             KeyValueBuilder<T> builder, String prefix, SouthboundQosHelper<T> helper)
2342             throws InterruptedException {
2343
2344         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2345
2346         // updateFromTestCases represent the original test case value.  updateToTestCases represent the new value after
2347         // the update has been performed.
2348         List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
2349         List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
2350
2351         for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
2352             for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
2353                 String testQosId = String.format("%s_%s", prefix, updateToTestCase.name);
2354
2355                 // CREATE: and update the test qos with starting values.
2356                 try (TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId), SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HTB), null, null)) {
2357                     QosEntriesBuilder qosBuilder = new QosEntriesBuilder();
2358                     qosBuilder.setQosId(new Uri(testQosId));
2359                     InstanceIdentifier<QosEntries> qosIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
2360                             .augmentation(OvsdbNodeAugmentation.class)
2361                             .child(QosEntries.class, qosBuilder.build().getKey());
2362                     final NotifyingDataChangeListener qosConfigurationListener =
2363                             new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION, qosIid);
2364                     qosConfigurationListener.registerDataChangeListener();
2365                     final NotifyingDataChangeListener qosOperationalListener =
2366                             new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qosIid);
2367                     qosOperationalListener.registerDataChangeListener();
2368
2369                     helper.writeValues(qosBuilder, updateFromTestCase.inputValues);
2370                     Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2371                             qosIid, qosBuilder.build()));
2372                     qosConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2373
2374                     // READ: Read the test queue and ensure changes are propagated to the CONFIGURATION data store,
2375                     // then repeat for OPERATIONAL data store
2376                     OvsdbNodeAugmentation updateFromConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2377                             LogicalDatastoreType.CONFIGURATION);
2378                     QosEntries qosFromConfig = getQos(new Uri(testQosId), updateFromConfigurationOvsdbNodeAugmentation);
2379                     if (qosFromConfig != null) {
2380                         List<T> updateFromConfigurationValues =
2381                                 helper.readValues(qosFromConfig);
2382                         assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues);
2383                     }
2384
2385                     qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2386                     OvsdbNodeAugmentation updateFromOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2387                             LogicalDatastoreType.OPERATIONAL);
2388                     QosEntries qosFromOper = getQos(new Uri(testQosId), updateFromOperationalOvsdbNodeAugmentation);
2389                     if (qosFromOper != null) {
2390                         List<T> updateFromOperationalValues =
2391                                 helper.readValues(qosFromOper);
2392                         assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalValues);
2393                     }
2394
2395                     // UPDATE:  update the values
2396                     QosEntriesBuilder qosUpdateBuilder = new QosEntriesBuilder();
2397                     qosUpdateBuilder.setQosId(new Uri(testQosId));
2398                     helper.writeValues(qosUpdateBuilder, updateToTestCase.inputValues);
2399                     Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2400                             qosIid, qosUpdateBuilder.build()));
2401                     qosConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2402
2403                     // READ: the test queue and ensure changes are propagated to the CONFIGURATION data store,
2404                     // then repeat for OPERATIONAL data store
2405                     OvsdbNodeAugmentation updateToConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2406                             LogicalDatastoreType.CONFIGURATION);
2407                     QosEntries qosToConfig = getQos(new Uri(testQosId), updateToConfigurationOvsdbNodeAugmentation);
2408                     if (qosToConfig != null) {
2409                         List<T> updateToConfigurationValues =
2410                                 helper.readValues(qosToConfig);
2411                         assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues);
2412                     }
2413
2414                     qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2415                     OvsdbNodeAugmentation updateToOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2416                             LogicalDatastoreType.OPERATIONAL);
2417                     QosEntries qosToOper = getQos(new Uri(testQosId), updateToOperationalOvsdbNodeAugmentation);
2418                     if (qosToOper != null) {
2419                         List<T> updateToOperationalValues =
2420                                 helper.readValues(qosToOper);
2421                         assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues);
2422                     }
2423
2424                     // DELETE handled by TestQueue
2425                 }
2426             }
2427         }
2428     }
2429
2430     @Test
2431     public void testCRUDQosExternalIds() throws InterruptedException {
2432         testCRUDQos(new SouthboundQosExternalIdsBuilder(), "QosExternalIds",
2433                 new SouthboundQosExternalIdsHelper());
2434     }
2435
2436     @Test
2437     public void testCRUDQosOtherConfig() throws InterruptedException {
2438         testCRUDQos(new SouthboundQosOtherConfigBuilder(), "QosOtherConfig",
2439                 new SouthboundQosOtherConfigHelper());
2440     }
2441     @Test
2442     public void testCRUDQosQueues() throws InterruptedException {
2443         ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
2444         String testQosId = "testQosQueues";
2445
2446         // CREATE: and update the test queue with starting values.
2447         try (TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId),
2448                 SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HTB), null, null);
2449                 TestQueue testQueue1 = new TestQueue(connectionInfo, new Uri("queue1"), new Short("12"), null, null);
2450                 TestQueue testQueue2 = new TestQueue(connectionInfo, new Uri("queue2"), new Short("35"), null, null)) {
2451             QosEntriesBuilder qosBuilder = new QosEntriesBuilder();
2452             qosBuilder.setQosId(new Uri(testQosId));
2453             InstanceIdentifier<QosEntries> qosIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
2454                     .augmentation(OvsdbNodeAugmentation.class)
2455                     .child(QosEntries.class, qosBuilder.build().getKey());
2456             final NotifyingDataChangeListener qosOperationalListener =
2457                     new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qosIid);
2458             qosOperationalListener.registerDataChangeListener();
2459
2460             // READ, UPDATE:  Read the UUIDs of the Queue rows and add them to the
2461             // configuration of the Qos row.
2462             OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2463                     LogicalDatastoreType.OPERATIONAL);
2464             Queues operQueue1 = getQueue(new Uri("queue1"), ovsdbNodeAugmentation);
2465             Assert.assertNotNull(operQueue1);
2466             Uuid queue1Uuid = new Uuid(operQueue1.getQueueUuid().getValue());
2467             Queues operQueue2 = getQueue(new Uri("queue2"), ovsdbNodeAugmentation);
2468             Assert.assertNotNull(operQueue2);
2469             Uuid queue2Uuid = new Uuid(operQueue2.getQueueUuid().getValue());
2470
2471             List<QueueList> queueList = new ArrayList<>();
2472             queueList.add(new QueueListBuilder().setQueueNumber(new Long("0"))
2473                     .setQueueUuid(queue1Uuid).build());
2474             queueList.add(new QueueListBuilder().setQueueNumber(new Long("1"))
2475                     .setQueueUuid(queue2Uuid).build());
2476             qosBuilder.setQueueList(queueList);
2477
2478             Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
2479                     qosIid, qosBuilder.build()));
2480             qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2481
2482             // READ: Read the test qos and ensure changes are propagated to the OPERATIONAL data store
2483             // assumption is that CONFIGURATION was updated if OPERATIONAL is correct
2484             ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2485                     LogicalDatastoreType.OPERATIONAL);
2486             QosEntries operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
2487             Assert.assertNotNull(operQos);
2488             List<QueueList> operQueueList = operQos.getQueueList();
2489             Assert.assertNotNull(operQueueList);
2490             for (QueueList queueEntry : queueList) {
2491                 Assert.assertTrue(isQueueInList(operQueueList, queueEntry));
2492             }
2493
2494             // DELETE one queue from queue list and check that one remains
2495             KeyedInstanceIdentifier<QueueList, QueueListKey> qosQueueIid = qosIid
2496                         .child(QueueList.class, new QueueListKey(new Long("0")));
2497             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qosQueueIid));
2498             qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2499
2500             // READ: Read the test qos and ensure changes are propagated to the OPERATIONAL data store
2501             // assumption is that CONFIGURATION was updated if OPERATIONAL is correct
2502             ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2503                     LogicalDatastoreType.OPERATIONAL);
2504             operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
2505             Assert.assertNotNull(operQos);
2506             operQueueList = operQos.getQueueList();
2507             Assert.assertNotNull(operQueueList);
2508             for (QueueList queueEntry : queueList) {
2509                 if (queueEntry.getQueueUuid().equals(queue2Uuid)) {
2510                     Assert.assertTrue(isQueueInList(operQueueList, queueEntry));
2511                 } else if (queueEntry.getQueueUuid().equals(queue1Uuid)) {
2512                     Assert.assertFalse(isQueueInList(operQueueList, queueEntry));
2513                 } else {
2514                     Assert.assertTrue("Unknown queue entry in qos queue list", false);
2515                 }
2516             }
2517
2518             // DELETE  queue list and check that list is empty
2519             qosQueueIid = qosIid
2520                     .child(QueueList.class, new QueueListKey(new Long("1")));
2521             Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qosQueueIid));
2522             qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
2523
2524             ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
2525                     LogicalDatastoreType.OPERATIONAL);
2526             operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
2527             Assert.assertNotNull(operQos);
2528             operQueueList = operQos.getQueueList();
2529             Assert.assertNotNull(operQueueList);
2530             Assert.assertTrue(operQueueList.isEmpty());
2531         }
2532     }
2533
2534     private Boolean isQueueInList(List<QueueList> queueList, QueueList queue) {
2535         for (QueueList queueEntry : queueList) {
2536             if (queueEntry.getQueueNumber().equals(queue.getQueueNumber())
2537                 && queueEntry.getQueueUuid().equals(queue.getQueueUuid())) {
2538                 return true;
2539             }
2540         }
2541         return false;
2542     }
2543
2544     /**
2545      * <p>
2546      * Representation of a southbound test case. Each test case has a name, a list of input values and a list of
2547      * expected values. The input values are provided to the augmentation builder, and the expected values are checked
2548      * against the output of the resulting augmentation.
2549      * </p>
2550      * <p>
2551      * Instances of this class are immutable.
2552      * </p>
2553      *
2554      * @param <T> The type of data used for the test case.
2555      */
2556     private static final class SouthboundTestCase<T> {
2557         private final String name;
2558         private final List<T> inputValues;
2559         private final List<T> expectedValues;
2560
2561         /**
2562          * Creates an instance of a southbound test case.
2563          *
2564          * @param name The test case's name.
2565          * @param inputValues The input values (provided as input to the underlying augmentation builder).
2566          * @param expectedValues The expected values (checked against the output of the underlying augmentation).
2567          */
2568         public SouthboundTestCase(
2569                 final String name, final List<T> inputValues, final List<T> expectedValues) {
2570             this.name = name;
2571             this.inputValues = inputValues;
2572             this.expectedValues = expectedValues;
2573         }
2574     }
2575
2576     /**
2577      * Southbound test case builder.
2578      *
2579      * @param <T> The type of data used for the test case.
2580      */
2581     private static final class SouthboundTestCaseBuilder<T> {
2582         private String name;
2583         private List<T> inputValues;
2584         private List<T> expectedValues;
2585
2586         /**
2587          * Creates a builder. Builders may be reused, the generated immutable instances are independent of the
2588          * builders. There are no default values.
2589          */
2590         public SouthboundTestCaseBuilder() {
2591             // Nothing to do
2592         }
2593
2594         /**
2595          * Sets the test case's name.
2596          *
2597          * @param name The test case's name.
2598          * @return The builder.
2599          */
2600         public SouthboundTestCaseBuilder<T> name(final String name) {
2601             this.name = name;
2602             return this;
2603         }
2604
2605         /**
2606          * Sets the input values.
2607          *
2608          * @param inputValues The input values.
2609          * @return The builder.
2610          */
2611         @SafeVarargs
2612         public final SouthboundTestCaseBuilder<T> input(final T... inputValues) {
2613             this.inputValues = Lists.newArrayList(inputValues);
2614             return this;
2615         }
2616
2617         /**
2618          * Indicates that the provided input values should be expected as output values.
2619          *
2620          * @return The builder.
2621          */
2622         public SouthboundTestCaseBuilder<T> expectInputAsOutput() {
2623             this.expectedValues = this.inputValues;
2624             return this;
2625         }
2626
2627         /**
2628          * Indicates that no output should be expected.
2629          *
2630          * @return The builder.
2631          */
2632         public SouthboundTestCaseBuilder<T> expectNoOutput() {
2633             this.expectedValues = null;
2634             return this;
2635         }
2636
2637         /**
2638          * Builds an immutable instance representing the test case.
2639          *
2640          * @return The test case.
2641          */
2642         @SuppressWarnings("unchecked")
2643         public SouthboundTestCase<T> build() {
2644             return new SouthboundTestCase<>(name, inputValues, expectedValues);
2645         }
2646     }
2647
2648     private abstract static class KeyValueBuilder<T> {
2649         private static final int COUNTER_START = 0;
2650         private int counter = COUNTER_START;
2651
2652         protected abstract Builder<T> builder();
2653
2654         protected abstract void setKey(Builder<T> builder, String key);
2655
2656         protected abstract void setValue(Builder<T> builder, String value);
2657
2658         protected abstract boolean isValueMandatory();
2659
2660         public final T build(final String testName, final String key, final String value) {
2661             final Builder<T> builder = builder();
2662             this.counter++;
2663             if (key != null) {
2664                 setKey(builder, String.format(FORMAT_STR, testName, key, this.counter));
2665             }
2666             if (value != null) {
2667                 setValue(builder, String.format(FORMAT_STR, testName, value, this.counter));
2668             }
2669             return builder.build();
2670         }
2671
2672         public final void reset() {
2673             this.counter = COUNTER_START;
2674         }
2675     }
2676
2677     private static final class SouthboundQueuesExternalIdsBuilder extends KeyValueBuilder<QueuesExternalIds> {
2678         @Override
2679         protected Builder<QueuesExternalIds> builder() {
2680             return new QueuesExternalIdsBuilder();
2681         }
2682
2683         @Override
2684         protected void setKey(Builder<QueuesExternalIds> builder, String key) {
2685             ((QueuesExternalIdsBuilder) builder).setQueuesExternalIdKey(key);
2686         }
2687
2688         @Override
2689         protected void setValue(Builder<QueuesExternalIds> builder, String value) {
2690             ((QueuesExternalIdsBuilder) builder).setQueuesExternalIdValue(value);
2691         }
2692
2693         @Override
2694         protected boolean isValueMandatory() {
2695             return true;
2696         }
2697     }
2698
2699     private static final class SouthboundQueuesOtherConfigBuilder extends KeyValueBuilder<QueuesOtherConfig> {
2700         @Override
2701         protected Builder<QueuesOtherConfig> builder() {
2702             return new QueuesOtherConfigBuilder();
2703         }
2704
2705         @Override
2706         protected void setKey(Builder<QueuesOtherConfig> builder, String key) {
2707             ((QueuesOtherConfigBuilder) builder).setQueueOtherConfigKey(key);
2708         }
2709
2710         @Override
2711         protected void setValue(Builder<QueuesOtherConfig> builder, String value) {
2712             ((QueuesOtherConfigBuilder) builder).setQueueOtherConfigValue(value);
2713         }
2714
2715         @Override
2716         protected boolean isValueMandatory() {
2717             return false;
2718         }
2719     }
2720
2721     private static final class SouthboundQosExternalIdsBuilder extends KeyValueBuilder<QosExternalIds> {
2722         @Override
2723         protected Builder<QosExternalIds> builder() {
2724             return new QosExternalIdsBuilder();
2725         }
2726
2727         @Override
2728         protected void setKey(Builder<QosExternalIds> builder, String key) {
2729             ((QosExternalIdsBuilder) builder).setQosExternalIdKey(key);
2730         }
2731
2732         @Override
2733         protected void setValue(Builder<QosExternalIds> builder, String value) {
2734             ((QosExternalIdsBuilder) builder).setQosExternalIdValue(value);
2735         }
2736
2737         @Override
2738         protected boolean isValueMandatory() {
2739             return true;
2740         }
2741     }
2742
2743     private static final class SouthboundQosOtherConfigBuilder extends KeyValueBuilder<QosOtherConfig> {
2744         @Override
2745         protected Builder<QosOtherConfig> builder() {
2746             return new QosOtherConfigBuilder();
2747         }
2748
2749         @Override
2750         protected void setKey(Builder<QosOtherConfig> builder, String key) {
2751             ((QosOtherConfigBuilder) builder).setOtherConfigKey(key);
2752         }
2753
2754         @Override
2755         protected void setValue(Builder<QosOtherConfig> builder, String value) {
2756             ((QosOtherConfigBuilder) builder).setOtherConfigValue(value);
2757         }
2758
2759         @Override
2760         protected boolean isValueMandatory() {
2761             return false;
2762         }
2763     }
2764
2765     private static final class SouthboundPortExternalIdsBuilder extends KeyValueBuilder<PortExternalIds> {
2766         @Override
2767         protected Builder<PortExternalIds> builder() {
2768             return new PortExternalIdsBuilder();
2769         }
2770
2771         @Override
2772         protected void setKey(Builder<PortExternalIds> builder, String key) {
2773             ((PortExternalIdsBuilder) builder).setExternalIdKey(key);
2774         }
2775
2776         @Override
2777         protected void setValue(Builder<PortExternalIds> builder, String value) {
2778             ((PortExternalIdsBuilder) builder).setExternalIdValue(value);
2779         }
2780
2781         @Override
2782         protected boolean isValueMandatory() {
2783             return true;
2784         }
2785     }
2786
2787     private static final class SouthboundInterfaceExternalIdsBuilder extends KeyValueBuilder<InterfaceExternalIds> {
2788         @Override
2789         protected Builder<InterfaceExternalIds> builder() {
2790             return new InterfaceExternalIdsBuilder();
2791         }
2792
2793         @Override
2794         protected void setKey(Builder<InterfaceExternalIds> builder, String key) {
2795             ((InterfaceExternalIdsBuilder) builder).setExternalIdKey(key);
2796         }
2797
2798         @Override
2799         protected void setValue(Builder<InterfaceExternalIds> builder, String value) {
2800             ((InterfaceExternalIdsBuilder) builder).setExternalIdValue(value);
2801         }
2802
2803         @Override
2804         protected boolean isValueMandatory() {
2805             return true;
2806         }
2807     }
2808
2809     private static final class SouthboundInterfaceLldpBuilder extends KeyValueBuilder<InterfaceLldp> {
2810         @Override
2811         protected Builder<InterfaceLldp> builder() {
2812             return new InterfaceLldpBuilder();
2813         }
2814
2815         @Override
2816         protected void setKey(Builder<InterfaceLldp> builder, String key) {
2817             ((InterfaceLldpBuilder) builder).setLldpKey((key));
2818         }
2819
2820         @Override
2821         protected void setValue(Builder<InterfaceLldp> builder, String value) {
2822             ((InterfaceLldpBuilder) builder).setLldpValue(value);
2823         }
2824
2825         @Override
2826         protected boolean isValueMandatory() {
2827             return true;
2828         }
2829     }
2830
2831     private static final class SouthboundOptionsBuilder extends KeyValueBuilder<Options> {
2832         @Override
2833         protected Builder<Options> builder() {
2834             return new OptionsBuilder();
2835         }
2836
2837         @Override
2838         protected void setKey(Builder<Options> builder, String key) {
2839             ((OptionsBuilder) builder).setOption(key);
2840         }
2841
2842         @Override
2843         protected void setValue(Builder<Options> builder, String value) {
2844             ((OptionsBuilder) builder).setValue(value);
2845         }
2846
2847         @Override
2848         protected boolean isValueMandatory() {
2849             return false;
2850         }
2851     }
2852
2853     private static final class SouthboundInterfaceOtherConfigsBuilder extends KeyValueBuilder<InterfaceOtherConfigs> {
2854         @Override
2855         protected Builder<InterfaceOtherConfigs> builder() {
2856             return new InterfaceOtherConfigsBuilder();
2857         }
2858
2859         @Override
2860         protected void setKey(Builder<InterfaceOtherConfigs> builder, String key) {
2861             ((InterfaceOtherConfigsBuilder) builder).setOtherConfigKey(key);
2862         }
2863
2864         @Override
2865         protected void setValue(Builder<InterfaceOtherConfigs> builder, String value) {
2866             ((InterfaceOtherConfigsBuilder) builder).setOtherConfigValue(value);
2867         }
2868
2869         @Override
2870         protected boolean isValueMandatory() {
2871             return false;
2872         }
2873     }
2874
2875     private static final class SouthboundPortOtherConfigsBuilder extends KeyValueBuilder<PortOtherConfigs> {
2876         @Override
2877         protected Builder<PortOtherConfigs> builder() {
2878             return new PortOtherConfigsBuilder();
2879         }
2880
2881         @Override
2882         protected void setKey(Builder<PortOtherConfigs> builder, String key) {
2883             ((PortOtherConfigsBuilder) builder).setOtherConfigKey(key);
2884         }
2885
2886         @Override
2887         protected void setValue(Builder<PortOtherConfigs> builder, String value) {
2888             ((PortOtherConfigsBuilder) builder).setOtherConfigValue(value);
2889         }
2890
2891         @Override
2892         protected boolean isValueMandatory() {
2893             return false;
2894         }
2895     }
2896
2897     private static final class SouthboundBridgeOtherConfigsBuilder extends KeyValueBuilder<BridgeOtherConfigs> {
2898         @Override
2899         protected Builder<BridgeOtherConfigs> builder() {
2900             return new BridgeOtherConfigsBuilder();
2901         }
2902
2903         @Override
2904         protected void setKey(Builder<BridgeOtherConfigs> builder, String key) {
2905             ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigKey(key);
2906         }
2907
2908         @Override
2909         protected void setValue(Builder<BridgeOtherConfigs> builder, String value) {
2910             ((BridgeOtherConfigsBuilder) builder).setBridgeOtherConfigValue(value);
2911         }
2912
2913         @Override
2914         protected boolean isValueMandatory() {
2915             return false;
2916         }
2917     }
2918
2919     private static final class SouthboundBridgeExternalIdsBuilder extends KeyValueBuilder<BridgeExternalIds> {
2920         @Override
2921         protected Builder<BridgeExternalIds> builder() {
2922             return new BridgeExternalIdsBuilder();
2923         }
2924
2925         @Override
2926         protected void setKey(Builder<BridgeExternalIds> builder, String key) {
2927             ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdKey(key);
2928         }
2929
2930         @Override
2931         protected void setValue(Builder<BridgeExternalIds> builder, String value) {
2932             ((BridgeExternalIdsBuilder) builder).setBridgeExternalIdValue(value);
2933         }
2934
2935         @Override
2936         protected boolean isValueMandatory() {
2937             return true;
2938         }
2939     }
2940
2941     /*
2942      * Generates the test cases involved in testing key-value-based data.  See inline comments for descriptions of
2943      * the particular cases considered.
2944      */
2945     private static <T> List<SouthboundTestCase<T>> generateKeyValueTestCases(
2946             KeyValueBuilder<T> builder, String testName) {
2947         List<SouthboundTestCase<T>> testCases = new ArrayList<>();
2948
2949         final String GOOD_KEY = "GoodKey";
2950         final String GOOD_VALUE = "GoodValue";
2951         final String NO_VALUE_FOR_KEY = "NoValueForKey";
2952
2953         final String idKey = testName + "Key";
2954         final String idValue = testName + "Value";
2955
2956         // Test Case 1:  TestOne
2957         // Test Type:    Positive
2958         // Description:  Create a termination point with one value
2959         // Expected:     A port is created with the single value specified below
2960         final String testOneName = "TestOne" + testName;
2961         testCases.add(new SouthboundTestCaseBuilder<T>()
2962                 .name(testOneName)
2963                 .input(builder.build(testOneName, idKey, idValue))
2964                 .expectInputAsOutput()
2965                 .build());
2966         builder.reset();
2967
2968         // Test Case 2:  TestFive
2969         // Test Type:    Positive
2970         // Description:  Create a termination point with multiple (five) values
2971         // Expected:     A port is created with the five values specified below
2972         final String testFiveName = "TestFive" + testName;
2973         testCases.add(new SouthboundTestCaseBuilder<T>()
2974                 .name(testFiveName)
2975                 .input(
2976                         builder.build(testFiveName, idKey, idValue),
2977                         builder.build(testFiveName, idKey, idValue),
2978                         builder.build(testFiveName, idKey, idValue),
2979                         builder.build(testFiveName, idKey, idValue),
2980                         builder.build(testFiveName, idKey, idValue))
2981                 .expectInputAsOutput()
2982                 .build());
2983         builder.reset();
2984
2985         if (!builder.isValueMandatory()) {
2986             // Test Case 3:  TestOneGoodOneMalformedValue
2987             // Test Type:    Negative
2988             // Description:
2989             //     One perfectly fine input
2990             //        (TestOneGoodOneMalformedValue_GoodKey_1,
2991             //        TestOneGoodOneMalformedValue_GoodValue_1)
2992             //     and one malformed input which only has key specified
2993             //        (TestOneGoodOneMalformedValue_NoValueForKey_2,
2994             //        UNSPECIFIED)
2995             // Expected:     A port is created without any values
2996             final String testOneGoodOneMalformedValueName = "TestOneGoodOneMalformedValue" + testName;
2997             testCases.add(new SouthboundTestCaseBuilder<T>()
2998                     .name(testOneGoodOneMalformedValueName)
2999                     .input(
3000                             builder.build(testOneGoodOneMalformedValueName, GOOD_KEY, GOOD_VALUE),
3001                             builder.build(testOneGoodOneMalformedValueName, NO_VALUE_FOR_KEY, null))
3002                     .expectNoOutput()
3003                     .build());
3004             builder.reset();
3005         } else {
3006             LOG.info("generateKeyValueTestCases: skipping test case 3 for {}", builder.getClass().getSimpleName());
3007         }
3008
3009         return testCases;
3010     }
3011
3012     private static class PortExternalIdsSouthboundHelper implements SouthboundTerminationPointHelper<PortExternalIds> {
3013         @Override
3014         public void writeValues(OvsdbTerminationPointAugmentationBuilder builder, List<PortExternalIds> values) {
3015             builder.setPortExternalIds(values);
3016         }
3017
3018         @Override
3019         public List<PortExternalIds> readValues(OvsdbTerminationPointAugmentation augmentation) {
3020             return augmentation.getPortExternalIds();
3021         }
3022     }
3023
3024     private static class InterfaceExternalIdsSouthboundHelper implements
3025             SouthboundTerminationPointHelper<InterfaceExternalIds> {
3026         @Override
3027         public void writeValues(
3028                 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceExternalIds> values) {
3029             builder.setInterfaceExternalIds(values);
3030         }
3031
3032         @Override
3033         public List<InterfaceExternalIds> readValues(OvsdbTerminationPointAugmentation augmentation) {
3034             return augmentation.getInterfaceExternalIds();
3035         }
3036     }
3037
3038     private static class InterfaceLldpSouthboundHelper implements
3039     SouthboundTerminationPointHelper<InterfaceLldp> {
3040         @Override
3041         public void writeValues(
3042                 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceLldp> values) {
3043             builder.setInterfaceLldp(values);
3044         }
3045
3046         @Override
3047         public List<InterfaceLldp> readValues(OvsdbTerminationPointAugmentation augmentation) {
3048             return augmentation.getInterfaceLldp();
3049         }
3050     }
3051
3052     private static class OptionsSouthboundHelper implements SouthboundTerminationPointHelper<Options> {
3053         @Override
3054         public void writeValues(
3055                 OvsdbTerminationPointAugmentationBuilder builder, List<Options> values) {
3056             builder.setOptions(values);
3057         }
3058
3059         @Override
3060         public List<Options> readValues(OvsdbTerminationPointAugmentation augmentation) {
3061             return augmentation.getOptions();
3062         }
3063     }
3064
3065     private static class InterfaceOtherConfigsSouthboundHelper implements
3066             SouthboundTerminationPointHelper<InterfaceOtherConfigs> {
3067         @Override
3068         public void writeValues(
3069                 OvsdbTerminationPointAugmentationBuilder builder, List<InterfaceOtherConfigs> values) {
3070             builder.setInterfaceOtherConfigs(values);
3071         }
3072
3073         @Override
3074         public List<InterfaceOtherConfigs> readValues(OvsdbTerminationPointAugmentation augmentation) {
3075             return augmentation.getInterfaceOtherConfigs();
3076         }
3077     }
3078
3079     private static class PortOtherConfigsSouthboundHelper implements
3080             SouthboundTerminationPointHelper<PortOtherConfigs> {
3081         @Override
3082         public void writeValues(
3083                 OvsdbTerminationPointAugmentationBuilder builder, List<PortOtherConfigs> values) {
3084             builder.setPortOtherConfigs(values);
3085         }
3086
3087         @Override
3088         public List<PortOtherConfigs> readValues(OvsdbTerminationPointAugmentation augmentation) {
3089             return augmentation.getPortOtherConfigs();
3090         }
3091     }
3092
3093     private static class BridgeExternalIdsSouthboundHelper implements SouthboundBridgeHelper<BridgeExternalIds> {
3094         @Override
3095         public void writeValues(
3096                 OvsdbBridgeAugmentationBuilder builder, List<BridgeExternalIds> values) {
3097             builder.setBridgeExternalIds(values);
3098         }
3099
3100         @Override
3101         public List<BridgeExternalIds> readValues(OvsdbBridgeAugmentation augmentation) {
3102             return augmentation.getBridgeExternalIds();
3103         }
3104     }
3105
3106     private static class BridgeOtherConfigsSouthboundHelper implements SouthboundBridgeHelper<BridgeOtherConfigs> {
3107         @Override
3108         public void writeValues(
3109                 OvsdbBridgeAugmentationBuilder builder, List<BridgeOtherConfigs> values) {
3110             builder.setBridgeOtherConfigs(values);
3111         }
3112
3113         @Override
3114         public List<BridgeOtherConfigs> readValues(OvsdbBridgeAugmentation augmentation) {
3115             return augmentation.getBridgeOtherConfigs();
3116         }
3117     }
3118 }