package org.opendaylight.vtn.manager.internal.inventory.xml;
import java.util.ArrayList;
-import java.util.HashMap;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
+import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A list of static inter-switch links.
*/
- private Map<String, XmlStaticSwitchLink> switchLinks;
+ @XmlElement(name = "static-switch-link")
+ private List<XmlStaticSwitchLink> switchLinks;
/**
* Construct an empty instance.
* this instance.
*
* <p>
- * This method is provided only for JAXB.
+ * This method is provided only for testing.
* </p>
*
* @return A list of {@link XmlStaticSwitchLink} instances or
* {@code null}.
*/
- @XmlElement(name = "static-switch-link")
- public List<XmlStaticSwitchLink> getXmlStaticSwitchLink() {
+ List<XmlStaticSwitchLink> getXmlStaticSwitchLink() {
return (switchLinks == null)
- ? null : new ArrayList<XmlStaticSwitchLink>(switchLinks.values());
- }
-
- /**
- * Set a list of {@link XmlStaticSwitchLink} instances to this instance.
- *
- * <p>
- * This method is provided only for JAXB.
- * </p>
- *
- * @param xlinks A list of {@link XmlStaticSwitchLink} instance.
- */
- public void setXmlStaticSwitchLink(List<XmlStaticSwitchLink> xlinks) {
- if (xlinks == null) {
- switchLinks = null;
- return;
- }
-
- Map<String, XmlStaticSwitchLink> map = new HashMap<>();
- for (XmlStaticSwitchLink xlink: xlinks) {
- if (xlink.isValid()) {
- XmlStaticSwitchLink old = map.put(xlink.getSource(), xlink);
- if (old != null) {
- LOG.warn("Ignore duplicate static link specified by XML" +
- ": {}", old);
- }
- } else {
- LOG.warn("Ignore invalid static link specified by XML: {}",
- xlink);
- }
- }
-
- if (!map.isEmpty()) {
- switchLinks = map;
- }
+ ? null
+ : Collections.unmodifiableList(switchLinks);
}
/**
* list of {@link XmlStaticSwitchLink} instances.
*
* @param swlinks A {@link StaticSwitchLinks} instance.
- * @return A map which keeps {@link XmlStaticSwitchLink} instances or
- * {@code null}.
+ * @return A list of {@link XmlStaticSwitchLink} instances or {@code null}.
*/
- private Map<String, XmlStaticSwitchLink> toXmlStaticSwitchLink(
+ private List<XmlStaticSwitchLink> toXmlStaticSwitchLink(
StaticSwitchLinks swlinks) {
if (swlinks == null) {
return null;
List<StaticSwitchLink> links = swlinks.getStaticSwitchLink();
if (links != null) {
- Map<String, XmlStaticSwitchLink> xlinks = new HashMap<>();
+ List<XmlStaticSwitchLink> xlinks = new ArrayList<>(links.size());
+ Set<String> srcSet = new HashSet<>();
for (StaticSwitchLink link: links) {
XmlStaticSwitchLink xlink;
try {
}
String src = xlink.getSource();
- XmlStaticSwitchLink old = xlinks.put(src, xlink);
- if (old != null) {
- LOG.warn("Ignore duplicate static link: ", old);
+ if (srcSet.add(src)) {
+ xlinks.add(xlink);
+ } else {
+ LOG.warn("Ignore duplicate static link: ", xlink);
}
}
* @return A list of {@link StaticSwitchLink} instances or {@code null}.
*/
private List<StaticSwitchLink> getStaticSwitchLinks() {
- if (switchLinks != null) {
- List<StaticSwitchLink> links = new ArrayList<>();
- for (XmlStaticSwitchLink xlink: switchLinks.values()) {
- try {
- links.add(xlink.toStaticSwitchLink());
- } catch (RuntimeException e) {
- // This should never happen because static links are
- // already verified by setXmlStaticSwitchLink().
- LOG.warn("Ignore invalid static link specified by XML: " +
- xlink, e);
+ List<StaticSwitchLink> links;
+ if (switchLinks == null) {
+ links = null;
+ } else {
+ links = new ArrayList<>();
+ Set<String> srcSet = new HashSet<>();
+ for (XmlStaticSwitchLink xlink: switchLinks) {
+ if (xlink.isValid()) {
+ String src = xlink.getSource();
+ if (srcSet.add(src)) {
+ links.add(xlink.toStaticSwitchLink());
+ } else {
+ LOG.warn("Ignore duplicate static link specified " +
+ "by XML: {}", xlink);
+ }
+ } else {
+ LOG.warn("Ignore invalid static link specified by XML: {}",
+ xlink);
}
}
- if (!links.isEmpty()) {
- return links;
+ if (links.isEmpty()) {
+ links = null;
}
}
- return null;
+ return links;
}
// XmlStaticTopologyConfig
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
-import static org.opendaylight.vtn.manager.internal.inventory.xml.XmlStaticSwitchLinkTest.newXmlStaticSwitchLink;
-
import java.io.File;
import java.util.ArrayList;
import java.util.HashSet;
goodLinks.add(swlink);
links.add(swlink);
- // The source port will be overriden.
String src = "openflow:99:1";
swlink = newStaticSwitchLink(src, "openflow:10:11");
+ goodLinks.add(swlink);
links.add(swlink);
swlink = newStaticSwitchLink("unknown:1:2", "openflow:1:99");
badLinks.add(swlink);
links.add(swlink);
- // Override the source port "openflow:99:1".
+ // Duplicate source port "openflow:99:1".
swlink = newStaticSwitchLink(src, "openflow:888:999");
- goodLinks.add(swlink);
links.add(swlink);
swlinks = new StaticSwitchLinksBuilder().
assertTrue(goodLinks.isEmpty());
}
- /**
- * Test case for {@link XmlStaticSwitchLinks#getXmlStaticSwitchLink()} and
- * {@link XmlStaticSwitchLinks#setXmlStaticSwitchLink(List)}.
- *
- * @throws Exception An error occurred.
- */
- @Test
- public void testXmlStaticSwitchLink() throws Exception {
- StaticSwitchLinks swlinks = new StaticSwitchLinksBuilder().build();
- XmlStaticSwitchLinks xswlinks = new XmlStaticSwitchLinks(swlinks);
- assertEquals(null, xswlinks.getXmlStaticSwitchLink());
-
- for (List<StaticSwitchLink> links: createStaticSwitchLinks(false)) {
- Set<XmlStaticSwitchLink> xlset = new HashSet<>();
- for (StaticSwitchLink swlink: links) {
- xlset.add(new XmlStaticSwitchLink(swlink));
- }
-
- List<XmlStaticSwitchLink> xlinks = new ArrayList<>(xlset);
- xswlinks.setXmlStaticSwitchLink(xlinks);
- xlinks = xswlinks.getXmlStaticSwitchLink();
- if (xlset.isEmpty()) {
- assertEquals(null, xlinks);
- } else {
- for (XmlStaticSwitchLink xlink: xlinks) {
- assertEquals(true, xlset.remove(xlink));
- }
- assertTrue(xlset.isEmpty());
- }
- }
-
- xswlinks.setXmlStaticSwitchLink(null);
- assertEquals(null, xswlinks.getXmlStaticSwitchLink());
- xswlinks.setXmlStaticSwitchLink(new ArrayList<XmlStaticSwitchLink>());
- assertEquals(null, xswlinks.getXmlStaticSwitchLink());
-
- // Ensure that invalid static links are eliminated.
- List<XmlStaticSwitchLink> xlinks = new ArrayList<>();
- List<XmlStaticSwitchLink> badLinks = new ArrayList<>();
- Set<XmlStaticSwitchLink> goodLinks = new HashSet<>();
- XmlStaticSwitchLink xlink =
- newXmlStaticSwitchLink("openflow:1:2", "openflow:2:2");
- goodLinks.add(xlink);
- xlinks.add(xlink);
-
- // Empty link.
- xlink = newXmlStaticSwitchLink(null, null);
- badLinks.add(xlink);
- xlinks.add(xlink);
-
- xlink = newXmlStaticSwitchLink("openflow:1:3", "openflow:2:1");
- goodLinks.add(xlink);
- xlinks.add(xlink);
-
- // Source port is null.
- xlink = newXmlStaticSwitchLink(null, "openflow:2:10");
- badLinks.add(xlink);
- xlinks.add(xlink);
-
- // Source port is empty.
- xlink = newXmlStaticSwitchLink("", "openflow:2:10");
- badLinks.add(xlink);
- xlinks.add(xlink);
-
- xlink = newXmlStaticSwitchLink("proto:1:3", "proto:2:1");
- goodLinks.add(xlink);
- xlinks.add(xlink);
-
- // Destination port is null.
- xlink = newXmlStaticSwitchLink("proto:1:3", null);
- badLinks.add(xlink);
- xlinks.add(xlink);
-
- // Source port is empty.
- xlink = newXmlStaticSwitchLink("proto:1:3", "");
- badLinks.add(xlink);
- xlinks.add(xlink);
-
- xlink = newXmlStaticSwitchLink("openflow:10:10", "openflow:20:20");
- goodLinks.add(xlink);
- xlinks.add(xlink);
-
- // The source port will be overridden.
- String src = "openflow:100:1";
- xlink = newXmlStaticSwitchLink(src, "openflow:100:200");
- xlinks.add(xlink);
-
- xlink = newXmlStaticSwitchLink("openflow:10:11", "openflow:20:21");
- goodLinks.add(xlink);
- xlinks.add(xlink);
-
- // The destination port is the same as the source.
- String[] ports = {
- "openflow:1:2", "openflow:1:3", src, "openflow:123:456",
- };
- for (String port: ports) {
- xlink = newXmlStaticSwitchLink(port, port);
- badLinks.add(xlink);
- xlinks.add(xlink);
- }
-
- // Override the source port "openflow:100:1".
- for (String port: ports) {
- xlink = newXmlStaticSwitchLink(src, port);
- xlinks.add(xlink);
- }
-
- xlink = newXmlStaticSwitchLink(src, "openflow:12345:678");
- goodLinks.add(xlink);
- xlinks.add(xlink);
-
- xlink = newXmlStaticSwitchLink("unknown:1", "unknown:2");
- goodLinks.add(xlink);
- xlinks.add(xlink);
-
- xswlinks.setXmlStaticSwitchLink(badLinks);
- assertEquals(null, xswlinks.getXmlStaticSwitchLink());
- xswlinks.setXmlStaticSwitchLink(xlinks);
- for (XmlStaticSwitchLink xl: xswlinks.getXmlStaticSwitchLink()) {
- assertEquals(true, goodLinks.remove(xl));
- }
- assertTrue(goodLinks.isEmpty());
- }
-
/**
* Test case for {@link XmlStaticSwitchLinks#equals(Object)} and
* {@link XmlStaticSwitchLinks#hashCode()}.
goodLinks.add(newStaticSwitchLink(src, dst));
xlinks.add(xlink);
- // The source port will be overridden.
String dupSrc = "openflow:123:456";
- xlink = createXmlLink(dupSrc, "openflow:111:222");
+ dst = "openflow:111:222";
+ xlink = createXmlLink(dupSrc, dst);
+ goodLinks.add(newStaticSwitchLink(dupSrc, dst));
xlinks.add(xlink);
src = "unknown:1:3";
badLinks.add(xlink);
xlinks.add(xlink);
- // Override the source port "openflow:123:456".
+ // Duplicate source port "openflow:123:456" will be ignored.
xlink = createXmlLink(dupSrc, port);
xlinks.add(xlink);
}
- dst = "openflow:555:678";
- xlink = createXmlLink(dupSrc, dst);
- goodLinks.add(newStaticSwitchLink(dupSrc, dst));
+ // Duplicate source port "openflow:123:456" will be ignored.
+ xlink = createXmlLink(dupSrc, "openflow:555:678");
xlinks.add(xlink);
for (int i = 1; i <= 5; i++) {