Added XML bindings for path map and path policy configuration. 68/26768/1
authorShigeru Yasuda <s-yasuda@da.jp.nec.com>
Thu, 10 Sep 2015 13:03:42 +0000 (22:03 +0900)
committerShigeru Yasuda <s-yasuda@da.jp.nec.com>
Thu, 10 Sep 2015 13:03:42 +0000 (22:03 +0900)
Path map and path policy configuration were converted into XML string
by AD-SAL interface classes (PathMap, PathPolicy). But those classes
will be removed in Beryllium release.

Other changes:

  * Added unit tests for XML adapters.

Change-Id: I4c2b819a5ed0d92fc2e112b9e9f23bffcf6e17fa
Signed-off-by: Shigeru Yasuda <s-yasuda@da.jp.nec.com>
37 files changed:
common/pom.xml
manager/api/pom.xml
manager/api/src/main/java/org/opendaylight/vtn/manager/util/xml/adapters/VnodeNameAdapter.java [new file with mode: 0644]
manager/api/src/main/java/org/opendaylight/vtn/manager/util/xml/adapters/VtnPortDescAdapter.java [new file with mode: 0644]
manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/ByteAdapterTest.java [new file with mode: 0644]
manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/DoubleAdapterTest.java [new file with mode: 0644]
manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/IntegerAdapterTest.java [new file with mode: 0644]
manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/LongAdapterTest.java [new file with mode: 0644]
manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/ShortAdapterTest.java [new file with mode: 0644]
manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/VnodeNameAdapterTest.java [new file with mode: 0644]
manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/VtnPortDescAdapterTest.java [new file with mode: 0644]
manager/common/pom.xml
manager/common/yang/pom.xml
manager/features/src/main/resources/features.xml
manager/implementation/pom.xml
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/GlobalPathMapChange.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/PathMapManager.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/PathPolicyChange.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/PathPolicyListener.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/PathPolicyTransformer.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathCost.java [new file with mode: 0644]
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathMap.java [new file with mode: 0644]
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathPolicy.java [new file with mode: 0644]
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/xml/package-info.java [new file with mode: 0644]
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/util/flow/FlowUtils.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/util/pathpolicy/PathPolicyUtils.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/vnode/VTenantLoadTask.java
manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/vnode/xml/XmlVTenant.java
manager/implementation/src/test/java/org/opendaylight/vtn/manager/internal/TestBase.java
manager/implementation/src/test/java/org/opendaylight/vtn/manager/internal/XmlDataType.java
manager/implementation/src/test/java/org/opendaylight/vtn/manager/internal/routing/PathPolicyChangeTest.java
manager/implementation/src/test/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathCostTest.java [new file with mode: 0644]
manager/implementation/src/test/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathMapTest.java [new file with mode: 0644]
manager/implementation/src/test/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathPolicyTest.java [new file with mode: 0644]
manager/it/common/pom.xml
manager/it/ofmock/pom.xml
manager/model/pom.xml

index 4f71467752e256cf2e964198978356fbfe77ee59..1a434a8c919a7bf4fe65aec63a4a4017415e79e5 100644 (file)
     <vtn.manager.version>0.4.0-SNAPSHOT</vtn.manager.version>
   </properties>
 
-  <dependencyManagement>
-    <dependencies>
-      <dependency>
-        <groupId>org.opendaylight.mdsal</groupId>
-        <artifactId>mdsal-artifacts</artifactId>
-        <version>2.0.0-SNAPSHOT</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-      <dependency>
-        <groupId>org.opendaylight.mdsal.model</groupId>
-        <artifactId>mdsal-model-artifacts</artifactId>
-        <version>0.8.0-SNAPSHOT</version>
-        <type>pom</type>
-        <scope>import</scope>
-      </dependency>
-    </dependencies>
-  </dependencyManagement>
-
   <distributionManagement>
     <!-- OpenDayLight Released artifact -->
     <repository>
index 73fe6776a237808d81855cebaacd2a0d31bad0ea..5c3b082cc0b57517d3bd5b101d6a4eee912d6a4a 100644 (file)
@@ -93,7 +93,7 @@
       <artifactId>manager.model</artifactId>
     </dependency>
 
-    <!-- OpenDaylight YANG Tools -->
+    <!-- OpenDaylight MD-SAL -->
     <dependency>
       <groupId>org.opendaylight.mdsal.model</groupId>
       <artifactId>ietf-yang-types</artifactId>
diff --git a/manager/api/src/main/java/org/opendaylight/vtn/manager/util/xml/adapters/VnodeNameAdapter.java b/manager/api/src/main/java/org/opendaylight/vtn/manager/util/xml/adapters/VnodeNameAdapter.java
new file mode 100644 (file)
index 0000000..72cca4e
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015 NEC Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vtn.manager.util.xml.adapters;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VnodeName;
+
+/**
+ * {@code VnodeNameAdapter} establishes XML data binding between
+ * {@link VnodeName} type and {@code String}.
+ *
+ * @since  Beryllium
+ */
+public final class VnodeNameAdapter extends XmlAdapter<String, VnodeName> {
+    /**
+     * Convert the given {@link VnodeName} instance into a string.
+     *
+     * @param v  A {@link VnodeName} instance to be converted.
+     * @return   A string if {@code v} is not {@code null}.
+     *           {@code null} if {@code v} is {@code null}.
+     */
+    @Override
+    public String marshal(VnodeName v) {
+        return (v == null) ? null : v.getValue();
+    }
+
+    /**
+     * Convert the given string into a {@link VnodeName} instance.
+     *
+     * @param v  A string to be converted.
+     * @return   A {@link VnodeName} instance if {@code v} is not {@code null}.
+     *           {@code null} if {@code v} is {@code null}.
+     */
+    @Override
+    public VnodeName unmarshal(String v) {
+        return (v == null) ? null : new VnodeName(v);
+    }
+}
diff --git a/manager/api/src/main/java/org/opendaylight/vtn/manager/util/xml/adapters/VtnPortDescAdapter.java b/manager/api/src/main/java/org/opendaylight/vtn/manager/util/xml/adapters/VtnPortDescAdapter.java
new file mode 100644 (file)
index 0000000..191c60a
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2015 NEC Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vtn.manager.util.xml.adapters;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VtnPortDesc;
+
+/**
+ * {@code VtnPortDescAdapter} establishes XML data binding between
+ * {@link VtnPortDesc} type and {@code String}.
+ *
+ * @since  Beryllium
+ */
+public final class VtnPortDescAdapter extends XmlAdapter<String, VtnPortDesc> {
+    /**
+     * Convert the given {@link VtnPortDesc} instance into a string.
+     *
+     * @param v  A {@link VtnPortDesc} instance to be converted.
+     * @return   A string if {@code v} is not {@code null}.
+     *           {@code null} if {@code v} is {@code null}.
+     */
+    @Override
+    public String marshal(VtnPortDesc v) {
+        return (v == null) ? null : v.getValue();
+    }
+
+    /**
+     * Convert the given string into a {@link VtnPortDesc} instance.
+     *
+     * @param v  A string to be converted.
+     * @return   A {@link VtnPortDesc} instance if {@code v} is not
+     *           {@code null}. {@code null} if {@code v} is {@code null}.
+     */
+    @Override
+    public VtnPortDesc unmarshal(String v) {
+        return (v == null) ? null : new VtnPortDesc(v);
+    }
+}
diff --git a/manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/ByteAdapterTest.java b/manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/ByteAdapterTest.java
new file mode 100644 (file)
index 0000000..ef8b2ea
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2015 NEC Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vtn.manager.util.xml.adapters;
+
+import org.junit.Test;
+
+import org.opendaylight.vtn.manager.TestBase;
+
+/**
+ * JUnit test for {@link ByteAdapter}.
+ */
+public class ByteAdapterTest extends TestBase {
+    /**
+     * Test case for {@link ByteAdapter#marshal(Byte)}.
+     */
+    @Test
+    public void testMarshal() {
+        ByteAdapter adapter = new ByteAdapter();
+        assertEquals(null, adapter.marshal((Byte)null));
+
+        byte v = Byte.MIN_VALUE;
+        do {
+            assertEquals(Byte.toString(v), adapter.marshal(v));
+            v++;
+        } while (v != Byte.MIN_VALUE);
+    }
+
+    /**
+     * Test case for {@link ByteAdapter#unmarshal(String)}.
+     */
+    @Test
+    public void testUnmarshal() {
+        ByteAdapter adapter = new ByteAdapter();
+        assertEquals(null, adapter.unmarshal((String)null));
+
+        byte v = Byte.MIN_VALUE;
+        do {
+            Byte value = Byte.valueOf(v);
+
+            // Decimal
+            String dec = value.toString();
+            assertEquals(value, adapter.unmarshal(dec));
+
+            String hex;
+            String oct;
+            if (v < 0) {
+                int i = (int)v * -1;
+                hex = String.format("-0x%x", i);
+                oct = String.format("-0%o", i);
+            } else {
+                hex = String.format("0x%x", v);
+                oct = String.format("0%o", v);
+            }
+
+            // Hexadecimal
+            assertEquals(value, adapter.unmarshal(hex));
+
+            // Octal
+            assertEquals(value, adapter.unmarshal(oct));
+
+            v++;
+        } while (v != Byte.MIN_VALUE);
+
+        String[] invalid = {
+            // Invalid format.
+            "",
+            "a",
+            "bad string",
+            "123x45",
+
+            // value out of range
+            "128",
+            "129",
+            "99999999",
+            "-129",
+            "-130",
+            "-12345",
+            "10000000000000000000000000",
+            "-10000000000000000000000000",
+        };
+
+        for (String str: invalid) {
+            try {
+                adapter.unmarshal(str);
+                unexpected();
+            } catch (NumberFormatException e) {
+            }
+        }
+    }
+}
diff --git a/manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/DoubleAdapterTest.java b/manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/DoubleAdapterTest.java
new file mode 100644 (file)
index 0000000..bb4e5bf
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2015 NEC Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vtn.manager.util.xml.adapters;
+
+import org.junit.Test;
+
+import org.opendaylight.vtn.manager.TestBase;
+
+/**
+ * JUnit test for {@link DoubleAdapter}.
+ */
+public class DoubleAdapterTest extends TestBase {
+    /**
+     * Test case for {@link DoubleAdapter#marshal(Double)}.
+     */
+    @Test
+    public void testMarshal() {
+        DoubleAdapter adapter = new DoubleAdapter();
+        assertEquals(null, adapter.marshal((Double)null));
+
+        Double[] values = {
+            Double.MIN_VALUE,
+            Double.MIN_VALUE + 0.1d,
+            -999999999999.8765432d,
+            -1234567890.12345d,
+            -33333.4444d,
+            -999d,
+            -2d,
+            -1d,
+            -0.1d,
+            0d,
+            0.1d,
+            1d,
+            2d,
+            3.141592d,
+            555d,
+            6789012.3456d,
+            5555555555.6666666d,
+            Double.MAX_VALUE + 0.1,
+            Double.MAX_VALUE,
+        };
+
+        for (Double value: values) {
+            assertEquals(value.toString(), adapter.marshal(value));
+        }
+    }
+
+    /**
+     * Test case for {@link DoubleAdapter#unmarshal(String)}.
+     */
+    @Test
+    public void testUnmarshal() {
+        DoubleAdapter adapter = new DoubleAdapter();
+        assertEquals(null, adapter.unmarshal((String)null));
+
+        Double[] values = {
+            Double.MIN_VALUE,
+            Double.MIN_VALUE + 0.1d,
+            -999999999999.8765432d,
+            -1234567890.12345d,
+            -33333.4444d,
+            -999d,
+            -2d,
+            -1d,
+            -0.1d,
+            0d,
+            0.1d,
+            1d,
+            2d,
+            3.141592d,
+            555d,
+            6789012.3456d,
+            5555555555.6666666d,
+            Double.MAX_VALUE + 0.1,
+            Double.MAX_VALUE,
+        };
+
+        for (Double value: values) {
+            String dec = value.toString();
+            assertEquals(value, adapter.unmarshal(dec));
+        }
+
+        String[] invalid = {
+            "",
+            "a",
+            "bad string",
+            "123x45",
+            "0xffff",
+            "-0x12345",
+        };
+
+        for (String str: invalid) {
+            try {
+                adapter.unmarshal(str);
+                unexpected();
+            } catch (NumberFormatException e) {
+            }
+        }
+    }
+}
diff --git a/manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/IntegerAdapterTest.java b/manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/IntegerAdapterTest.java
new file mode 100644 (file)
index 0000000..3d2d5d0
--- /dev/null
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2015 NEC Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vtn.manager.util.xml.adapters;
+
+import org.junit.Test;
+
+import org.opendaylight.vtn.manager.TestBase;
+
+/**
+ * JUnit test for {@link IntegerAdapter}.
+ */
+public class IntegerAdapterTest extends TestBase {
+    /**
+     * Test case for {@link IntegerAdapter#marshal(Integer)}.
+     */
+    @Test
+    public void testMarshal() {
+        IntegerAdapter adapter = new IntegerAdapter();
+        assertEquals(null, adapter.marshal((Integer)null));
+
+        Integer[] values = {
+            Integer.MIN_VALUE,
+            Integer.MIN_VALUE + 1,
+            -12345678,
+            -999999,
+            -8888,
+            -777,
+            -66,
+            -10,
+            -3,
+            -2,
+            -1,
+            0,
+            1,
+            2,
+            3,
+            11,
+            222,
+            3333,
+            44444,
+            555555,
+            6666666,
+            Integer.MAX_VALUE - 1,
+            Integer.MAX_VALUE,
+        };
+
+        for (Integer value: values) {
+            assertEquals(value.toString(), adapter.marshal(value));
+        }
+    }
+
+    /**
+     * Test case for {@link IntegerAdapter#unmarshal(String)}.
+     */
+    @Test
+    public void testUnmarshal() {
+        IntegerAdapter adapter = new IntegerAdapter();
+        assertEquals(null, adapter.unmarshal((String)null));
+
+        Integer[] values = {
+            Integer.MIN_VALUE,
+            Integer.MIN_VALUE + 1,
+            -12345678,
+            -999999,
+            -8888,
+            -777,
+            -66,
+            -10,
+            -3,
+            -2,
+            -1,
+            0,
+            1,
+            2,
+            3,
+            11,
+            222,
+            3333,
+            44444,
+            555555,
+            6666666,
+            Integer.MAX_VALUE - 1,
+            Integer.MAX_VALUE,
+        };
+
+        for (Integer value: values) {
+            int v = value.intValue();
+
+            // Decimal
+            String dec = value.toString();
+            assertEquals(value, adapter.unmarshal(dec));
+
+            String hex;
+            String oct;
+            if (v < 0) {
+                long l = (long)v * -1;
+                hex = String.format("-0x%x", l);
+                oct = String.format("-0%o", l);
+            } else {
+                hex = String.format("0x%x", v);
+                oct = String.format("0%o", v);
+            }
+
+            // Hexadecimal
+            assertEquals(value, adapter.unmarshal(hex));
+
+            // Octal
+            assertEquals(value, adapter.unmarshal(oct));
+        }
+
+        String[] invalid = {
+            // Invalid format.
+            "",
+            "a",
+            "bad string",
+            "123x45",
+
+            // value out of range
+            "2147483648",
+            "2147483649",
+            "12345678901",
+            "-2147483649",
+            "-2147483650",
+            "-3333333333",
+            "10000000000000000000000000",
+            "-10000000000000000000000000",
+        };
+
+        for (String str: invalid) {
+            try {
+                adapter.unmarshal(str);
+                unexpected();
+            } catch (NumberFormatException e) {
+            }
+        }
+    }
+}
diff --git a/manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/LongAdapterTest.java b/manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/LongAdapterTest.java
new file mode 100644 (file)
index 0000000..7f2dab1
--- /dev/null
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2015 NEC Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vtn.manager.util.xml.adapters;
+
+import org.junit.Test;
+
+import org.opendaylight.vtn.manager.TestBase;
+
+/**
+ * JUnit test for {@link LongAdapter}.
+ */
+public class LongAdapterTest extends TestBase {
+    /**
+     * Test case for {@link LongAdapter#marshal(Long)}.
+     */
+    @Test
+    public void testMarshal() {
+        LongAdapter adapter = new LongAdapter();
+        assertEquals(null, adapter.marshal((Long)null));
+
+        Long[] values = {
+            Long.MIN_VALUE,
+            Long.MIN_VALUE + 1,
+            -123456789012L,
+            -999999999999L,
+            -88888888888L,
+            -7777777777L,
+            -666666666L,
+            -5555555L,
+            -444444L,
+            -33333L,
+            -2222L,
+            -100L,
+            -3L,
+            -2L,
+            -1L,
+            0L,
+            1L,
+            2L,
+            3L,
+            111L,
+            2345L,
+            34567L,
+            456789L,
+            5678901L,
+            67890123L,
+            789012345L,
+            8901234567L,
+            90123456789L,
+            Long.MAX_VALUE - 1,
+            Long.MAX_VALUE,
+        };
+
+        for (Long value: values) {
+            assertEquals(value.toString(), adapter.marshal(value));
+        }
+    }
+
+    /**
+     * Test case for {@link LongAdapter#unmarshal(String)}.
+     */
+    @Test
+    public void testUnmarshal() {
+        LongAdapter adapter = new LongAdapter();
+        assertEquals(null, adapter.unmarshal((String)null));
+
+        Long[] values = {
+            Long.MIN_VALUE,
+            Long.MIN_VALUE + 1,
+            -123456789012L,
+            -999999999999L,
+            -88888888888L,
+            -7777777777L,
+            -666666666L,
+            -5555555L,
+            -444444L,
+            -33333L,
+            -2222L,
+            -100L,
+            -3L,
+            -2L,
+            -1L,
+            0L,
+            1L,
+            2L,
+            3L,
+            111L,
+            2345L,
+            34567L,
+            456789L,
+            5678901L,
+            67890123L,
+            789012345L,
+            8901234567L,
+            90123456789L,
+            Long.MAX_VALUE - 1,
+            Long.MAX_VALUE,
+        };
+
+        for (Long value: values) {
+            long v = value.longValue();
+
+            // Decimal
+            String dec = value.toString();
+            assertEquals(value, adapter.unmarshal(dec));
+
+            String hex;
+            String oct;
+            if (v < 0) {
+                long l = v * -1;
+                hex = String.format("-0x%x", l);
+                oct = String.format("-0%o", l);
+            } else {
+                hex = String.format("0x%x", v);
+                oct = String.format("0%o", v);
+            }
+
+            // Hexadecimal
+            assertEquals(value, adapter.unmarshal(hex));
+
+            // Octal
+            assertEquals(value, adapter.unmarshal(oct));
+        }
+
+        String[] invalid = {
+            // Invalid format.
+            "",
+            "a",
+            "bad string",
+            "123x45",
+
+            // value out of range
+            "9223372036854775808",
+            "9223372036854775809",
+            "12345678901234567890",
+            "-9223372036854775809",
+            "-9223372036854775810",
+            "-9999999999999999999",
+            "10000000000000000000000000",
+            "-10000000000000000000000000",
+        };
+
+        for (String str: invalid) {
+            try {
+                adapter.unmarshal(str);
+                unexpected();
+            } catch (NumberFormatException e) {
+            }
+        }
+    }
+}
diff --git a/manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/ShortAdapterTest.java b/manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/ShortAdapterTest.java
new file mode 100644 (file)
index 0000000..1b75f71
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2015 NEC Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vtn.manager.util.xml.adapters;
+
+import org.junit.Test;
+
+import org.opendaylight.vtn.manager.TestBase;
+
+/**
+ * JUnit test for {@link ShortAdapter}.
+ */
+public class ShortAdapterTest extends TestBase {
+    /**
+     * Test case for {@link ShortAdapter#marshal(Short)}.
+     */
+    @Test
+    public void testMarshal() {
+        ShortAdapter adapter = new ShortAdapter();
+        assertEquals(null, adapter.marshal((Short)null));
+
+        Short[] values = {
+            Short.MIN_VALUE,
+            Short.MIN_VALUE + 1,
+            -12345,
+            -100,
+            -3,
+            -2,
+            -1,
+            0,
+            1,
+            2,
+            3,
+            99,
+            333,
+            12345,
+            23456,
+            Short.MAX_VALUE - 1,
+            Short.MAX_VALUE,
+        };
+
+        for (Short value: values) {
+            assertEquals(value.toString(), adapter.marshal(value));
+        }
+    }
+
+    /**
+     * Test case for {@link ShortAdapter#unmarshal(String)}.
+     */
+    @Test
+    public void testUnmarshal() {
+        ShortAdapter adapter = new ShortAdapter();
+        assertEquals(null, adapter.unmarshal((String)null));
+
+        Short[] values = {
+            Short.MIN_VALUE,
+            Short.MIN_VALUE + 1,
+            -12345,
+            -100,
+            -3,
+            -2,
+            -1,
+            0,
+            1,
+            2,
+            3,
+            101,
+            789,
+            12345,
+            30000,
+            Short.MAX_VALUE - 1,
+            Short.MAX_VALUE,
+        };
+
+        for (Short value: values) {
+            short v = value.shortValue();
+
+            // Decimal
+            String dec = value.toString();
+            assertEquals(value, adapter.unmarshal(dec));
+
+            String hex;
+            String oct;
+            if (v < 0) {
+                int i = (int)v * -1;
+                hex = String.format("-0x%x", i);
+                oct = String.format("-0%o", i);
+            } else {
+                hex = String.format("0x%x", v);
+                oct = String.format("0%o", v);
+            }
+
+            // Hexadecimal
+            assertEquals(value, adapter.unmarshal(hex));
+
+            // Octal
+            assertEquals(value, adapter.unmarshal(oct));
+        }
+
+        String[] invalid = {
+            // Invalid format.
+            "",
+            "a",
+            "bad string",
+            "123x45",
+
+            // value out of range
+            "32768",
+            "32769",
+            "99999999",
+            "-32769",
+            "-32770",
+            "-1234567",
+            "10000000000000000000000000",
+            "-10000000000000000000000000",
+        };
+
+        for (String str: invalid) {
+            try {
+                adapter.unmarshal(str);
+                unexpected();
+            } catch (NumberFormatException e) {
+            }
+        }
+    }
+}
diff --git a/manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/VnodeNameAdapterTest.java b/manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/VnodeNameAdapterTest.java
new file mode 100644 (file)
index 0000000..e5399ee
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2015 NEC Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vtn.manager.util.xml.adapters;
+
+import org.junit.Test;
+
+import org.opendaylight.vtn.manager.TestBase;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VnodeName;
+
+/**
+ * JUnit test for {@link VnodeNameAdapter}.
+ */
+public class VnodeNameAdapterTest extends TestBase {
+    /**
+     * Test case for {@link VnodeNameAdapter#marshal(VnodeName)}.
+     */
+    @Test
+    public void testMarshal() {
+        VnodeNameAdapter adapter = new VnodeNameAdapter();
+        assertEquals(null, adapter.marshal((VnodeName)null));
+
+        String[] names = {
+            "a",
+            "AB",
+            "abcde",
+            "0",
+            "01",
+            "012",
+            "0123456789",
+            "a123456789B123456789c123456789D",
+            "vtn_1",
+            "vbridge_2",
+            "vif_3",
+        };
+
+        for (String name: names) {
+            VnodeName vname = new VnodeName(name);
+            assertEquals(name, adapter.marshal(vname));
+        }
+    }
+
+    /**
+     * Test case for {@link VnodeNameAdapter#unmarshal(String)}.
+     */
+    @Test
+    public void testUnmarshal() {
+        VnodeNameAdapter adapter = new VnodeNameAdapter();
+        assertEquals(null, adapter.unmarshal((String)null));
+
+        String[] names = {
+            "a",
+            "AB",
+            "abcde",
+            "0",
+            "01",
+            "0123456789",
+            "a123456789B123456789c123456789D",
+            "vtn_1",
+            "vbridge_2",
+            "vif_3",
+        };
+
+        for (String name: names) {
+            VnodeName vname = new VnodeName(name);
+            assertEquals(vname, adapter.unmarshal(name));
+        }
+
+        String[] invalid = {
+            // Invalid format.
+            "",
+            "bad name",
+            "vtn-1",
+            "@vtn",
+            "_vtn",
+            "/vbridge",
+            "a123456789B123456789c123456789D1",
+        };
+
+        for (String str: invalid) {
+            try {
+                adapter.unmarshal(str);
+                unexpected();
+            } catch (IllegalArgumentException e) {
+            }
+        }
+    }
+}
diff --git a/manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/VtnPortDescAdapterTest.java b/manager/api/src/test/java/org/opendaylight/vtn/manager/util/xml/adapters/VtnPortDescAdapterTest.java
new file mode 100644 (file)
index 0000000..340d241
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2015 NEC Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vtn.manager.util.xml.adapters;
+
+import org.junit.Test;
+
+import org.opendaylight.vtn.manager.TestBase;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VtnPortDesc;
+
+/**
+ * JUnit test for {@link VtnPortDescAdapter}.
+ */
+public class VtnPortDescAdapterTest extends TestBase {
+    /**
+     * Test case for {@link VtnPortDescAdapter#marshal(VtnPortDesc)}.
+     */
+    @Test
+    public void testMarshal() {
+        VtnPortDescAdapter adapter = new VtnPortDescAdapter();
+        assertEquals(null, adapter.marshal((VtnPortDesc)null));
+
+        String[] descs = {
+            "openflow:1,2,eth2",
+            "openflow:1,2,",
+            "openflow:1,,",
+            "openflow:9999:3,,eth3",
+            "unknown:1,abc,port-A",
+            "unknown:1,abc,",
+            "unknown:1,,port-A",
+            "unknown:1,,",
+        };
+
+        for (String desc: descs) {
+            VtnPortDesc vpdesc = new VtnPortDesc(desc);
+            assertEquals(desc, adapter.marshal(vpdesc));
+        }
+    }
+
+    /**
+     * Test case for {@link VtnPortDescAdapter#unmarshal(String)}.
+     */
+    @Test
+    public void testUnmarshal() {
+        VtnPortDescAdapter adapter = new VtnPortDescAdapter();
+        assertEquals(null, adapter.unmarshal((String)null));
+
+        String[] descs = {
+            "openflow:1,2,eth2",
+            "openflow:1,2,",
+            "openflow:1,,",
+            "openflow:9999:3,,eth3",
+            "unknown:1,abc,port-A",
+            "unknown:1,abc,",
+            "unknown:1,,port-A",
+            "unknown:1,,",
+        };
+
+        for (String desc: descs) {
+            VtnPortDesc vpdesc = new VtnPortDesc(desc);
+            assertEquals(vpdesc, adapter.unmarshal(desc));
+        }
+
+        String[] invalid = {
+            // Invalid format.
+            "",
+            "bad port desc",
+            "openflow:1:1,",
+            "openflow:1:2",
+            ",1,eth1",
+        };
+
+        for (String str: invalid) {
+            try {
+                adapter.unmarshal(str);
+                unexpected();
+            } catch (IllegalArgumentException e) {
+            }
+        }
+    }
+}
index b32a983e438dc95dce59b9bcff8b2ca72c14f4e9..20dddae6b336ff0485a1c77235f7af4c96bf6137 100644 (file)
     <javadoc.exclude>*.internal,*.impl,*.it</javadoc.exclude>
 
     <!-- OpenDaylight artifacts -->
-    <odl.mdsal.version>1.3.0-SNAPSHOT</odl.mdsal.version>
+    <odl.controller.mdsal.version>1.3.0-SNAPSHOT</odl.controller.mdsal.version>
     <odl.config.version>0.4.0-SNAPSHOT</odl.config.version>
     <odl.yangtools.version>0.8.0-SNAPSHOT</odl.yangtools.version>
+    <odl.mdsal.version>2.0.0-SNAPSHOT</odl.mdsal.version>
+    <odl.mdsal.model.version>0.8.0-SNAPSHOT</odl.mdsal.model.version>
     <odl.netconf.version>1.3.0-SNAPSHOT</odl.netconf.version>
     <odl.openflowplugin.version>0.2.0-SNAPSHOT</odl.openflowplugin.version>
     <odl.neutron.version>0.6.0-SNAPSHOT</odl.neutron.version>
         <version>2.0.1</version>
       </dependency>
 
-      <!-- OpenDaylight MD-SAL -->
+      <!-- OpenDaylight controller projects (MD-SAL) -->
       <dependency>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>mdsal-artifacts</artifactId>
-        <version>${odl.mdsal.version}</version>
+        <version>${odl.controller.mdsal.version}</version>
         <type>pom</type>
         <scope>import</scope>
       </dependency>
       <dependency>
         <groupId>org.opendaylight.controller</groupId>
         <artifactId>sal-binding-it</artifactId>
-        <version>${odl.mdsal.version}</version>
+        <version>${odl.controller.mdsal.version}</version>
       </dependency>
 
       <!-- OpenDaylight config subsystem -->
         <scope>import</scope>
       </dependency>
 
+      <!-- OpenDaylight MD-SAL -->
+      <dependency>
+        <groupId>org.opendaylight.mdsal</groupId>
+        <artifactId>mdsal-artifacts</artifactId>
+        <version>${odl.mdsal.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+      <dependency>
+        <groupId>org.opendaylight.mdsal.model</groupId>
+        <artifactId>mdsal-model-artifacts</artifactId>
+        <version>${odl.mdsal.model.version}</version>
+        <type>pom</type>
+        <scope>import</scope>
+      </dependency>
+
       <!-- OpenDaylight openflowplugin -->
       <dependency>
         <groupId>org.opendaylight.openflowplugin</groupId>
index 71753299ceb943fae2a1a65e7459ae567bccdca3..f985741c852d4876c3ad732d6d29d5fee940c556 100644 (file)
   </build>
 
   <dependencies>
-    <!-- OpenDaylight YANG Tools -->
+    <!-- OpenDaylight MD-SAL -->
     <dependency>
       <groupId>org.opendaylight.mdsal</groupId>
       <artifactId>yang-binding</artifactId>
index 435b59dcb4e4699b9ef0ace266d4f462bc74ba32..7fac34c0f84be1841b1519a94141a7c15caecbea 100644 (file)
@@ -15,7 +15,7 @@
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://karaf.apache.org/xmlns/features/v1.2.0 http://karaf.apache.org/xmlns/features/v1.2.0">
 
-  <repository>mvn:org.opendaylight.controller/features-mdsal/${odl.mdsal.version}/xml/features</repository>
+  <repository>mvn:org.opendaylight.controller/features-mdsal/${odl.controller.mdsal.version}/xml/features</repository>
   <repository>mvn:org.opendaylight.controller/features-nsf/${feature.nsf.version}/xml/features</repository>
   <repository>mvn:org.opendaylight.netconf/features-restconf/${odl.netconf.version}/xml/features</repository>
   <repository>mvn:org.opendaylight.neutron/features-neutron/${odl.neutron.version}/xml/features</repository>
@@ -26,7 +26,7 @@
       name='odl-vtn-manager'
       description="OpenDaylight :: VTN Manager :: Java API"
       version='${project.version}'>
-    <feature version="${odl.mdsal.version}">odl-mdsal-broker</feature>
+    <feature version="${odl.controller.mdsal.version}">odl-mdsal-broker</feature>
     <feature version="${odl.openflowplugin.version}">odl-openflowplugin-flow-services</feature>
     <feature version="${odl.openflowplugin.version}">odl-openflowplugin-nsf-model</feature>
     <feature version="${feature.nsf.version}">odl-nsf-service</feature>
index 7a828df202b214648f40961d6afe28a4634d2cfe..c75ba1075c62c212fcf6f63ebe50a3053916be44 100644 (file)
       <artifactId>org.osgi.core</artifactId>
     </dependency>
 
-    <!-- OpenDaylight MD-SAL -->
+    <!-- OpenDaylight controller (MD-SAL) -->
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-binding-config</artifactId>
       <artifactId>model-inventory</artifactId>
     </dependency>
 
-    <!-- OpenDaylight YANG Tools -->
+    <!-- OpenDaylight MD-SAL -->
     <dependency>
       <groupId>org.opendaylight.mdsal.model</groupId>
       <artifactId>ietf-yang-types</artifactId>
index 31dccd9282774e9de6ee9609868045af5c805f16..1685f77cc7e520322dbb7e1be5d57031e3768739 100644 (file)
@@ -8,8 +8,7 @@
 
 package org.opendaylight.vtn.manager.internal.routing;
 
-import org.opendaylight.vtn.manager.PathMap;
-
+import org.opendaylight.vtn.manager.internal.routing.xml.XmlPathMap;
 import org.opendaylight.vtn.manager.internal.util.ConfigFileUpdater;
 import org.opendaylight.vtn.manager.internal.util.XmlConfigFile;
 
@@ -21,7 +20,7 @@ import org.opendaylight.vtn.manager.internal.util.XmlConfigFile;
  *   Note that this class is not synchronized.
  * </p>
  */
-final class GlobalPathMapChange extends ConfigFileUpdater<Integer, PathMap> {
+final class GlobalPathMapChange extends ConfigFileUpdater<Integer, XmlPathMap> {
     /**
      * Construct a new instance.
      */
index 2eb5916c3d6814288c03d1b16831b4b56b33f11d..f224b6f1aa17a20eb5b0cc830a44b20475c29966 100644 (file)
@@ -18,13 +18,13 @@ import java.util.concurrent.Future;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.opendaylight.vtn.manager.PathMap;
 import org.opendaylight.vtn.manager.VTNException;
 
 import org.opendaylight.vtn.manager.internal.TxContext;
 import org.opendaylight.vtn.manager.internal.TxTask;
 import org.opendaylight.vtn.manager.internal.VTNManagerProvider;
 import org.opendaylight.vtn.manager.internal.VTNSubSystem;
+import org.opendaylight.vtn.manager.internal.routing.xml.XmlPathMap;
 import org.opendaylight.vtn.manager.internal.util.ChangedData;
 import org.opendaylight.vtn.manager.internal.util.CompositeAutoCloseable;
 import org.opendaylight.vtn.manager.internal.util.DataStoreListener;
@@ -99,11 +99,11 @@ public final class PathMapManager
          *                resumed configuration.
          * @param loaded  A set of loaded path path map indices.
          * @param key     A string representation of the map index.
-         * @param pmap    A {@link PathMap} instance.
+         * @param xpm     A {@link XmlPathMap} instance.
          */
         private void resume(List<VtnPathMap> vlist, Set<Integer> loaded,
-                            String key, PathMap pmap) {
-            Integer index = pmap.getIndex();
+                            String key, XmlPathMap xpm) {
+            Integer index = xpm.getIndex();
             try {
                 if (!key.equals(String.valueOf(index))) {
                     String msg = new StringBuilder("Unexpected index: ").
@@ -111,14 +111,14 @@ public final class PathMapManager
                         toString();
                     throw new IllegalArgumentException(msg);
                 }
-                VtnPathMap vpm = PathMapUtils.toVtnPathMapBuilder(pmap).
+                VtnPathMap vpm = PathMapUtils.toVtnPathMapBuilder(xpm).
                     build();
                 vlist.add(vpm);
                 loaded.add(index);
             } catch (RpcException | RuntimeException e) {
                 String msg = MiscUtils.joinColon(
                     "Ignore invalid path map configuration",
-                    pmap, e.getMessage());
+                    xpm, e.getMessage());
                 LOG.warn(msg, e);
             }
         }
@@ -135,9 +135,10 @@ public final class PathMapManager
             XmlConfigFile.Type ftype = XmlConfigFile.Type.PATHMAP;
             List<VtnPathMap> vlist = new ArrayList<>();
             for (String key: XmlConfigFile.getKeys(ftype)) {
-                PathMap pmap = XmlConfigFile.load(ftype, key, PathMap.class);
-                if (pmap != null) {
-                    resume(vlist, loaded, key, pmap);
+                XmlPathMap xpm =
+                    XmlConfigFile.load(ftype, key, XmlPathMap.class);
+                if (xpm != null) {
+                    resume(vlist, loaded, key, xpm);
                 }
             }
 
@@ -236,9 +237,9 @@ public final class PathMapManager
                 for (VtnPathMap vpm: vlist) {
                     // Save configuration into a file.
                     try {
-                        PathMap pmap = PathMapUtils.toPathMap(vpm);
-                        String index = pmap.getIndex().toString();
-                        XmlConfigFile.save(ftype, index, pmap);
+                        XmlPathMap xpm = new XmlPathMap(vpm);
+                        String index = xpm.getIndex().toString();
+                        XmlConfigFile.save(ftype, index, xpm);
                         indices.add(index);
                     } catch (Exception e) {
                         LOG.warn("Ignore broken path map: " + vpm, e);
@@ -278,8 +279,8 @@ public final class PathMapManager
                            IdentifiedData<VtnPathMap> data, boolean created) {
         VtnPathMap vpm = data.getValue();
         try {
-            PathMap pmap = PathMapUtils.toPathMap(vpm);
-            ectx.addUpdated(pmap.getIndex(), pmap, created);
+            XmlPathMap xpm = new XmlPathMap(vpm);
+            ectx.addUpdated(xpm.getIndex(), xpm, created);
         } catch (Exception e) {
             FixedLogger logger = new FixedLogger.Warn(LOG);
             logger.log(e, "Ignore broken %s event: path=%s, value=%s",
index 1ad5c07e8f17ce2b193ece3e0b947e7d86d1a5b1..5f53934f0311b2d2255ecda8bcdee41d522ab865 100644 (file)
@@ -8,8 +8,7 @@
 
 package org.opendaylight.vtn.manager.internal.routing;
 
-import org.opendaylight.vtn.manager.PathPolicy;
-
+import org.opendaylight.vtn.manager.internal.routing.xml.XmlPathPolicy;
 import org.opendaylight.vtn.manager.internal.util.AbstractConfigFileUpdater;
 import org.opendaylight.vtn.manager.internal.util.XmlConfigFile;
 
@@ -22,7 +21,7 @@ import org.opendaylight.vtn.manager.internal.util.XmlConfigFile;
  * </p>
  */
 final class PathPolicyChange
-    extends AbstractConfigFileUpdater<Integer, PathPolicy> {
+    extends AbstractConfigFileUpdater<Integer, XmlPathPolicy> {
     /**
      * The network topology graph.
      */
@@ -44,7 +43,7 @@ final class PathPolicyChange
      * {@inheritDoc}
      */
     @Override
-    protected boolean onUpdated(Integer key, PathPolicy value) {
+    protected boolean onUpdated(Integer key, XmlPathPolicy value) {
         // Update the route resolver for the given path policy.
         return topology.updateResolver(key);
     }
index f3ce425a3632ea5871346b90c6a656ed8967092e..4835f345d70f5253f2bcb1b928203b0d56850332 100644 (file)
@@ -17,12 +17,12 @@ import java.util.concurrent.ConcurrentSkipListSet;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.opendaylight.vtn.manager.PathPolicy;
 import org.opendaylight.vtn.manager.VTNException;
 
 import org.opendaylight.vtn.manager.internal.TxContext;
 import org.opendaylight.vtn.manager.internal.TxTask;
 import org.opendaylight.vtn.manager.internal.VTNManagerProvider;
+import org.opendaylight.vtn.manager.internal.routing.xml.XmlPathPolicy;
 import org.opendaylight.vtn.manager.internal.util.ChangedData;
 import org.opendaylight.vtn.manager.internal.util.DataStoreListener;
 import org.opendaylight.vtn.manager.internal.util.DataStoreUtils;
@@ -31,7 +31,6 @@ import org.opendaylight.vtn.manager.internal.util.MiscUtils;
 import org.opendaylight.vtn.manager.internal.util.XmlConfigFile;
 import org.opendaylight.vtn.manager.internal.util.concurrent.VTNFuture;
 import org.opendaylight.vtn.manager.internal.util.pathpolicy.PathPolicyConfigBuilder;
-import org.opendaylight.vtn.manager.internal.util.pathpolicy.PathPolicyUtils;
 import org.opendaylight.vtn.manager.internal.util.rpc.RpcException;
 import org.opendaylight.vtn.manager.internal.util.tx.AbstractTxTask;
 
@@ -84,11 +83,11 @@ final class PathPolicyListener
          *                resumed configuration.
          * @param loaded  A set of loaded path policy IDs.
          * @param key     A string representation of the policy ID.
-         * @param pp      A {@link PathPolicy} instance.
+         * @param xpp     A {@link XmlPathPolicy} instance.
          */
         private void resume(List<VtnPathPolicy> vlist, Set<Integer> loaded,
-                            String key, PathPolicy pp) {
-            Integer pid = pp.getPolicyId();
+                            String key, XmlPathPolicy xpp) {
+            Integer pid = xpp.getId();
             try {
                 if (!key.equals(String.valueOf(pid))) {
                     String msg = new StringBuilder("Unexpected ID: ").
@@ -97,13 +96,13 @@ final class PathPolicyListener
                     throw new IllegalArgumentException(msg);
                 }
                 VtnPathPolicy vpp = new PathPolicyConfigBuilder.Data().
-                    set(pp).getBuilder().build();
+                    set(xpp).getBuilder().build();
                 vlist.add(vpp);
                 loaded.add(pid);
             } catch (RpcException | RuntimeException e) {
                 String msg = MiscUtils.joinColon(
                     "Ignore invalid path policy configuration",
-                    pp, e.getMessage());
+                    xpp, e.getMessage());
                 LOG.warn(msg, e);
             }
         }
@@ -120,10 +119,10 @@ final class PathPolicyListener
             XmlConfigFile.Type ftype = XmlConfigFile.Type.PATHPOLICY;
             List<VtnPathPolicy> vlist = new ArrayList<>();
             for (String key: XmlConfigFile.getKeys(ftype)) {
-                PathPolicy pp = XmlConfigFile.load(
-                    ftype, key, PathPolicy.class);
-                if (pp != null) {
-                    resume(vlist, loaded, key, pp);
+                XmlPathPolicy xpp = XmlConfigFile.load(
+                    ftype, key, XmlPathPolicy.class);
+                if (xpp != null) {
+                    resume(vlist, loaded, key, xpp);
                 }
             }
 
@@ -222,9 +221,9 @@ final class PathPolicyListener
             if (vlist != null) {
                 for (VtnPathPolicy vpp: vlist) {
                     // Save configuration into a file.
-                    PathPolicy pp = PathPolicyUtils.toPathPolicy(vpp);
-                    String key = pp.getPolicyId().toString();
-                    XmlConfigFile.save(ftype, key, pp);
+                    XmlPathPolicy xpp = new XmlPathPolicy(vpp);
+                    String key = xpp.getId().toString();
+                    XmlConfigFile.save(ftype, key, xpp);
                     names.add(key);
                 }
             }
@@ -314,8 +313,7 @@ final class PathPolicyListener
             // setup.
             Set<Integer> loaded = loadedPolicies;
             if (loaded == null || !loaded.remove(id)) {
-                VtnPathPolicy vpp = data.getValue();
-                ectx.addUpdated(id, PathPolicyUtils.toPathPolicy(vpp));
+                ectx.addUpdated(id, new XmlPathPolicy(data.getValue()));
             } else if (loaded.isEmpty()) {
                 LOG.debug("All loaded path policies have been notified.");
                 loadedPolicies = null;
@@ -336,7 +334,7 @@ final class PathPolicyListener
             LOG.warn("Ignore broken update event: path={}, old={}, new={}",
                      path, vpp, data.getOldValue());
         } else {
-            ectx.addUpdated(id, PathPolicyUtils.toPathPolicy(vpp));
+            ectx.addUpdated(id, new XmlPathPolicy(vpp));
         }
     }
 
index 9cbf61e3bf081aff64933939969b32f5a00df4f5..f31b65ee223d453defc6a9f131b7247db28aeea1 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.vtn.manager.internal.routing;
 
+import static org.opendaylight.vtn.manager.internal.util.pathpolicy.PathPolicyUtils.COST_UNDEF;
+
 import java.util.List;
 
 import org.slf4j.Logger;
@@ -15,7 +17,6 @@ import org.slf4j.LoggerFactory;
 
 import org.apache.commons.collections15.Transformer;
 
-import org.opendaylight.vtn.manager.PathPolicy;
 import org.opendaylight.vtn.manager.VTNException;
 
 import org.opendaylight.vtn.manager.internal.util.DataStoreUtils;
@@ -213,7 +214,7 @@ final class PathPolicyTransformer implements Transformer<LinkEdge, Long> {
     private Long getDefaultCost(VtnPathPolicy vpp, SalPort sport,
                                 VtnPort vport) {
         Long cost = vpp.getDefaultCost();
-        if (cost == null || cost.longValue() == PathPolicy.COST_UNDEF) {
+        if (cost == null || cost.longValue() == COST_UNDEF) {
             cost = vport.getCost();
             LOG.trace("{}: Use link cost in VTN port: port={}, cost={}",
                       policyId, sport, cost);
diff --git a/manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathCost.java b/manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathCost.java
new file mode 100644 (file)
index 0000000..86f3754
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2015 NEC Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vtn.manager.internal.routing.xml;
+
+import java.util.Objects;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.VtnPathCostConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VtnPortDesc;
+
+/**
+ * {@code XmlPathCost} provides XML binding to data model for the cost of using
+ * specific inter-switch link.
+ */
+@XmlRootElement(name = "vtn-path-cost")
+@XmlAccessorType(XmlAccessType.NONE)
+public final class XmlPathCost implements VtnPathCostConfig {
+    /**
+     * A string which specifies the location of the physical switch port
+     * linked to another physical switch.
+     */
+    @XmlElement(name = "port-desc", required = true)
+    private VtnPortDesc  portDesc;
+
+    /**
+     * The cost of using physical switch port.
+     */
+    @XmlElement
+    private Long  cost;
+
+    /**
+     * Private constructor only for JAXB.
+     */
+    private XmlPathCost() {
+    }
+
+    /**
+     * Construct a new instance from the given {@link VtnPathCostConfig}
+     * instance.
+     *
+     * <p>
+     *   Note that this constructor assumes that the given instance is valid.
+     * </p>
+     *
+     * @param vpcc  A {@link VtnPathCostConfig} instance.
+     */
+    public XmlPathCost(VtnPathCostConfig vpcc) {
+        portDesc = vpcc.getPortDesc();
+        cost = vpcc.getCost();
+    }
+
+    // DataContainer
+
+    /**
+     * Return a class which indicates the data model type implemented by this
+     * instance.
+     *
+     * @return  A class instance of {@link VtnPathCostConfig}.
+     */
+    @Override
+    public Class<VtnPathCostConfig> getImplementedInterface() {
+        return VtnPathCostConfig.class;
+    }
+
+    // VtnPathCostConfig
+
+    /**
+     * Return the location of the physical switch port.
+     *
+     * @return  A {@link VtnPortDesc} instance which indicates the location of
+     *          the physical switch port.
+     */
+    @Override
+    public VtnPortDesc getPortDesc() {
+        return portDesc;
+    }
+
+    /**
+     * Return the cost of using physical switch port.
+     *
+     * @return  A {@link Long} instance which represents the cost of using
+     *          physical switch port.
+     */
+    @Override
+    public Long getCost() {
+        return cost;
+    }
+
+    // Object
+
+    /**
+     * Determine whether the given object is identical to this object.
+     *
+     * @param o  An object to be compared.
+     * @return   {@code true} if identical. Otherwise {@code false}.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+
+        boolean ret;
+        if (o != null && getClass().equals(o.getClass())) {
+            XmlPathCost xpc = (XmlPathCost)o;
+            ret = (Objects.equals(portDesc, xpc.portDesc) &&
+                   Objects.equals(cost, xpc.cost));
+        } else {
+            ret = false;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Return the hash code of this object.
+     *
+     * @return  The hash code.
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(getClass(), portDesc, cost);
+    }
+
+    /**
+     * Return a string representation of this object.
+     *
+     * @return  A string representation of this object.
+     */
+    @Override
+    public String toString() {
+        String desc = (portDesc == null) ? null : portDesc.getValue();
+        return "vtn-path-cost[port=" + desc + ", cost=" + cost + "]";
+    }
+}
diff --git a/manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathMap.java b/manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathMap.java
new file mode 100644 (file)
index 0000000..78b6108
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 2015 NEC Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vtn.manager.internal.routing.xml;
+
+import java.util.Objects;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.vtn.manager.internal.util.flow.FlowUtils;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathmap.rev150328.VtnPathMapConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VnodeName;
+
+/**
+ * {@code XmlPathMap} provides XML binding to data model for path map
+ * configuration.
+ */
+@XmlRootElement(name = "vtn-path-map")
+@XmlAccessorType(XmlAccessType.NONE)
+public final class XmlPathMap implements VtnPathMapConfig {
+    /**
+     * An index value assigned to this path map.
+     */
+    @XmlElement(required = true)
+    private Integer  index;
+
+    /**
+     * The name of the flow condition that selects packets.
+     */
+    @XmlElement(required = true)
+    private VnodeName  condition;
+
+    /**
+     * The identifier of the path policy which determines the route of packets.
+     */
+    @XmlElement
+    private Integer  policy;
+
+    /**
+     * The number of seconds to be configured in {@code idle_timeout} field
+     * in flow entries.
+     */
+    @XmlElement(name = "idle-timeout")
+    private Integer  idleTimeout;
+
+    /**
+     * The number of seconds to be configured in {@code hard_timeout} field
+     * in flow entries.
+     */
+    @XmlElement(name = "hard-timeout")
+    private Integer  hardTimeout;
+
+    /**
+     * Private constructor only for JAXB.
+     */
+    private XmlPathMap() {
+    }
+
+    /**
+     * Construct a new instance from the given {@link VtnPathMapConfig}
+     * instance.
+     *
+     * <p>
+     *   Note that this constructor assumes that the given instance is valid.
+     * </p>
+     *
+     * @param vpmc  A {@link VtnPathMapConfig} instance.
+     */
+    public XmlPathMap(VtnPathMapConfig vpmc) {
+        index = vpmc.getIndex();
+        condition = vpmc.getCondition();
+        policy = vpmc.getPolicy();
+        idleTimeout = vpmc.getIdleTimeout();
+        hardTimeout = vpmc.getHardTimeout();
+    }
+
+    // DataContainer
+
+    /**
+     * Return a class which indicates the data model type implemented by this
+     * instance.
+     *
+     * @return  A class instance of {@link VtnPathMapConfig}.
+     */
+    @Override
+    public Class<VtnPathMapConfig> getImplementedInterface() {
+        return VtnPathMapConfig.class;
+    }
+
+    // VtnIndex
+
+    /**
+     * Return an index number assigned to this path map.
+     *
+     * @return  An {@link Integer} instance which indicates the index number.
+     */
+    @Override
+    public Integer getIndex() {
+        return index;
+    }
+
+    // VtnFlowTimeoutConfig
+
+    /**
+     * Return the number of seconds to be set to {@code idle-timeout} field in
+     * flow entries.
+     *
+     * @return  An {@link Integer} instance which indicates the value for
+     *          {@code idle-timeout}.
+     */
+    @Override
+    public Integer getIdleTimeout() {
+        return idleTimeout;
+    }
+
+    /**
+     * Return the number of seconds to be set to {@code hard-timeout} field in
+     * flow entries.
+     *
+     * @return  An {@link Integer} instance which indicates the value for
+     *          {@code hard-timeout}.
+     */
+    @Override
+    public Integer getHardTimeout() {
+        return hardTimeout;
+    }
+
+    // VtnPathMapConfig
+
+    /**
+     * Return the name of the flow condition that selects packets.
+     *
+     * @return  A {@link VnodeName} instance which contains the flow condition
+     *          name.
+     */
+    @Override
+    public VnodeName getCondition() {
+        return condition;
+    }
+
+    /**
+     * Return the identifier of the path policy which determines the route of
+     * packets.
+     *
+     * @return  An {@link Integer} instance which indicates the path policy
+     *          identifier.
+     */
+    @Override
+    public Integer getPolicy() {
+        return policy;
+    }
+
+    // Object
+
+    /**
+     * Determine whether the given object is identical to this object.
+     *
+     * @param o  An object to be compared.
+     * @return   {@code true} if identical. Otherwise {@code false}.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+
+        boolean ret;
+        if (o != null && getClass().equals(o.getClass())) {
+            XmlPathMap xpm = (XmlPathMap)o;
+            ret = (Objects.equals(index, xpm.index) &&
+                   Objects.equals(condition, xpm.condition) &&
+                   Objects.equals(policy, xpm.policy) &&
+                   FlowUtils.equalsFlowTimeoutConfig(this, xpm));
+        } else {
+            ret = false;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Return the hash code of this object.
+     *
+     * @return  The hash code.
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(getClass(), index, condition, policy, idleTimeout,
+                            hardTimeout);
+    }
+
+    /**
+     * Return a string representation of this object.
+     *
+     * @return  A string representation of this object.
+     */
+    @Override
+    public String toString() {
+        String cond = (condition == null) ? null : condition.getValue();
+        return "vtn-path-map[index=" + index + ", condition=" + cond +
+            ", policy=" + policy + ", idle-timeout=" + idleTimeout +
+            ", hard-timeout=" + hardTimeout + "]";
+    }
+}
diff --git a/manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathPolicy.java b/manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathPolicy.java
new file mode 100644 (file)
index 0000000..33fefe5
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2015 NEC Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vtn.manager.internal.routing.xml;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlElementWrapper;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.VtnPathPolicyConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.vtn.path.policy.config.VtnPathCost;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.vtn.path.policy.config.VtnPathCostBuilder;
+
+/**
+ * {@code XmlPathPolicy} provides XML binding to data model for path policy
+ * configuration.
+ */
+@XmlRootElement(name = "vtn-path-policy")
+@XmlAccessorType(XmlAccessType.NONE)
+public final class XmlPathPolicy implements VtnPathPolicyConfig {
+    /**
+     * The identifier of this path policy.
+     */
+    @XmlElement(required = true)
+    private Integer  id;
+
+    /**
+     * The default cost for unspecified link.
+     */
+    @XmlElement(name = "default")
+    private Long  defaultCost;
+
+    /**
+     * A list of path costs which specifies the cost of switch link for
+     * transmitting.
+     */
+    @XmlElementWrapper(name = "vtn-path-costs")
+    @XmlElement(name = "vtn-path-cost")
+    private List<XmlPathCost>  pathCosts;
+
+    /**
+     * Private constructor only for JAXB.
+     */
+    private XmlPathPolicy() {
+    }
+
+    /**
+     * Consturct a new instance from the given {@link VtnPathPolicyConfig}
+     * instance.
+     *
+     * <p>
+     *   Note that this constructor assumes that the given instance is valid.
+     * </p>
+     *
+     * @param vppc  A {@link VtnPathPolicyConfig} instance.
+     */
+    public XmlPathPolicy(VtnPathPolicyConfig vppc) {
+        id = vppc.getId();
+        defaultCost = vppc.getDefaultCost();
+        List<VtnPathCost> costs = vppc.getVtnPathCost();
+        if (costs != null && !costs.isEmpty()) {
+            List<XmlPathCost> xcosts = new ArrayList<>(costs.size());
+            for (VtnPathCost vpc: costs) {
+                xcosts.add(new XmlPathCost(vpc));
+            }
+            pathCosts = xcosts;
+        }
+    }
+
+    // DataContainer
+
+    /**
+     * Return a class which indicates the data model type implemented by this
+     * instance.
+     *
+     * @return  A class instance of {@link VtnPathPolicyConfig}.
+     */
+    @Override
+    public Class<VtnPathPolicyConfig> getImplementedInterface() {
+        return VtnPathPolicyConfig.class;
+    }
+
+    // VtnPathPolicyConfig
+
+    /**
+     * Return the identifier of this path policy.
+     *
+     * @return  An {@link Integer} instance which indicates the path policy
+     *          identifier.
+     */
+    @Override
+    public Integer getId() {
+        return id;
+    }
+
+    /**
+     * Reurn the default cost for unspecified link.
+     *
+     * @return  A {@link Long} instance which indicates the default cost.
+     */
+    @Override
+    public Long getDefaultCost() {
+        return defaultCost;
+    }
+
+    /**
+     * Return a list of path costs configured in this path policy.
+     *
+     * @return  A list of {@link VtnPathCost} instances.
+     */
+    @Override
+    public List<VtnPathCost> getVtnPathCost() {
+        List<VtnPathCost> costs;
+        if (pathCosts == null) {
+            costs = null;
+        } else {
+            costs = new ArrayList<>(pathCosts.size());
+            for (XmlPathCost xpc: pathCosts) {
+                costs.add(new VtnPathCostBuilder(xpc).build());
+            }
+        }
+
+        return costs;
+    }
+
+    // Object
+
+    /**
+     * Determine whether the given object is identical to this object.
+     *
+     * @param o  An object to be compared.
+     * @return   {@code true} if identical. Otherwise {@code false}.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+
+        boolean ret;
+        if (o != null && getClass().equals(o.getClass())) {
+            XmlPathPolicy xpp = (XmlPathPolicy)o;
+            ret = (Objects.equals(id, xpp.id) &&
+                   Objects.equals(defaultCost, xpp.defaultCost) &&
+                   Objects.equals(pathCosts, xpp.pathCosts));
+        } else {
+            ret = false;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Return the hash code of this object.
+     *
+     * @return  The hash code.
+     */
+    @Override
+    public int hashCode() {
+        return Objects.hash(getClass(), id, defaultCost, pathCosts);
+    }
+
+    /**
+     * Return a string representation of this object.
+     *
+     * @return  A string representation of this object.
+     */
+    @Override
+    public String toString() {
+        return "vtn-path-policy[id=" + id + ", default=" + defaultCost +
+            ", costs=" + pathCosts + "]";
+    }
+}
diff --git a/manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/xml/package-info.java b/manager/implementation/src/main/java/org/opendaylight/vtn/manager/internal/routing/xml/package-info.java
new file mode 100644 (file)
index 0000000..6fd6fd1
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2015 NEC Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/**
+ * This package contains XML bindings to models used for packet routing.
+ */
+@XmlJavaTypeAdapters({
+    @XmlJavaTypeAdapter(value = ByteAdapter.class, type = Byte.class),
+    @XmlJavaTypeAdapter(value = ByteAdapter.class, type = byte.class),
+    @XmlJavaTypeAdapter(value = ShortAdapter.class, type = Short.class),
+    @XmlJavaTypeAdapter(value = ShortAdapter.class, type = short.class),
+    @XmlJavaTypeAdapter(value = IntegerAdapter.class, type = Integer.class),
+    @XmlJavaTypeAdapter(value = IntegerAdapter.class, type = int.class),
+    @XmlJavaTypeAdapter(value = LongAdapter.class, type = Long.class),
+    @XmlJavaTypeAdapter(value = LongAdapter.class, type = long.class),
+    @XmlJavaTypeAdapter(value = DoubleAdapter.class, type = double.class),
+    @XmlJavaTypeAdapter(value = DoubleAdapter.class, type = Double.class),
+    @XmlJavaTypeAdapter(value = VnodeNameAdapter.class, type = VnodeName.class),
+    @XmlJavaTypeAdapter(value = VtnPortDescAdapter.class,
+                        type = VtnPortDesc.class),
+})
+package org.opendaylight.vtn.manager.internal.routing.xml;
+
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapters;
+
+import org.opendaylight.vtn.manager.util.xml.adapters.ByteAdapter;
+import org.opendaylight.vtn.manager.util.xml.adapters.DoubleAdapter;
+import org.opendaylight.vtn.manager.util.xml.adapters.IntegerAdapter;
+import org.opendaylight.vtn.manager.util.xml.adapters.LongAdapter;
+import org.opendaylight.vtn.manager.util.xml.adapters.ShortAdapter;
+import org.opendaylight.vtn.manager.util.xml.adapters.VnodeNameAdapter;
+import org.opendaylight.vtn.manager.util.xml.adapters.VtnPortDescAdapter;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VnodeName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VtnPortDesc;
index df5910a5870d569886c5ea8d6d8b33a16bd10173..5a1913f6bc4304b647a5464a367b8fc0688666f0 100644 (file)
@@ -13,6 +13,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 
 import org.slf4j.Logger;
@@ -218,6 +219,30 @@ public final class FlowUtils {
         }
     }
 
+    /**
+     * Determine whether the given two {@link VtnFlowTimeoutConfig} instances
+     * contain the same configuration or not.
+     *
+     * @param vftc1  The first instance to be compared.
+     * @param vftc2  The second instance to be compared.
+     * @return  {@code true} only if the given instances contains the same
+     *          configuration.
+     */
+    public static boolean equalsFlowTimeoutConfig(
+        VtnFlowTimeoutConfig vftc1, VtnFlowTimeoutConfig vftc2) {
+        Integer idle1 = vftc1.getIdleTimeout();
+        Integer idle2 = vftc2.getIdleTimeout();
+        boolean ret;
+        if (Objects.equals(idle1, idle2)) {
+            ret = Objects.equals(vftc1.getHardTimeout(),
+                                 vftc2.getHardTimeout());
+        } else {
+            ret = false;
+        }
+
+        return ret;
+    }
+
     /**
      * Return the initial value of the VTN flow ID.
      *
index 26c7040414c781076a2ef31794801f9a51b59e69..d307a405b8eaaca0ddcb200815a911315aa9bc7c 100644 (file)
@@ -52,6 +52,11 @@ public final class PathPolicyUtils {
      */
     public static final Long  DEFAULT_LINK_COST = Long.valueOf(1L);
 
+    /**
+     * The pseudo link cost value which represents the cost is not defined.
+     */
+    public static final long  COST_UNDEF = 0L;
+
     /**
      * Private constructor that protects this class from instantiating.
      */
@@ -253,7 +258,7 @@ public final class PathPolicyUtils {
      */
     public static PathPolicy toPathPolicy(VtnPathPolicy vpp) {
         Long c = vpp.getDefaultCost();
-        long defc = (c == null) ? PathPolicy.COST_UNDEF : c.longValue();
+        long defc = (c == null) ? COST_UNDEF : c.longValue();
         List<PathCost> costs = new ArrayList<>();
         List<VtnPathCost> vlist = vpp.getVtnPathCost();
         if (vlist != null) {
index dff9cc988ce301a2e4f6fba7b92f395670659fa6..d3398007eed64c5bec0fea1082a03d90f311872e 100644 (file)
@@ -16,11 +16,11 @@ import java.util.concurrent.ConcurrentMap;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.opendaylight.vtn.manager.PathMap;
 import org.opendaylight.vtn.manager.VTNException;
 
 import org.opendaylight.vtn.manager.internal.TxContext;
 import org.opendaylight.vtn.manager.internal.VTNManagerProvider;
+import org.opendaylight.vtn.manager.internal.routing.xml.XmlPathMap;
 import org.opendaylight.vtn.manager.internal.util.DataStoreUtils;
 import org.opendaylight.vtn.manager.internal.util.FixedLogger;
 import org.opendaylight.vtn.manager.internal.util.LogRecord;
@@ -145,31 +145,31 @@ class VTenantLoadTask extends AbstractTxTask<Vtns> {
      * Resume VTN path map configuration.
      *
      * @param vname  A {@link VnodeName} instance that contains the VTN name.
-     * @param pmaps  A list of {@link PathMap} instances.
+     * @param xpms   A list of {@link XmlPathMap} instances.
      * @return  A list of {@link VtnPathMap} instances if at least one VTN
      *          path map is present. {@code null} if no path map is present.
      */
     private List<VtnPathMap> resumePathMaps(VnodeName vname,
-                                            List<PathMap> pmaps) {
-        if (pmaps == null || pmaps.isEmpty()) {
+                                            List<XmlPathMap> xpms) {
+        if (xpms == null || xpms.isEmpty()) {
             return null;
         }
 
-        List<VtnPathMap> vlist = new ArrayList<>(pmaps.size());
-        for (PathMap pmap: pmaps) {
+        List<VtnPathMap> vlist = new ArrayList<>(xpms.size());
+        for (XmlPathMap xpm: xpms) {
+            Integer index = xpm.getIndex();
             try {
-                vlist.add(PathMapUtils.toVtnPathMapBuilder(pmap).build());
-                Integer index = pmap.getIndex();
+                vlist.add(PathMapUtils.toVtnPathMapBuilder(xpm).build());
                 addLoadedPath(PathMapUtils.getIdentifier(vname, index),
                               "%s.%s: VTN path map has been loaded: " +
                               "cond=%s, policy=%s, idle=%s, hard=%s",
-                              vname.getValue(), pmap.getIndex(),
-                              pmap.getFlowConditionName(),
-                              pmap.getPathPolicyId(), pmap.getIdleTimeout(),
-                              pmap.getHardTimeout());
+                              vname.getValue(), index,
+                              xpm.getCondition(),
+                              xpm.getPolicy(), xpm.getIdleTimeout(),
+                              xpm.getHardTimeout());
             } catch (Exception e) {
                 String msg = new StringBuilder(vname.getValue()).
-                    append('.').append(pmap.getIndex()).
+                    append('.').append(index).
                     append(": Ignore broken VTN path map.").toString();
                 logger.warn(msg, e);
             }
index 4da5d638643ee80778008cc6f81511251a033300..d316506e9e81c18f2a02bb413d5ada20af51c584 100644 (file)
@@ -18,9 +18,7 @@ import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlElementWrapper;
 import javax.xml.bind.annotation.XmlRootElement;
 
-import org.opendaylight.vtn.manager.PathMap;
-
-import org.opendaylight.vtn.manager.internal.util.pathmap.PathMapUtils;
+import org.opendaylight.vtn.manager.internal.routing.xml.XmlPathMap;
 import org.opendaylight.vtn.manager.internal.util.rpc.RpcException;
 import org.opendaylight.vtn.manager.internal.util.vnode.VTenantUtils;
 
@@ -40,7 +38,7 @@ public final class XmlVTenant extends XmlVNode {
      */
     @XmlElementWrapper(name = "vtn-path-maps")
     @XmlElement(name = "vtn-path-map")
-    private List<PathMap>  pathMaps;
+    private List<XmlPathMap>  pathMaps;
 
     /**
      * Private constructor only for JAXB.
@@ -76,9 +74,9 @@ public final class XmlVTenant extends XmlVNode {
     /**
      * Return a list of VTN path map configurations.
      *
-     * @return  A list of {@link PathMap} instances or {@code null}.
+     * @return  A list of {@link XmlPathMap} instances or {@code null}.
      */
-    public List<PathMap> getPathMaps() {
+    public List<XmlPathMap> getPathMaps() {
         return pathMaps;
     }
 
@@ -99,10 +97,10 @@ public final class XmlVTenant extends XmlVNode {
             return;
         }
 
-        List<PathMap> list = new ArrayList<>(vlist.size());
+        List<XmlPathMap> list = new ArrayList<>(vlist.size());
         pathMaps = list;
         for (VtnPathMap vpm: vlist) {
-            list.add(PathMapUtils.toPathMap(vpm));
+            list.add(new XmlPathMap(vpm));
         }
     }
 
index 52d6be4583bc5de1c9a8e7913593ab198d2885b8..99a3737f279cd101a1f483b3b60bb24cb1cbb364 100644 (file)
@@ -45,9 +45,6 @@ import com.google.common.util.concurrent.ListenableFuture;
 
 import org.opendaylight.vtn.manager.DataLinkHost;
 import org.opendaylight.vtn.manager.EthernetHost;
-import org.opendaylight.vtn.manager.PathCost;
-import org.opendaylight.vtn.manager.PathMap;
-import org.opendaylight.vtn.manager.PathPolicy;
 import org.opendaylight.vtn.manager.PortLocation;
 import org.opendaylight.vtn.manager.SwitchPort;
 import org.opendaylight.vtn.manager.VBridgeConfig;
@@ -207,6 +204,19 @@ public abstract class TestBase extends Assert {
         return i;
     }
 
+    /**
+     * Create a copy of the specified {@link Long} object.
+     *
+     * @param num  An {@link Long} object to be copied.
+     * @return     A copied boolean object.
+     */
+    protected static Long copy(Long num) {
+        if (num != null) {
+            num = new Long(num.longValue());
+        }
+        return num;
+    }
+
     /**
      * Create a copy of the specified {@link Node}.
      *
@@ -2150,94 +2160,6 @@ public abstract class TestBase extends Assert {
         }
     }
 
-    /**
-     * Common Method to create PathMap.
-     *  @return PathMap list object.
-     */
-    public List<PathMap> createPathMaps() {
-        List<PathMap> pathmaplist = new ArrayList<PathMap>();
-
-        try {
-            PathMap pathmap = null;
-            pathmaplist.add(null);
-            pathmaplist.add(pathmap);
-
-            // PathMap with ConditionName and PolicyId
-            for (String conditionName : TENANT_NAME) {
-                for (int policyId: createIntegers(-1, 4, false)) {
-                    pathmap = new PathMap(conditionName, policyId);
-                    pathmaplist.add(pathmap);
-                }
-            }
-
-            // PathMap with Index, ConditionName and PolicyId
-            pathmaplist.addAll(createPathMapsWithIndex());
-
-            // PathMap with Index, ConditionName, PolicyId, IdleTimeout and HardTimeout
-            pathmaplist.addAll(createPathMapsWithAllParameters());
-
-            return pathmaplist;
-        } catch (Exception ex) {
-            ex.printStackTrace();
-            return null;
-        }
-    }
-
-    /**
-     * Common Method to create PathMap with Index, ConditionName, PolicyId.
-     *  @return PathMap list object.
-     */
-    public List<PathMap> createPathMapsWithIndex() {
-        List<PathMap> pathmaplist = new ArrayList<PathMap>();
-
-        try {
-            // PathMap with Index, ConditionName and PolicyId
-            for (int policyId : createIntegers(1, 1, false)) {
-                for (int idx : createIntegers(5, 3, false)) {
-                    PathMap pathmap = new PathMap(idx, TENANT_NAME[0], policyId);
-                    pathmaplist.add(pathmap);
-                }
-            }
-
-            return pathmaplist;
-        } catch (Exception ex) {
-            ex.printStackTrace();
-            return null;
-        }
-    }
-
-    /**
-     * Common Method to create PathMap with Index, ConditionName, PolicyId, IdleTimeout and HardTimeout.
-     *  @return PathMap list object.
-     */
-    public List<PathMap> createPathMapsWithAllParameters() {
-        List<PathMap> pathmaplist = new ArrayList<PathMap>();
-
-        try {
-            PathMap pathmap = null;
-            // PathMap with Index, ConditionName, PolicyId, IdleTimeout and HardTimeout
-            for (String conditionName : TENANT_NAME) {
-                for (int policyId : createIntegers(0, 2, false)) {
-                    for (int idx : INDEX_ARRAY) {
-                        // VTenantConfig.idleTimeout List
-                        for (Integer idleTimeout: createIntegers(-1, 3, false)) {
-                            // VTenantConfig.hardTimeout List
-                            for (Integer hardTimeout: createIntegers(-1, 3, false)) {
-                                pathmap = new PathMap(idx, conditionName, policyId, idleTimeout, hardTimeout);
-                                pathmaplist.add(pathmap);
-                            }
-                        }
-                    }
-                }
-            }
-
-            return pathmaplist;
-        } catch (Exception ex) {
-            ex.printStackTrace();
-            return null;
-        }
-    }
-
     /**
      * Common Method to create VTenantImpl.
      *
@@ -2294,50 +2216,6 @@ public abstract class TestBase extends Assert {
         }
     }
 
-    /**
-     * Create lists of {@link PathPolicy} instances for test.
-     *
-     * @return A list of {@link PathPolicy} lists.
-     */
-    public List<PathPolicy> createPathPolicy() {
-        try {
-            int[] ids = {0, 1, 30};
-
-            ArrayList<List<PathCost>> list = new ArrayList<List<PathCost>>();
-            ArrayList<PathPolicy> pathPolicyList = new ArrayList<PathPolicy>();
-            list.add(new ArrayList<PathCost>());
-            ArrayList<PathCost> pathCostList = new ArrayList<PathCost>();
-
-            for (Node node : createNodes(2)) {
-                for (SwitchPort port : createSwitchPorts(2)) {
-                    for (long cost : COST) {
-                        PortLocation ploc = new PortLocation(node, port);
-                        PathCost pc = new PathCost(ploc, cost);
-                        pathCostList.add(pc);
-                        list.add(new ArrayList<PathCost>(pathCostList));
-                    }
-                }
-            }
-
-            PathPolicy ppolicy = null;
-            pathPolicyList.add(null);
-            pathPolicyList.add(ppolicy);
-
-            for (int id : ids) {
-                for (long cost : COST) {
-                    for (List<PathCost> pathCost : list) {
-                        ppolicy = new PathPolicy(cost, pathCost);
-                        pathPolicyList.add(ppolicy);
-                    }
-                }
-            }
-            return pathPolicyList;
-        } catch (Exception ex) {
-            //ex.printStackTrace();
-            return null;
-        }
-    }
-
     /**
      * Return the value of the field configured in the given object.
      *
index be77a4648987690e45e9724be7f50d67e41e493e..afc70f8363d1145e21f9bb77971dd8ce497e0016 100644 (file)
@@ -21,6 +21,9 @@ import java.util.Map;
 import org.opendaylight.vtn.manager.util.EtherAddress;
 import org.opendaylight.vtn.manager.util.Ip4Network;
 
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VnodeName;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VtnPortDesc;
+
 /**
  * {@code XmlDataType} describes the data type of the XML node value or
  * attribute.
@@ -128,6 +131,26 @@ public abstract class XmlDataType {
             "10.1.2.3/1/2/3",
         };
         map.put(Ip4Network.class, forIp4);
+
+        String[] forVnodeName = {
+            "",
+            "bad name",
+            "vtn-1",
+            "@vtn",
+            "_vtn",
+            "/vbridge",
+            "a123456789B123456789c123456789D1",
+        };
+        map.put(VnodeName.class, forVnodeName);
+
+        String[] forVtnPortDesc = {
+            "",
+            "bad port desc",
+            "openflow:1:1,",
+            "openflow:1:2",
+            ",1,eth1",
+        };
+        map.put(VtnPortDesc.class, forVtnPortDesc);
     }
 
     /**
index c740d5e3a2988c19ba06a56362c765fccfd14414..893264b05169338b6462f92e6be9164d4e6fc426 100644 (file)
@@ -8,16 +8,21 @@
 
 package org.opendaylight.vtn.manager.internal.routing;
 
+import static org.opendaylight.vtn.manager.internal.util.pathpolicy.PathPolicyUtilsTest.PATH_POLICY_MIN;
+import static org.opendaylight.vtn.manager.internal.util.pathpolicy.PathPolicyUtilsTest.PATH_POLICY_MAX;
+
 import org.junit.Test;
 
 import org.mockito.Mockito;
 
-import org.opendaylight.vtn.manager.PathPolicy;
-
 import org.opendaylight.vtn.manager.internal.VTNManagerProvider;
+import org.opendaylight.vtn.manager.internal.routing.xml.XmlPathPolicy;
 
 import org.opendaylight.vtn.manager.internal.TestBase;
 
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.vtn.path.policies.VtnPathPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.vtn.path.policies.VtnPathPolicyBuilder;
+
 /**
  * JUnit test for {@link PathPolicyChange}
  */
@@ -26,7 +31,7 @@ public class PathPolicyChangeTest extends TestBase {
      * Test case for the following methods.
      *
      * <ul>
-     *   <li>{@link PathPolicyChange#onUpdated(Integer,PathPolicy)}</li>
+     *   <li>{@link PathPolicyChange#onUpdated(Integer,XmlPathPolicy)}</li>
      *   <li>{@link PathPolicyChange#onRemoved(Integer)}</li>
      * </ul>
      */
@@ -35,12 +40,13 @@ public class PathPolicyChangeTest extends TestBase {
         VTNManagerProvider provider = Mockito.mock(VTNManagerProvider.class);
         TopologyGraph topo = new TopologyGraph(provider);
         PathPolicyChange change = new PathPolicyChange(topo);
-        Integer[] policies = {1, 2, 3};
-        for (Integer id: policies) {
-            PathPolicy pp = new PathPolicy(id, 0L, null);
-            assertEquals(true, change.onUpdated(id, pp));
-            assertEquals(false, change.onUpdated(id, pp));
-            assertEquals(false, change.onUpdated(id, pp));
+        for (int id = PATH_POLICY_MIN; id <= PATH_POLICY_MAX; id++) {
+            Integer pid = Integer.valueOf(id);
+            VtnPathPolicy vpp = new VtnPathPolicyBuilder().setId(pid).build();
+            XmlPathPolicy xpp = new XmlPathPolicy(vpp);
+            assertEquals(true, change.onUpdated(id, xpp));
+            assertEquals(false, change.onUpdated(id, xpp));
+            assertEquals(false, change.onUpdated(id, xpp));
             change.onRemoved(id);
         }
     }
diff --git a/manager/implementation/src/test/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathCostTest.java b/manager/implementation/src/test/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathCostTest.java
new file mode 100644 (file)
index 0000000..f92e04d
--- /dev/null
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2015 NEC Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vtn.manager.internal.routing.xml;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+
+import javax.xml.bind.Unmarshaller;
+
+import org.junit.Test;
+
+import org.opendaylight.vtn.manager.internal.TestBase;
+import org.opendaylight.vtn.manager.internal.XmlDataType;
+import org.opendaylight.vtn.manager.internal.XmlNode;
+import org.opendaylight.vtn.manager.internal.XmlValueType;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.VtnPathCostConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.vtn.path.policy.config.VtnPathCost;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.vtn.path.policy.config.VtnPathCostBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VtnPortDesc;
+
+/**
+ * JUnit test for {@link XmlPathCost}.
+ */
+public class XmlPathCostTest extends TestBase {
+    /**
+     * Root XML element name associated with {@link XmlPathCost} class.
+     */
+    private static final String  XML_ROOT = "vtn-path-cost";
+
+    /**
+     * Return a list of {@link XmlDataType} instances that specifies XML node
+     * types mapped to a {@link XmlPathCost} instance.
+     *
+     * @param name    The name of the target node.
+     * @param parent  Path to the parent node.
+     * @return  A list of {@link XmlDataType} instances.
+     */
+    public static List<XmlDataType> getXmlDataTypes(String name,
+                                                    String ... parent) {
+        List<XmlDataType> dlist = new ArrayList<>();
+        Collections.addAll(
+            dlist,
+            new XmlValueType("port-desc", VtnPortDesc.class).add(name).
+            prepend(parent),
+            new XmlValueType("cost", Long.class).add(name).prepend(parent));
+
+        return dlist;
+    }
+
+    /**
+     * Test case for {@link XmlPathCost#getImplementedInterface()}.
+     */
+    @Test
+    public void testGetImplementedInterface() {
+        XmlPathCost xpm = new XmlPathCost(new VtnPathCostBuilder().build());
+        for (int i = 0; i < 10; i++) {
+            assertEquals(VtnPathCostConfig.class,
+                         xpm.getImplementedInterface());
+        }
+    }
+
+    /**
+     * Test case for {@link XmlPathCost#getPortDesc()}.
+     */
+    @Test
+    public void testGetPortDesc() {
+        String[] descs = {
+            null,
+            "openflow:1,2,eth2",
+            "openflow:1,2,",
+            "openflow:1,,",
+            "openflow:9999:3,,eth3",
+            "unknown:1,abc,port-A",
+            "unknown:1,abc,",
+            "unknown:1,,port-A",
+            "unknown:1,,",
+        };
+
+        for (String desc: descs) {
+            VtnPortDesc vpdesc = (desc == null) ? null : new VtnPortDesc(desc);
+            VtnPathCost vpc = new VtnPathCostBuilder().
+                setPortDesc(vpdesc).build();
+            XmlPathCost xpc = new XmlPathCost(vpc);
+            assertEquals(vpdesc, xpc.getPortDesc());
+            assertEquals(null, xpc.getCost());
+        }
+    }
+
+    /**
+     * Test case for {@link XmlPathCost#getCost()}.
+     */
+    @Test
+    public void testGetCost() {
+        Long[] costs = {
+            null, 1L, 2L, 10L, 222L, 3333L, 5555555L, 1234567890123L,
+            99999999999999L, Long.MAX_VALUE,
+        };
+
+        for (Long cost: costs) {
+            VtnPathCost vpc = new VtnPathCostBuilder().
+                setCost(cost).build();
+            XmlPathCost xpc = new XmlPathCost(vpc);
+            assertEquals(null, xpc.getPortDesc());
+            assertEquals(cost, xpc.getCost());
+        }
+    }
+
+    /**
+     * Test case for {@link XmlPathCost#equals(Object)} and
+     * {@link XmlPathCost#hashCode()}.
+     */
+    @Test
+    public void testEquals() {
+        HashSet<Object> set = new HashSet<>();
+
+        String[] descs = {
+            null,
+            "openflow:1,2,eth2",
+            "openflow:1,2,",
+            "openflow:1,,",
+            "openflow:9999:3,,eth3",
+            "unknown:1,abc,port-A",
+            "unknown:1,abc,",
+            "unknown:1,,port-A",
+            "unknown:1,,",
+        };
+        Long[] costs = {
+            null, 1L, 2L, 10L, 999L, 12345L, 3141692L, 1234567890123L,
+            77777777777777L, Long.MAX_VALUE,
+        };
+
+        VtnPathCostBuilder bld1 = new VtnPathCostBuilder();
+        VtnPathCostBuilder bld2 = new VtnPathCostBuilder();
+        for (String desc: descs) {
+            if (desc == null) {
+                bld1.setPortDesc(null);
+                bld2.setPortDesc(null);
+            } else {
+                bld1.setPortDesc(new VtnPortDesc(desc));
+                bld2.setPortDesc(new VtnPortDesc(copy(desc)));
+            }
+
+            for (Long cost: costs) {
+                VtnPathCost vpc1 = bld1.setCost(cost).build();
+                VtnPathCost vpc2 = bld2.setCost(copy(cost)).build();
+                XmlPathCost xpc1 = new XmlPathCost(vpc1);
+                XmlPathCost xpc2 = new XmlPathCost(vpc2);
+                testEquals(set, xpc1, xpc2);
+            }
+        }
+
+        int expected = descs.length * costs.length;
+        assertEquals(expected, set.size());
+    }
+
+    /**
+     * Test case for {@link XmlPathCost#toString()}.
+     */
+    @Test
+    public void testToString() {
+        String[] descs = {
+            null,
+            "openflow:1,2,eth2",
+            "openflow:1,2,",
+            "openflow:1,,",
+            "openflow:9999:3,,eth3",
+            "unknown:1,abc,port-A",
+            "unknown:1,abc,",
+            "unknown:1,,port-A",
+            "unknown:1,,",
+        };
+        Long[] costs = {
+            null, 1L, 2L, 10L, 999L, 12345L, 3141692L, 1234567890123L,
+            77777777777777L, Long.MAX_VALUE,
+        };
+
+        VtnPathCostBuilder bld = new VtnPathCostBuilder();
+        for (String desc: descs) {
+            VtnPortDesc vpdesc = (desc == null) ? null : new VtnPortDesc(desc);
+            bld.setPortDesc(vpdesc);
+            for (Long cost: costs) {
+                VtnPathCost vpc = bld.setCost(cost).build();
+                XmlPathCost xpc = new XmlPathCost(vpc);
+                String expected = "vtn-path-cost[port=" + desc +
+                    ", cost=" + cost + "]";
+                assertEquals(expected, xpc.toString());
+            }
+        }
+    }
+
+    /**
+     * Test case for XML binding.
+     *
+     * @throws Exception  An error occurred.
+     */
+    @Test
+    public void testJAXB() throws Exception {
+        Class<XmlPathCost> type = XmlPathCost.class;
+        Unmarshaller um = createUnmarshaller(type);
+
+        // Normal case.
+        String[] descs = {
+            null,
+            "openflow:1,2,eth2",
+            "openflow:1,2,",
+            "openflow:1,,",
+            "openflow:9999:3,,eth3",
+            "unknown:1,abc,port-A",
+            "unknown:1,abc,",
+            "unknown:1,,port-A",
+            "unknown:1,,",
+        };
+        Long[] costs = {
+            null, Long.MIN_VALUE, -123456789012345L, -333333333333L,
+            0L, 1L, 2L, 10L, 999L, 12345L, 3141692L, 1234567890123L,
+            77777777777777L, Long.MAX_VALUE,
+        };
+
+        for (String desc: descs) {
+            VtnPortDesc vpdesc = (desc == null) ? null : new VtnPortDesc(desc);
+            for (Long cost: costs) {
+                XmlNode xnode = new XmlNode(XML_ROOT);
+                if (desc != null) {
+                    xnode.add(new XmlNode("port-desc", desc));
+                }
+                if (cost != null) {
+                    xnode.add(new XmlNode("cost", cost));
+                }
+
+                String xml = xnode.toString();
+                XmlPathCost xpc = unmarshal(um, xml, type);
+                assertEquals(vpdesc, xpc.getPortDesc());
+                assertEquals(cost, xpc.getCost());
+            }
+        }
+
+        // Ensure that broken values in XML can be detected.
+        jaxbErrorTest(um, type, getXmlDataTypes(XML_ROOT));
+    }
+}
diff --git a/manager/implementation/src/test/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathMapTest.java b/manager/implementation/src/test/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathMapTest.java
new file mode 100644 (file)
index 0000000..4693d2c
--- /dev/null
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2015 NEC Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vtn.manager.internal.routing.xml;
+
+import static org.opendaylight.vtn.manager.internal.util.pathpolicy.PathPolicyUtilsTest.PATH_POLICY_MIN;
+import static org.opendaylight.vtn.manager.internal.util.pathpolicy.PathPolicyUtilsTest.PATH_POLICY_MAX;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+
+import javax.xml.bind.Unmarshaller;
+
+import org.junit.Test;
+
+import org.opendaylight.vtn.manager.internal.TestBase;
+import org.opendaylight.vtn.manager.internal.XmlDataType;
+import org.opendaylight.vtn.manager.internal.XmlNode;
+import org.opendaylight.vtn.manager.internal.XmlValueType;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathmap.rev150328.VtnPathMapConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathmap.rev150328.vtn.path.map.list.VtnPathMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathmap.rev150328.vtn.path.map.list.VtnPathMapBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VnodeName;
+
+/**
+ * JUnit test for {@link XmlPathMap}.
+ */
+public class XmlPathMapTest extends TestBase {
+    /**
+     * Root XML element name associated with {@link XmlPathMap} class.
+     */
+    private static final String  XML_ROOT = "vtn-path-map";
+
+    /**
+     * Return a list of {@link XmlDataType} instances that specifies XML node
+     * types mapped to a {@link XmlPathMap} instance.
+     *
+     * @param name    The name of the target node.
+     * @param parent  Path to the parent node.
+     * @return  A list of {@link XmlDataType} instances.
+     */
+    public static List<XmlDataType> getXmlDataTypes(String name,
+                                                    String ... parent) {
+        List<XmlDataType> dlist = new ArrayList<>();
+        Collections.addAll(
+            dlist,
+            new XmlValueType("index", Integer.class).add(name).prepend(parent),
+            new XmlValueType("condition", VnodeName.class).add(name).
+            prepend(parent),
+            new XmlValueType("policy", Integer.class).add(name).prepend(parent),
+            new XmlValueType("idle-timeout", Integer.class).add(name).
+            prepend(parent),
+            new XmlValueType("hard-timeout", Integer.class).add(name).
+            prepend(parent));
+
+        return dlist;
+    }
+
+    /**
+     * Test case for {@link XmlPathMap#getImplementedInterface()}.
+     */
+    @Test
+    public void testGetImplementedInterface() {
+        XmlPathMap xpm = new XmlPathMap(new VtnPathMapBuilder().build());
+        for (int i = 0; i < 10; i++) {
+            assertEquals(VtnPathMapConfig.class,
+                         xpm.getImplementedInterface());
+        }
+    }
+
+    /**
+     * Test case for {@link XmlPathMap#getIndex()}.
+     */
+    @Test
+    public void testGetIndex() {
+        Integer[] indices = {
+            null, 1, 2, 10, 333, 5555, 10000, 32767, 32768, 40000, 55555,
+            65534, 65535,
+        };
+
+        for (Integer index: indices) {
+            VtnPathMap vpm = new VtnPathMapBuilder().
+                setIndex(index).build();
+            XmlPathMap xpm = new XmlPathMap(vpm);
+            assertEquals(index, xpm.getIndex());
+            assertEquals(null, xpm.getCondition());
+            assertEquals(null, xpm.getPolicy());
+            assertEquals(null, xpm.getIdleTimeout());
+            assertEquals(null, xpm.getHardTimeout());
+        }
+    }
+
+    /**
+     * Test case for {@link XmlPathMap#getCondition()}.
+     */
+    @Test
+    public void testGetCondition() {
+        String[] conds = {
+            null,
+            "a",
+            "AB",
+            "abcde",
+            "0",
+            "01",
+            "0123456789",
+            "a123456789B123456789c123456789D",
+            "cond_1",
+            "cond_2",
+            "Condition_3",
+        };
+
+        for (String cond: conds) {
+            VnodeName vcond = (cond == null) ? null : new VnodeName(cond);
+            VtnPathMap vpm = new VtnPathMapBuilder().
+                setCondition(vcond).build();
+            XmlPathMap xpm = new XmlPathMap(vpm);
+            assertEquals(null, xpm.getIndex());
+            assertEquals(vcond, xpm.getCondition());
+            assertEquals(null, xpm.getPolicy());
+            assertEquals(null, xpm.getIdleTimeout());
+            assertEquals(null, xpm.getHardTimeout());
+        }
+    }
+
+    /**
+     * Test case for {@link XmlPathMap#getPolicy()}.
+     */
+    @Test
+    public void testGetPolicy() {
+        List<Integer> ids = new ArrayList<>();
+        ids.add(null);
+        for (int id = PATH_POLICY_MIN; id <= PATH_POLICY_MAX; id++) {
+            ids.add(id);
+        }
+
+        for (Integer pid: ids) {
+            VtnPathMap vpm = new VtnPathMapBuilder().
+                setPolicy(pid).build();
+            XmlPathMap xpm = new XmlPathMap(vpm);
+            assertEquals(null, xpm.getIndex());
+            assertEquals(null, xpm.getCondition());
+            assertEquals(pid, xpm.getPolicy());
+            assertEquals(null, xpm.getIdleTimeout());
+            assertEquals(null, xpm.getHardTimeout());
+        }
+    }
+
+    /**
+     * Test case for {@link XmlPathMap#getIdleTimeout()}.
+     */
+    @Test
+    public void testGetIdleTimeout() {
+        Integer[] timeouts = {
+            null, 0, 1, 2, 10, 222, 3333, 10000, 32767, 32768, 44444,
+            55555, 60000, 65534, 65535,
+        };
+
+        for (Integer timeout: timeouts) {
+            VtnPathMap vpm = new VtnPathMapBuilder().
+                setIdleTimeout(timeout).build();
+            XmlPathMap xpm = new XmlPathMap(vpm);
+            assertEquals(null, xpm.getIndex());
+            assertEquals(null, xpm.getCondition());
+            assertEquals(null, xpm.getPolicy());
+            assertEquals(timeout, xpm.getIdleTimeout());
+            assertEquals(null, xpm.getHardTimeout());
+        }
+    }
+
+    /**
+     * Test case for {@link XmlPathMap#getHardTimeout()}.
+     */
+    @Test
+    public void testGetHardTimeout() {
+        Integer[] timeouts = {
+            null, 0, 1, 2, 10, 222, 3333, 10000, 32767, 32768, 44444,
+            55555, 60000, 65534, 65535,
+        };
+
+        for (Integer timeout: timeouts) {
+            VtnPathMap vpm = new VtnPathMapBuilder().
+                setHardTimeout(timeout).build();
+            XmlPathMap xpm = new XmlPathMap(vpm);
+            assertEquals(null, xpm.getIndex());
+            assertEquals(null, xpm.getCondition());
+            assertEquals(null, xpm.getPolicy());
+            assertEquals(null, xpm.getIdleTimeout());
+            assertEquals(timeout, xpm.getHardTimeout());
+        }
+    }
+
+    /**
+     * Test case for {@link XmlPathMap#equals(Object)} and
+     * {@link XmlPathMap#hashCode()}.
+     */
+    @Test
+    public void testEquals() {
+        HashSet<Object> set = new HashSet<>();
+
+        Integer[] indices = {
+            null, 333, 65535,
+        };
+        String[] conds = {
+            null, "cond", "cond_1",
+        };
+        Integer[] timeouts = {
+            null, 123, 65535,
+        };
+
+        List<Integer> ids = new ArrayList<>();
+        ids.add(null);
+        for (int id = PATH_POLICY_MIN; id <= PATH_POLICY_MAX; id++) {
+            ids.add(id);
+        }
+
+        VtnPathMapBuilder bld1 = new VtnPathMapBuilder();
+        VtnPathMapBuilder bld2 = new VtnPathMapBuilder();
+        for (String cond: conds) {
+            if (cond == null) {
+                bld1.setCondition(null);
+                bld2.setCondition(null);
+            } else {
+                bld1.setCondition(new VnodeName(cond));
+                bld2.setCondition(new VnodeName(copy(cond)));
+            }
+
+            for (Integer index: indices) {
+                bld1.setIndex(index);
+                bld2.setIndex(copy(index));
+                for (Integer pid: ids) {
+                    bld1.setPolicy(pid);
+                    bld2.setPolicy(copy(pid));
+                    for (Integer idle: timeouts) {
+                        bld1.setIdleTimeout(idle);
+                        bld2.setIdleTimeout(copy(idle));
+                        for (Integer hard: timeouts) {
+                            VtnPathMap vpm1 =
+                                bld1.setHardTimeout(hard).build();
+                            VtnPathMap vpm2 =
+                                bld2.setHardTimeout(copy(hard)).build();
+                            XmlPathMap xpm1 = new XmlPathMap(vpm1);
+                            XmlPathMap xpm2 = new XmlPathMap(vpm2);
+                            testEquals(set, xpm1, xpm2);
+                        }
+                    }
+                }
+            }
+        }
+
+        int expected = indices.length * conds.length * timeouts.length *
+            timeouts.length * ids.size();
+        assertEquals(expected, set.size());
+    }
+
+    /**
+     * Test case for {@link XmlPathMap#toString()}.
+     */
+    @Test
+    public void testToString() {
+        Integer[] indices = {
+            null, 11, 65535,
+        };
+        String[] conds = {
+            null, "cond", "cond_1",
+        };
+        Integer[] idles = {
+            null, 234, 65535,
+        };
+        Integer[] hards = {
+            null, 0, 33333,
+        };
+
+        List<Integer> ids = new ArrayList<>();
+        ids.add(null);
+        for (int id = PATH_POLICY_MIN; id <= PATH_POLICY_MAX; id++) {
+            ids.add(id);
+        }
+
+        VtnPathMapBuilder bld = new VtnPathMapBuilder();
+        for (String cond: conds) {
+            VnodeName vcond = (cond == null) ? null : new VnodeName(cond);
+            bld.setCondition(vcond);
+            for (Integer index: indices) {
+                bld.setIndex(index);
+                for (Integer pid: ids) {
+                    bld.setPolicy(pid);
+                    for (Integer idle: idles) {
+                        bld.setIdleTimeout(idle);
+                        for (Integer hard: hards) {
+                            VtnPathMap vpm = bld.setHardTimeout(hard).build();
+                            XmlPathMap xpm = new XmlPathMap(vpm);
+                            String expected = "vtn-path-map[index=" + index +
+                                ", condition=" + cond + ", policy=" + pid +
+                                ", idle-timeout=" + idle +
+                                ", hard-timeout=" + hard + "]";
+                            assertEquals(expected, xpm.toString());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Test case for XML binding.
+     *
+     * @throws Exception  An error occurred.
+     */
+    @Test
+    public void testJAXB() throws Exception {
+        Class<XmlPathMap> type = XmlPathMap.class;
+        Unmarshaller um = createUnmarshaller(type);
+
+        // Normal case.
+        Integer[] indices = {
+            null, 11, 65535,
+        };
+        String[] conds = {
+            null, "cond", "cond_1",
+        };
+        Integer[] idles = {
+            null, 234, 65535,
+        };
+        Integer[] hards = {
+            null, 0, 33333,
+        };
+
+        List<Integer> ids = new ArrayList<>();
+        ids.add(null);
+        for (int id = PATH_POLICY_MIN; id <= PATH_POLICY_MAX; id++) {
+            ids.add(id);
+        }
+
+        for (String cond: conds) {
+            VnodeName vcond = (cond == null) ? null : new VnodeName(cond);
+            for (Integer index: indices) {
+                for (Integer pid: ids) {
+                    for (Integer idle: idles) {
+                        for (Integer hard: hards) {
+                            XmlNode xnode = new XmlNode(XML_ROOT);
+                            if (index != null) {
+                                xnode.add(new XmlNode("index", index));
+                            }
+                            if (cond != null) {
+                                xnode.add(new XmlNode("condition", cond));
+                            }
+                            if (pid != null) {
+                                xnode.add(new XmlNode("policy", pid));
+                            }
+                            if (idle != null) {
+                                xnode.add(new XmlNode("idle-timeout", idle));
+                            }
+                            if (hard != null) {
+                                xnode.add(new XmlNode("hard-timeout", hard));
+                            }
+
+                            String xml = xnode.toString();
+                            XmlPathMap xpm = unmarshal(um, xml, type);
+                            assertEquals(index, xpm.getIndex());
+                            assertEquals(vcond, xpm.getCondition());
+                            assertEquals(pid, xpm.getPolicy());
+                            assertEquals(idle, xpm.getIdleTimeout());
+                            assertEquals(hard, xpm.getHardTimeout());
+                        }
+                    }
+                }
+            }
+        }
+
+        // Ensure that broken values in XML can be detected.
+        jaxbErrorTest(um, type, getXmlDataTypes(XML_ROOT));
+    }
+}
diff --git a/manager/implementation/src/test/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathPolicyTest.java b/manager/implementation/src/test/java/org/opendaylight/vtn/manager/internal/routing/xml/XmlPathPolicyTest.java
new file mode 100644 (file)
index 0000000..f282d13
--- /dev/null
@@ -0,0 +1,382 @@
+/*
+ * Copyright (c) 2015 NEC Corporation. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.vtn.manager.internal.routing.xml;
+
+import static org.opendaylight.vtn.manager.internal.util.pathpolicy.PathPolicyUtilsTest.PATH_POLICY_MIN;
+import static org.opendaylight.vtn.manager.internal.util.pathpolicy.PathPolicyUtilsTest.PATH_POLICY_MAX;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+
+import javax.xml.bind.Unmarshaller;
+
+import org.junit.Test;
+
+import org.opendaylight.vtn.manager.internal.TestBase;
+import org.opendaylight.vtn.manager.internal.XmlDataType;
+import org.opendaylight.vtn.manager.internal.XmlNode;
+import org.opendaylight.vtn.manager.internal.XmlValueType;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.VtnPathPolicyConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.vtn.path.policies.VtnPathPolicy;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.vtn.path.policies.VtnPathPolicyBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.vtn.path.policy.config.VtnPathCost;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.pathpolicy.rev150209.vtn.path.policy.config.VtnPathCostBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vtn.types.rev150209.VtnPortDesc;
+
+/**
+ * JUnit test for {@link XmlPathPolicy}.
+ */
+public class XmlPathPolicyTest extends TestBase {
+    /**
+     * Root XML element name associated with {@link XmlPathPolicy} class.
+     */
+    private static final String  XML_ROOT = "vtn-path-policy";
+
+    /**
+     * Return a list of {@link XmlDataType} instances that specifies XML node
+     * types mapped to a {@link XmlPathPolicy} instance.
+     *
+     * @param name    The name of the target node.
+     * @param parent  Path to the parent node.
+     * @return  A list of {@link XmlDataType} instances.
+     */
+    public static List<XmlDataType> getXmlDataTypes(String name,
+                                                    String ... parent) {
+        String[] p = XmlDataType.addPath(
+            "vtn-path-costs", XmlDataType.addPath(name, parent));
+        List<XmlDataType> dlist = new ArrayList<>();
+        Collections.addAll(
+            dlist,
+            new XmlValueType("id", Integer.class).add(name).prepend(parent),
+            new XmlValueType("default", Long.class).add(name).prepend(parent));
+        dlist.addAll(XmlPathCostTest.getXmlDataTypes("vtn-path-cost", p));
+
+        return dlist;
+    }
+
+    /**
+     * Test case for {@link XmlPathPolicy#getImplementedInterface()}.
+     */
+    @Test
+    public void testGetImplementedInterface() {
+        XmlPathPolicy xpp = new XmlPathPolicy(
+            new VtnPathPolicyBuilder().build());
+        for (int i = 0; i < 10; i++) {
+            assertEquals(VtnPathPolicyConfig.class,
+                         xpp.getImplementedInterface());
+        }
+    }
+
+    /**
+     * Test case for {@link XmlPathPolicy#getId()}.
+     */
+    @Test
+    public void testGetId() {
+        List<Integer> ids = new ArrayList<>();
+        ids.add(null);
+        for (int id = PATH_POLICY_MIN; id <= PATH_POLICY_MAX; id++) {
+            ids.add(id);
+        }
+
+        for (Integer id: ids) {
+            VtnPathPolicy vpp = new VtnPathPolicyBuilder().
+                setId(id).build();
+            XmlPathPolicy xpp = new XmlPathPolicy(vpp);
+            assertEquals(id, xpp.getId());
+            assertEquals(null, xpp.getDefaultCost());
+            assertEquals(null, xpp.getVtnPathCost());
+        }
+    }
+
+    /**
+     * Test case for {@link XmlPathPolicy#getDefaultCost()}.
+     */
+    @Test
+    public void testGetDefaultCost() {
+        Long[] costs = {
+            null, 0L, 1L, 2L, 10L, 222L, 3333L, 5555555L, 1234567890123L,
+            99999999999999L, Long.MAX_VALUE,
+        };
+
+        for (Long cost: costs) {
+            VtnPathPolicy vpp = new VtnPathPolicyBuilder().
+                setDefaultCost(cost).build();
+            XmlPathPolicy xpp = new XmlPathPolicy(vpp);
+            assertEquals(null, xpp.getId());
+            assertEquals(cost, xpp.getDefaultCost());
+            assertEquals(null, xpp.getVtnPathCost());
+        }
+    }
+
+    /**
+     * Test case for {@link XmlPathPolicy#getVtnPathCost()}.
+     */
+    @Test
+    public void testGetVtnPathCost() {
+        // Null.
+        XmlPathPolicy xpp = new XmlPathPolicy(
+            new VtnPathPolicyBuilder().build());
+        assertEquals(null, xpp.getId());
+        assertEquals(null, xpp.getDefaultCost());
+        assertEquals(null, xpp.getVtnPathCost());
+
+        // Empty list.
+        List<VtnPathCost> vpcosts = new ArrayList<>();
+        xpp = new XmlPathPolicy(
+            new VtnPathPolicyBuilder().setVtnPathCost(vpcosts).build());
+        assertEquals(null, xpp.getId());
+        assertEquals(null, xpp.getDefaultCost());
+        assertEquals(null, xpp.getVtnPathCost());
+
+        String[] descs = {
+            null,
+            "openflow:1,2,eth2",
+            "openflow:1,2,",
+            "openflow:1,,",
+            "openflow:9999:3,,eth3",
+            "unknown:1,abc,port-A",
+            "unknown:1,abc,",
+            "unknown:1,,port-A",
+            "unknown:1,,",
+        };
+        Long[] costs = {
+            null, 1L, 2L, 10L, 999L, 12345L, 3141692L, 1234567890123L,
+            77777777777777L, Long.MAX_VALUE,
+        };
+
+        VtnPathPolicyBuilder bld = new VtnPathPolicyBuilder();
+        VtnPathCostBuilder cbld = new VtnPathCostBuilder();
+        for (String desc: descs) {
+            VtnPortDesc vpdesc = (desc == null) ? null : new VtnPortDesc(desc);
+            cbld.setPortDesc(vpdesc);
+            for (Long cost: costs) {
+                vpcosts.add(cbld.setCost(cost).build());
+                VtnPathPolicy vpp = bld.setVtnPathCost(vpcosts).build();
+                xpp = new XmlPathPolicy(vpp);
+                assertEquals(null, xpp.getId());
+                assertEquals(null, xpp.getDefaultCost());
+                assertEquals(vpcosts, xpp.getVtnPathCost());
+            }
+        }
+    }
+
+    /**
+     * Test case for {@link XmlPathPolicy#equals(Object)} and
+     * {@link XmlPathPolicy#hashCode()}.
+     */
+    @Test
+    public void testEquals() {
+        HashSet<Object> set = new HashSet<>();
+
+        List<Integer> ids = new ArrayList<>();
+        ids.add(null);
+        for (int id = PATH_POLICY_MIN; id <= PATH_POLICY_MAX; id++) {
+            ids.add(id);
+        }
+
+        Long[] defCosts = {
+            null, 0L, 10L, 5555555L, 1234567890123L, Long.MAX_VALUE,
+        };
+        String[] descs = {
+            null,
+            "openflow:1,2,eth2",
+            "openflow:1,,",
+            "unknown:1,,port-1",
+        };
+        Long[] costs = {
+            null, 1L, 12345678L, Long.MAX_VALUE,
+        };
+
+        List<VtnPathCost> vpcosts = new ArrayList<>();
+        VtnPathCostBuilder cbld = new VtnPathCostBuilder();
+        for (String desc: descs) {
+            VtnPortDesc vpdesc = (desc == null) ? null : new VtnPortDesc(desc);
+            cbld.setPortDesc(vpdesc);
+            for (Long cost: costs) {
+                vpcosts.add(cbld.setCost(cost).build());
+            }
+        }
+        List<List<VtnPathCost>> vpcLists = Arrays.asList(
+            (List<VtnPathCost>)null,
+            Collections.singletonList(vpcosts.get(0)),
+            vpcosts);
+
+        VtnPathPolicyBuilder bld1 = new VtnPathPolicyBuilder();
+        VtnPathPolicyBuilder bld2 = new VtnPathPolicyBuilder();
+        for (Integer id: ids) {
+            bld1.setId(id);
+            bld2.setId(copy(id));
+            for (Long cost: defCosts) {
+                bld1.setDefaultCost(cost);
+                bld2.setDefaultCost(copy(cost));
+                for (List<VtnPathCost> vpcs1: vpcLists) {
+                    List<VtnPathCost> vpcs2 = (vpcs1 == null)
+                        ? null
+                        : new ArrayList<>(vpcs1);
+                    VtnPathPolicy vpp1 = bld1.setVtnPathCost(vpcs1).build();
+                    VtnPathPolicy vpp2 = bld2.setVtnPathCost(vpcs2).build();
+                    XmlPathPolicy xpp1 = new XmlPathPolicy(vpp1);
+                    XmlPathPolicy xpp2 = new XmlPathPolicy(vpp2);
+                    testEquals(set, xpp1, xpp2);
+                }
+            }
+        }
+
+        int expected = ids.size() * defCosts.length * vpcLists.size();
+        assertEquals(expected, set.size());
+    }
+
+    /**
+     * Test case for {@link XmlPathPolicy#toString()}.
+     */
+    @Test
+    public void testToString() {
+        List<Integer> ids = new ArrayList<>();
+        ids.add(null);
+        for (int id = PATH_POLICY_MIN; id <= PATH_POLICY_MAX; id++) {
+            ids.add(id);
+        }
+
+        Long[] defCosts = {
+            null, 0L, 10L, 5555555L, 1234567890123L, Long.MAX_VALUE,
+        };
+        String[] descs = {
+            null,
+            "openflow:1,2,eth2",
+            "openflow:1,,",
+            "openflow:9999:3,,eth3",
+            "unknown:1,abc,",
+            "unknown:1,,",
+        };
+        Long[] costs = {
+            null, 1L, 11L, 8888888L, 12345678901234L, Long.MAX_VALUE,
+        };
+
+        List<VtnPathCost> vpcosts = new ArrayList<>();
+        VtnPathCostBuilder cbld = new VtnPathCostBuilder();
+        for (String desc: descs) {
+            VtnPortDesc vpdesc = (desc == null) ? null : new VtnPortDesc(desc);
+            cbld.setPortDesc(vpdesc);
+            for (Long cost: costs) {
+                vpcosts.add(cbld.setCost(cost).build());
+            }
+        }
+
+        VtnPathPolicyBuilder bld = new VtnPathPolicyBuilder();
+        List<VtnPathCost> vpcs = new ArrayList<>();
+        List<XmlPathCost> xpcs = new ArrayList<>();
+        for (Integer id: ids) {
+            bld.setId(id);
+            for (Long cost: defCosts) {
+                bld.setDefaultCost(cost);
+                for (VtnPathCost vpc: vpcosts) {
+                    vpcs.add(vpc);
+                    xpcs.add(new XmlPathCost(vpc));
+                    VtnPathPolicy vpp = bld.setVtnPathCost(vpcs).build();
+                    XmlPathPolicy xpp = new XmlPathPolicy(vpp);
+                    String expected = "vtn-path-policy[id=" + id +
+                        ", default=" + cost + ", costs=" + xpcs + "]";
+                }
+            }
+        }
+    }
+
+    /**
+     * Test case for XML binding.
+     *
+     * @throws Exception  An error occurred.
+     */
+    @Test
+    public void testJAXB() throws Exception {
+        Class<XmlPathPolicy> type = XmlPathPolicy.class;
+        Unmarshaller um = createUnmarshaller(type);
+
+        // Normal case.
+        List<Integer> ids = new ArrayList<>();
+        ids.add(null);
+        for (int id = PATH_POLICY_MIN; id <= PATH_POLICY_MAX; id++) {
+            ids.add(id);
+        }
+
+        Long[] defCosts = {
+            null, 0L, 10L, 5555555L, 1234567890123L, Long.MAX_VALUE,
+        };
+        String[] descs = {
+            null,
+            "openflow:2,10,eth10",
+            "openflow:5,,",
+            "openflow:9999:1,,eth1",
+            "unknown:33,abc,",
+            "unknown:1,,",
+        };
+        Long[] costs = {
+            null, 1L, 11L, 8888888L, 12345678901234L, Long.MAX_VALUE,
+        };
+
+        List<VtnPathCost> vpcosts = new ArrayList<>();
+        VtnPathCostBuilder cbld = new VtnPathCostBuilder();
+        for (String desc: descs) {
+            VtnPortDesc vpdesc = (desc == null) ? null : new VtnPortDesc(desc);
+            cbld.setPortDesc(vpdesc);
+            for (Long cost: costs) {
+                vpcosts.add(cbld.setCost(cost).build());
+            }
+        }
+
+        List<List<VtnPathCost>> vpcLists = Arrays.asList(
+            (List<VtnPathCost>)null, Collections.<VtnPathCost>emptyList(),
+            vpcosts);
+
+        for (Integer id: ids) {
+            for (Long cost: defCosts) {
+                for (List<VtnPathCost> vpcs: vpcLists) {
+                    XmlNode xnode = new XmlNode(XML_ROOT);
+                    if (id != null) {
+                        xnode.add(new XmlNode("id", id));
+                    }
+                    if (cost != null) {
+                        xnode.add(new XmlNode("default", cost));
+                    }
+                    if (vpcs != null) {
+                        XmlNode xlist = new XmlNode("vtn-path-costs");
+                        for (VtnPathCost vpc: vpcs) {
+                            XmlNode xcost = new XmlNode("vtn-path-cost");
+                            VtnPortDesc vpdesc = vpc.getPortDesc();
+                            if (vpdesc != null) {
+                                String desc = vpdesc.getValue();
+                                xcost.add(new XmlNode("port-desc", desc));
+                            }
+
+                            Long c = vpc.getCost();
+                            if (c != null) {
+                                xcost.add(new XmlNode("cost", c));
+                            }
+                            xlist.add(xcost);
+                        }
+
+                        xnode.add(xlist);
+                    }
+
+                    String xml = xnode.toString();
+                    XmlPathPolicy xpp = unmarshal(um, xml, type);
+                    assertEquals(id, xpp.getId());
+                    assertEquals(cost, xpp.getDefaultCost());
+                    assertEquals(vpcs, xpp.getVtnPathCost());
+                }
+            }
+        }
+
+        // Ensure that broken values in XML can be detected.
+        jaxbErrorTest(um, type, getXmlDataTypes(XML_ROOT));
+    }
+}
index 119e983e7b2d7f4261cf067805e7ec9b2cbf045d..0cd5236f2937c8128a994f72c5f55983e280803c 100644 (file)
@@ -82,7 +82,7 @@
       <artifactId>org.osgi.core</artifactId>
     </dependency>
 
-    <!-- OpenDaylight MD-SAL -->
+    <!-- OpenDaylight controller (MD-SAL) -->
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-binding-it</artifactId>
@@ -97,7 +97,7 @@
       <artifactId>model-topology</artifactId>
     </dependency>
 
-    <!-- OpenDaylight AD-SAL -->
+    <!-- OpenDaylight controller (AD-SAL) -->
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal</artifactId>
       <artifactId>com.sun.jersey.jersey-servlet</artifactId>
     </dependency>
 
-    <!-- OpenDaylight YANG Tools -->
+    <!-- OpenDaylight MD-SAL -->
     <dependency>
       <groupId>org.opendaylight.mdsal.model</groupId>
       <artifactId>ietf-topology</artifactId>
index c88ba82a09015ee055cd4c62421ff517963e4ff1..c6f1b9d96dc8b221e540a0a16e980ed8aa8718c7 100644 (file)
@@ -74,7 +74,7 @@
       <artifactId>org.osgi.core</artifactId>
     </dependency>
 
-    <!-- OpenDaylight MD-SAL -->
+    <!-- OpenDaylight controller (MD-SAL) -->
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>sal-common-api</artifactId>
       <groupId>org.opendaylight.yangtools</groupId>
       <artifactId>concepts</artifactId>
     </dependency>
+
+    <!-- OpenDaylight MD-SAL -->
     <dependency>
       <groupId>org.opendaylight.mdsal</groupId>
       <artifactId>yang-binding</artifactId>
index da62c345e8197bee2b4b721943f135c969a5c58c..fa5a41d5bd6b72be038dac71053fa662486469ce 100644 (file)
   </build>
 
   <dependencies>
-    <!-- OpenDaylight MD-SAL -->
+    <!-- OpenDaylight controller (MD-SAL) -->
     <dependency>
       <groupId>org.opendaylight.controller.model</groupId>
       <artifactId>model-inventory</artifactId>
     </dependency>
 
-    <!-- OpenDaylight YANG Tools -->
+    <!-- OpenDaylight MD-SAL -->
     <dependency>
       <groupId>org.opendaylight.mdsal.model</groupId>
       <artifactId>ietf-yang-types</artifactId>