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