Eliminate RouteDistinguisherBuilder 34/105634/2
authorRobert Varga <robert.varga@pantheon.tech>
Sun, 23 Apr 2023 22:23:54 +0000 (00:23 +0200)
committerRobert Varga <robert.varga@pantheon.tech>
Sun, 23 Apr 2023 22:54:38 +0000 (00:54 +0200)
This class is in a legacy place and its testing interactions with
RouteDistinguisherUtil are weird.

Integrate getDefaultInstance() into RouteDistringuisherUtil, adjusting
tests to properly perform assertions.

Also clean up API surface, so that things do not get confused.

Change-Id: I01d53086d8b7d49709a0da2d4cf287d62bf614c2
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
bgp/concepts/src/main/java/org/opendaylight/bgp/concepts/RouteDistinguisherUtil.java
bgp/concepts/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/bgp/types/rev200120/RouteDistinguisherBuilder.java [deleted file]
bgp/concepts/src/test/java/org/opendaylight/bgp/concepts/RouteDistinguisherUtilTest.java
bgp/extensions/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/nlri/NlriModelUtil.java
bgp/extensions/evpn/src/test/java/org/opendaylight/protocol/bgp/evpn/impl/EvpnTestUtil.java
bgp/extensions/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/FlowspecL3vpnIpv4NlriParserTest.java
bgp/extensions/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/unicast/ipv4/VpnIpv4NlriParserTest.java
bgp/extensions/l3vpn/src/test/java/org/opendaylight/protocol/bgp/l3vpn/unicast/ipv6/VpnIpv6NlriParserTest.java
bgp/extensions/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/impl/nlri/LinkstateNlriParser.java
bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/AbstractRIBSupport.java
bgp/topology-provider/src/test/java/org/opendaylight/bgpcep/bgp/topology/provider/UriBuilderTest.java

index 0d7510bd5775ecbfc776db6a6f6f9941e58dc202..a48f242a024c6c5b2989740cc7f1177ca6de2d62 100644 (file)
@@ -12,6 +12,7 @@ import static java.util.Objects.requireNonNull;
 
 import com.google.common.annotations.VisibleForTesting;
 import io.netty.buffer.ByteBuf;
+import java.util.regex.Pattern;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.Nullable;
 import org.opendaylight.protocol.util.Ipv4Util;
@@ -20,7 +21,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.type
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RdIpv4;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RdTwoOctetAs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisher;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisherBuilder;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.slf4j.Logger;
@@ -42,6 +42,45 @@ public final class RouteDistinguisherUtil {
     private static final int RD_IPV4     = 1;
     private static final int RD_AS_4BYTE = 2;
 
+    // Patterns for parsing String representation
+    private static final Pattern AS_2BYTE_PATTERN =
+        Pattern.compile("0:"
+            + "([0-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|"
+            + "[1-5][0-9][0-9][0-9][0-9]|6[0-4][0-9][0-9][0-9]|"
+            + "65[0-4][0-9][0-9]|655[0-2][0-9]|6553[0-5])"
+            + ":"
+            + "([0-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|"
+            + "[1-9][0-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9][0-9]|"
+            + "[1-9][0-9][0-9][0-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|"
+            + "[1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|[1-3][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|"
+            + "4[0-1][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|42[0-8][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|"
+            + "429[0-3][0-9][0-9][0-9][0-9][0-9][0-9]|4294[0-8][0-9][0-9][0-9][0-9][0-9]|"
+            + "42949[0-5][0-9][0-9][0-9][0-9]|429496[0-6][0-9][0-9][0-9]|4294967[0-1][0-9][0-9]|"
+            + "42949672[0-8][0-9]|429496729[0-5])");
+
+    private static final Pattern IPV4_PATTERN =
+        Pattern.compile("((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}"
+            + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))"
+            + ":"
+            + "([0-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|"
+            + "[1-5][0-9][0-9][0-9][0-9]|6[0-4][0-9][0-9][0-9]|"
+            + "65[0-4][0-9][0-9]|655[0-2][0-9]|6553[0-5])");
+
+    private static final Pattern AS_4BYTE_PATTERN =
+        Pattern.compile("([0-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|"
+            + "[1-9][0-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9][0-9]|"
+            + "[1-9][0-9][0-9][0-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|"
+            + "[1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|[1-3][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|"
+            + "4[0-1][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|42[0-8][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|"
+            + "429[0-3][0-9][0-9][0-9][0-9][0-9][0-9]|4294[0-8][0-9][0-9][0-9][0-9][0-9]|"
+            + "42949[0-5][0-9][0-9][0-9][0-9]|429496[0-6][0-9][0-9][0-9]|4294967[0-1][0-9][0-9]|"
+            + "42949672[0-8][0-9]|429496729[0-5])"
+            + ":"
+            + "([0-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|"
+            + "[1-5][0-9][0-9][0-9][0-9]|6[0-4][0-9][0-9][0-9]|"
+            + "65[0-4][0-9][0-9]|655[0-2][0-9]|6553[0-5])");
+
+
     private RouteDistinguisherUtil() {
         // Hidden on purpose
     }
@@ -146,24 +185,21 @@ public final class RouteDistinguisherUtil {
         }
     }
 
-    public static @Nullable RouteDistinguisher parseRouteDistinguisher(final String str) {
-        return str == null ? null : RouteDistinguisherBuilder.getDefaultInstance(str);
-    }
-
-    public static @Nullable RouteDistinguisher parseRouteDistinguisher(final Object obj) {
-        if (obj instanceof String str) {
-            return RouteDistinguisherBuilder.getDefaultInstance(str);
-        } else if (obj instanceof RouteDistinguisher rd) {
-            return rd;
+    public static @NonNull RouteDistinguisher parseRouteDistinguisher(final String defaultValue) {
+        if (AS_2BYTE_PATTERN.matcher(defaultValue).matches()) {
+            return new RouteDistinguisher(new RdTwoOctetAs(defaultValue));
+        } else if (IPV4_PATTERN.matcher(defaultValue).matches()) {
+            return new RouteDistinguisher(new RdIpv4(defaultValue));
+        } else if (AS_4BYTE_PATTERN.matcher(defaultValue).matches()) {
+            return new RouteDistinguisher(new RdAs(defaultValue));
         } else {
-            return null;
+            throw new IllegalArgumentException("Cannot create Route Distinguisher from " + defaultValue);
         }
     }
 
     public static @Nullable RouteDistinguisher extractRouteDistinguisher(final DataContainerNode route,
             final NodeIdentifier rdNid) {
         final var rdNode = route.childByArg(rdNid);
-        return rdNode == null ? null : parseRouteDistinguisher(rdNode.body());
+        return rdNode == null ? null : parseRouteDistinguisher((String) rdNode.body());
     }
-
 }
diff --git a/bgp/concepts/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/bgp/types/rev200120/RouteDistinguisherBuilder.java b/bgp/concepts/src/main/java/org/opendaylight/yang/gen/v1/urn/opendaylight/params/xml/ns/yang/bgp/types/rev200120/RouteDistinguisherBuilder.java
deleted file mode 100644 (file)
index b03f84c..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco Systems, Inc. and others.  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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120;
-
-import java.util.regex.Pattern;
-
-
-/**
- * The purpose of generated class in src/main/java for Union types is to create new instances of unions from a string representation.
- * In some cases it is very difficult to automate it since there can be unions such as (uint32 - uint16), or (string - uint32).
- *
- * The reason behind putting it under src/main/java is:
- * This class is generated in form of a stub and needs to be finished by the user. This class is generated only once to prevent
- * loss of user code.
- *
- */
-public final class RouteDistinguisherBuilder {
-
-    private static final Pattern RD_TWO_OCTET_AS =
-        Pattern.compile("0:"
-            + "([0-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|"
-            + "[1-5][0-9][0-9][0-9][0-9]|6[0-4][0-9][0-9][0-9]|"
-            + "65[0-4][0-9][0-9]|655[0-2][0-9]|6553[0-5])"
-            + ":"
-            + "([0-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|"
-            + "[1-9][0-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9][0-9]|"
-            + "[1-9][0-9][0-9][0-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|"
-            + "[1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|[1-3][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|"
-            + "4[0-1][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|42[0-8][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|"
-            + "429[0-3][0-9][0-9][0-9][0-9][0-9][0-9]|4294[0-8][0-9][0-9][0-9][0-9][0-9]|"
-            + "42949[0-5][0-9][0-9][0-9][0-9]|429496[0-6][0-9][0-9][0-9]|4294967[0-1][0-9][0-9]|"
-            + "42949672[0-8][0-9]|429496729[0-5])");
-
-    private static final Pattern RD_IPV4 =
-        Pattern.compile("((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\\.){3}"
-            + "([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5]))"
-            + ":"
-            + "([0-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|"
-            + "[1-5][0-9][0-9][0-9][0-9]|6[0-4][0-9][0-9][0-9]|"
-            + "65[0-4][0-9][0-9]|655[0-2][0-9]|6553[0-5])");
-
-    private static final Pattern RD_AS =
-        Pattern.compile("([0-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|"
-            + "[1-9][0-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9][0-9]|"
-            + "[1-9][0-9][0-9][0-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|"
-            + "[1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|[1-3][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|"
-            + "4[0-1][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|42[0-8][0-9][0-9][0-9][0-9][0-9][0-9][0-9]|"
-            + "429[0-3][0-9][0-9][0-9][0-9][0-9][0-9]|4294[0-8][0-9][0-9][0-9][0-9][0-9]|"
-            + "42949[0-5][0-9][0-9][0-9][0-9]|429496[0-6][0-9][0-9][0-9]|4294967[0-1][0-9][0-9]|"
-            + "42949672[0-8][0-9]|429496729[0-5])"
-            + ":"
-            + "([0-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|"
-            + "[1-5][0-9][0-9][0-9][0-9]|6[0-4][0-9][0-9][0-9]|"
-            + "65[0-4][0-9][0-9]|655[0-2][0-9]|6553[0-5])");
-
-    private RouteDistinguisherBuilder() {
-
-    }
-
-    public static RouteDistinguisher getDefaultInstance(final java.lang.String defaultValue) {
-        if (RD_TWO_OCTET_AS.matcher(defaultValue).matches()) {
-            return new RouteDistinguisher((new RdTwoOctetAs(defaultValue)));
-        } else if (RD_IPV4.matcher(defaultValue).matches()) {
-            return new RouteDistinguisher(new RdIpv4(defaultValue));
-        } else if (RD_AS.matcher(defaultValue).matches()) {
-            return new RouteDistinguisher(new RdAs(defaultValue));
-        } else {
-            throw new IllegalArgumentException("Cannot create Route Distinguisher from " + defaultValue);
-        }
-    }
-
-}
index 47f7eeef524cca399772703977373934ed868690..ad05cb3a72c2069dd5e468b1797c3f6ae6b93bb7 100644 (file)
@@ -9,16 +9,17 @@ package org.opendaylight.bgp.concepts;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
 import static org.opendaylight.bgp.concepts.RouteDistinguisherUtil.SEPARATOR;
 
-import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RdAs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RdIpv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RdTwoOctetAs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisher;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisherBuilder;
 
 public class RouteDistinguisherUtilTest {
-
     private static final String IP_ADDRESS = "1.2.3.4";
     private static final String IP_PORT = "10";
     private static final String ADMIN = "55";
@@ -30,89 +31,61 @@ public class RouteDistinguisherUtilTest {
     private static final byte[] AS_4B_BYTES = {0, 2, 0, 0, 0, 55, (byte) 0xff, (byte) 0xff};
     private static final byte[] INVALID_RD_TYPE_BYTES = {0, 3, 0, 0, 0, 55, (byte) 0xff, (byte) 0xff};
 
-    /**
-     * Create 4-octet AS RD or IPv4 RD, 2-octet AS RD cannot be created with this function.
-     */
-    private static RouteDistinguisher createRouteDistinguisher(final int type, final String administratorSubfield,
-            final String assignedNumberSubfield) {
-        final StringBuilder routeDistiguisher = new StringBuilder();
-        if (type == 0) {
-            routeDistiguisher.append(type).append(SEPARATOR);
-        }
-        routeDistiguisher.append(administratorSubfield);
-        routeDistiguisher.append(SEPARATOR);
-        routeDistiguisher.append(assignedNumberSubfield);
-        return RouteDistinguisherBuilder.getDefaultInstance(routeDistiguisher.toString());
-    }
-
     @Test
     public void testAs2BRouteDistinguisher() {
-        final RouteDistinguisher expected = createRouteDistinguisher(0, ADMIN, ASSIGNED_NUMBER);
-        final RouteDistinguisher parsed = RouteDistinguisherUtil
-            .parseRouteDistinguisher(Unpooled.copiedBuffer(AS_2B_BYTES));
-        assertEquals(expected.getRdTwoOctetAs(), parsed.getRdTwoOctetAs());
-        final ByteBuf byteAggregator = Unpooled.buffer(AS_2B_BYTES.length);
-        RouteDistinguisherUtil.serializeRouteDistinquisher(expected, byteAggregator);
+        final var expected = new RouteDistinguisher(
+            new RdTwoOctetAs("0" + SEPARATOR + ADMIN + SEPARATOR + ASSIGNED_NUMBER));
+        assertEquals(expected,
+            RouteDistinguisherUtil.parseRouteDistinguisher("0" + SEPARATOR + ADMIN + SEPARATOR + ASSIGNED_NUMBER));
+
+        final var parsed = RouteDistinguisherUtil.parseRouteDistinguisher(Unpooled.copiedBuffer(AS_2B_BYTES));
+        assertEquals(expected, parsed);
+        final var byteAggregator = Unpooled.buffer(AS_2B_BYTES.length);
+        RouteDistinguisherUtil.serializeRouteDistinquisher(parsed, byteAggregator);
         assertArrayEquals(AS_2B_BYTES, byteAggregator.array());
-        assertEquals("0" + SEPARATOR + ADMIN + SEPARATOR + ASSIGNED_NUMBER,
-                parsed.getRdTwoOctetAs().getValue());
     }
 
     @Test
     public void testAs2BLongRouteDistinguisher() {
-        final RouteDistinguisher expected = createRouteDistinguisher(0, ADMIN, ASSIGNED_NUMBER_BIG);
-        final RouteDistinguisher parsed = RouteDistinguisherUtil
-            .parseRouteDistinguisher(Unpooled.copiedBuffer(AS_2B_BYTES_BIG));
-        assertEquals(expected.getRdTwoOctetAs(), parsed.getRdTwoOctetAs());
-        final ByteBuf byteAggregator = Unpooled.buffer(AS_2B_BYTES_BIG.length);
-        RouteDistinguisherUtil.serializeRouteDistinquisher(expected, byteAggregator);
+        final var expected = new RouteDistinguisher(new RdTwoOctetAs(
+            "0" + SEPARATOR + ADMIN + SEPARATOR + ASSIGNED_NUMBER_BIG));
+        assertEquals(expected,
+            RouteDistinguisherUtil.parseRouteDistinguisher("0" + SEPARATOR + ADMIN + SEPARATOR + ASSIGNED_NUMBER_BIG));
+
+        final var parsed = RouteDistinguisherUtil.parseRouteDistinguisher(Unpooled.copiedBuffer(AS_2B_BYTES_BIG));
+        assertEquals(expected, parsed);
+        final var byteAggregator = Unpooled.buffer(AS_2B_BYTES_BIG.length);
+        RouteDistinguisherUtil.serializeRouteDistinquisher(parsed, byteAggregator);
         assertArrayEquals(AS_2B_BYTES_BIG, byteAggregator.array());
-        assertEquals("0" + SEPARATOR + ADMIN + SEPARATOR + ASSIGNED_NUMBER_BIG,
-                parsed.getRdTwoOctetAs().getValue());
     }
 
     @Test
     public void testIpv4RouteDistinguisher() {
-        final RouteDistinguisher expected = createRouteDistinguisher(1, IP_ADDRESS, IP_PORT);
-        final RouteDistinguisher parsed = RouteDistinguisherUtil
-            .parseRouteDistinguisher(Unpooled.copiedBuffer(IP_BYTES));
-        assertEquals(expected.getRdIpv4(), parsed.getRdIpv4());
-        final ByteBuf byteAggregator = Unpooled.buffer(IP_BYTES.length);
-        RouteDistinguisherUtil.serializeRouteDistinquisher(expected, byteAggregator);
+        final var expected = new RouteDistinguisher(new RdIpv4(IP_ADDRESS + SEPARATOR + IP_PORT));
+        assertEquals(expected, RouteDistinguisherUtil.parseRouteDistinguisher(IP_ADDRESS + SEPARATOR + IP_PORT));
+
+        final var parsed = RouteDistinguisherUtil.parseRouteDistinguisher(Unpooled.copiedBuffer(IP_BYTES));
+        assertEquals(expected, parsed);
+        final var byteAggregator = Unpooled.buffer(IP_BYTES.length);
+        RouteDistinguisherUtil.serializeRouteDistinquisher(parsed, byteAggregator);
         assertArrayEquals(IP_BYTES, byteAggregator.array());
-        assertEquals(IP_ADDRESS + SEPARATOR + IP_PORT, parsed.getRdIpv4().getValue());
     }
 
     @Test
     public void testAs4BRouteDistinguisher() {
-        final RouteDistinguisher expected = createRouteDistinguisher(2, ADMIN, ASSIGNED_NUMBER);
-        final RouteDistinguisher parsed = RouteDistinguisherUtil
-            .parseRouteDistinguisher(Unpooled.copiedBuffer(AS_4B_BYTES));
-        assertEquals(expected.getRdAs(), parsed.getRdAs());
-        final ByteBuf byteAggregator = Unpooled.buffer(AS_4B_BYTES.length);
-        RouteDistinguisherUtil.serializeRouteDistinquisher(expected, byteAggregator);
+        final var expected = new RouteDistinguisher(new RdAs(ADMIN + SEPARATOR + ASSIGNED_NUMBER));
+        assertEquals(expected, RouteDistinguisherUtil.parseRouteDistinguisher(ADMIN + SEPARATOR + ASSIGNED_NUMBER));
+
+        final var parsed = RouteDistinguisherUtil.parseRouteDistinguisher(Unpooled.copiedBuffer(AS_4B_BYTES));
+        assertEquals(expected, parsed);
+        final var byteAggregator = Unpooled.buffer(AS_4B_BYTES.length);
+        RouteDistinguisherUtil.serializeRouteDistinquisher(parsed, byteAggregator);
         assertArrayEquals(AS_4B_BYTES, byteAggregator.array());
-        assertEquals(ADMIN + SEPARATOR + ASSIGNED_NUMBER, parsed.getRdAs().getValue());
     }
 
     @Test
-    public void testParseRouteDistinguisher() {
-        final RouteDistinguisher expected = RouteDistinguisherUtil
-            .parseRouteDistinguisher(ADMIN + SEPARATOR + ASSIGNED_NUMBER);
-        final RouteDistinguisher parsed = RouteDistinguisherUtil
-            .parseRouteDistinguisher(Unpooled.copiedBuffer(AS_4B_BYTES));
-        assertEquals(expected.getRdAs(), parsed.getRdAs());
-
-        final RouteDistinguisher expectedRD = RouteDistinguisherUtil.parseRouteDistinguisher(expected);
-        assertEquals(expectedRD.getRdAs(), parsed.getRdAs());
-
-        final RouteDistinguisher expectedObj = RouteDistinguisherUtil
-            .parseRouteDistinguisher((Object) (ADMIN + SEPARATOR + ASSIGNED_NUMBER));
-        assertEquals(expectedObj.getRdAs(), parsed.getRdAs());
-    }
-
-    @Test(expected = IllegalArgumentException.class)
     public void testInvalidRDType() {
-        RouteDistinguisherUtil.parseRouteDistinguisher(Unpooled.copiedBuffer(INVALID_RD_TYPE_BYTES));
+        final var buf = Unpooled.copiedBuffer(INVALID_RD_TYPE_BYTES);
+        assertThrows(IllegalArgumentException.class, () -> RouteDistinguisherUtil.parseRouteDistinguisher(buf));
     }
 }
index 9f4596eb6a6fd88e9e10d6e00379a8a3258d0ca6..642df9520badee136d86a740c337d292d53e66ad 100644 (file)
@@ -7,6 +7,9 @@
  */
 package org.opendaylight.protocol.bgp.evpn.impl.nlri;
 
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone;
@@ -15,7 +18,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev200120.ethernet.tag.id.EthernetTagIdBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev200120.evpn.EvpnChoice;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisher;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisherBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.MplsLabel;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.Uint32;
@@ -51,34 +53,34 @@ final class NlriModelUtil {
         // Hidden on purpose
     }
 
-    static RouteDistinguisher extractRouteDistinguisher(final DataContainerNode evpn) {
-        return RouteDistinguisherBuilder.getDefaultInstance((String) evpn.getChildByArg(RD_NID).body());
+    static @Nullable RouteDistinguisher extractRouteDistinguisher(final DataContainerNode evpn) {
+        return RouteDistinguisherUtil.extractRouteDistinguisher(evpn, RD_NID);
     }
 
-    static IpAddressNoZone extractOrigRouteIp(final DataContainerNode evpn) {
+    static @NonNull IpAddressNoZone extractOrigRouteIp(final DataContainerNode evpn) {
         return parseIpAddress((String) evpn.getChildByArg(ORI_NID).body());
     }
 
-    static EthernetTagId extractETI(final ContainerNode evpn) {
+    static @NonNull EthernetTagId extractETI(final ContainerNode evpn) {
         final ContainerNode eti = (ContainerNode) evpn.getChildByArg(ETI_NID);
         return new EthernetTagIdBuilder().setVlanId((Uint32) eti.getChildByArg(VLAN_NID).body()).build();
     }
 
-    static MacAddress extractMAC(final DataContainerNode evpn) {
+    static @NonNull MacAddress extractMAC(final DataContainerNode evpn) {
         return new MacAddress((String) evpn.getChildByArg(MAC_NID).body());
     }
 
-    static IpAddressNoZone extractIp(final DataContainerNode evpn) {
+    static @Nullable IpAddressNoZone extractIp(final DataContainerNode evpn) {
         final var ip = evpn.childByArg(IP_NID);
         return ip == null ? null : parseIpAddress((String) ip.body());
     }
 
-    static MplsLabel extractMplsLabel(final DataContainerNode evpn, final NodeIdentifier mplsNid) {
+    static @Nullable MplsLabel extractMplsLabel(final DataContainerNode evpn, final NodeIdentifier mplsNid) {
         final var label = evpn.childByArg(mplsNid);
         return label == null ? null : new MplsLabel((Uint32) label.body());
     }
 
-    private static IpAddressNoZone parseIpAddress(final String str) {
+    private static @NonNull IpAddressNoZone parseIpAddress(final String str) {
         try {
             return new IpAddressNoZone(new Ipv4AddressNoZone(str));
         } catch (IllegalArgumentException e) {
index b0291959fd2ed2508142a16933f9b9cfdf01f730..0e6cc29ac99393a3daa99229d9befa14199f1c38 100644 (file)
@@ -7,13 +7,13 @@
  */
 package org.opendaylight.protocol.bgp.evpn.impl;
 
+import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddressNoZone;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4AddressNoZone;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6AddressNoZone;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisher;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisherBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.MplsLabel;
 import org.opendaylight.yangtools.yang.common.Uint16;
 import org.opendaylight.yangtools.yang.common.Uint32;
@@ -43,7 +43,7 @@ public final class EvpnTestUtil {
     public static final Uint32 MPLS_LABEL2_MODEL = Uint32.valueOf(24002L);
     public static final MplsLabel MPLS_LABEL2 = new MplsLabel(MPLS_LABEL2_MODEL);
     public static final String RD_MODEL = "1.2.3.4:258";
-    public static final RouteDistinguisher RD = RouteDistinguisherBuilder.getDefaultInstance(RD_MODEL);
+    public static final RouteDistinguisher RD = RouteDistinguisherUtil.parseRouteDistinguisher(RD_MODEL);
 
     private EvpnTestUtil() {
         // Hidden on purpose
index 0ae045cfea6427a1437bef8855a76702ee6c9838..6adb7eb1f1c457c95354e11e2bbb8dcc55c511b7 100644 (file)
@@ -24,6 +24,7 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
+import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
 import org.opendaylight.protocol.bgp.flowspec.FlowspecTypeRegistries.SAFI;
 import org.opendaylight.protocol.bgp.flowspec.handlers.AbstractNumericOperandParser;
 import org.opendaylight.protocol.bgp.flowspec.handlers.AbstractOperandParser;
@@ -93,7 +94,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.unreach.mp.unreach.nlri.WithdrawnRoutesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.Ipv4AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisher;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisherBuilder;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.Uint16;
 import org.opendaylight.yangtools.yang.common.Uint32;
@@ -103,6 +103,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdent
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.builder.DataContainerNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 
 @RunWith(MockitoJUnitRunner.StrictStubs.class)
 public class FlowspecL3vpnIpv4NlriParserTest {
@@ -962,19 +963,11 @@ public class FlowspecL3vpnIpv4NlriParserTest {
 
     @Test
     public void testExtractFlowspecRouteDistinguisher() {
-        final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
-                Builders.mapEntryBuilder();
-        entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
-        entry.withChild(
-            Builders.leafBuilder()
-                .withNodeIdentifier(RD_NID)
-                .withValue(
-                    RouteDistinguisherBuilder.getDefaultInstance(ROUTE_DISTINGUISHER)
-                ).build()
-        );
-
-        RouteDistinguisher rd = RouteDistinguisherBuilder.getDefaultInstance(ROUTE_DISTINGUISHER);
-        assertEquals(rd, extractRouteDistinguisher(entry.build(), AbstractFlowspecL3vpnNlriParser.RD_NID));
+        assertEquals(RouteDistinguisherUtil.parseRouteDistinguisher(ROUTE_DISTINGUISHER),
+            extractRouteDistinguisher(Builders.mapEntryBuilder()
+                .withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, "foo"))
+                .withChild(ImmutableNodes.leafNode(RD_NID, ROUTE_DISTINGUISHER))
+                .build(), AbstractFlowspecL3vpnNlriParser.RD_NID));
     }
 }
 
index f43e581318c7dfd48f85712aa80ce0fc5a407919..fd235bf232cb70422b720eedd49b1dbda537eb24 100644 (file)
@@ -15,6 +15,7 @@ import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.List;
 import org.junit.Test;
+import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
@@ -33,7 +34,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.Ipv4AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.MplsLabeledVpnSubsequentAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisher;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisherBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev180329.l3vpn.ipv4.destination.VpnIpv4DestinationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev180329.l3vpn.ip.destination.type.VpnDestination;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev180329.l3vpn.ip.destination.type.VpnDestinationBuilder;
@@ -82,8 +82,7 @@ public class VpnIpv4NlriParserTest {
     static final IpPrefix IPV4_PREFIX = new IpPrefix(new Ipv4Prefix("34.1.22.0/24"));
     static final List<LabelStack> LABEL_STACK = List.of(
         new LabelStackBuilder().setLabelValue(new MplsLabel(Uint32.valueOf(355))).build());
-    static final RouteDistinguisher DISTINGUISHER = RouteDistinguisherBuilder
-            .getDefaultInstance("1.2.3.4:258");
+    static final RouteDistinguisher DISTINGUISHER = RouteDistinguisherUtil.parseRouteDistinguisher("1.2.3.4:258");
     static final VpnDestination IPV4_VPN = new VpnDestinationBuilder().setRouteDistinguisher(DISTINGUISHER)
             .setPrefix(IPV4_PREFIX).setPathId(NON_PATH_ID).setLabelStack(LABEL_STACK).build();
     private static final VpnDestination IPV4_VPN_WITHOUT_LABELS = new VpnDestinationBuilder()
index 1ab19e31f46568dab0f05bf97f5837c06881f7d6..2f7676a9a91d9285c47487906455965c0d373fdd 100644 (file)
@@ -15,6 +15,7 @@ import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.List;
 import org.junit.Test;
+import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
@@ -33,7 +34,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.Ipv6AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.MplsLabeledVpnSubsequentAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisher;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisherBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev180329.l3vpn.ipv6.destination.VpnIpv6DestinationBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev180329.l3vpn.ip.destination.type.VpnDestination;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev180329.l3vpn.ip.destination.type.VpnDestinationBuilder;
@@ -82,8 +82,7 @@ public class VpnIpv6NlriParserTest {
     static final IpPrefix IPV6PREFIX = new IpPrefix(new Ipv6Prefix("2001:2345:5689::/48"));
     static final List<LabelStack> LABEL_STACK = List.of(
         new LabelStackBuilder().setLabelValue(new MplsLabel(Uint32.valueOf(355))).build());
-    static final RouteDistinguisher DISTINGUISHER = RouteDistinguisherBuilder
-            .getDefaultInstance("1.2.3.4:258");
+    static final RouteDistinguisher DISTINGUISHER = RouteDistinguisherUtil.parseRouteDistinguisher("1.2.3.4:258");
     static final VpnDestination IPV6_VPN = new VpnDestinationBuilder().setRouteDistinguisher(DISTINGUISHER)
             .setPrefix(IPV6PREFIX).setLabelStack(LABEL_STACK).setPathId(NON_PATH_ID)
             .build();
index bb27d11ffd1859c59052bf6c6356bbbd32c9ff17..17df17b8d18b2789a1fa5145b8b8059f1ec18d7e 100644 (file)
@@ -190,12 +190,8 @@ public final class LinkstateNlriParser implements NlriParser, NlriSerializer {
     }
 
     public static CLinkstateDestination extractLinkstateDestination(final DataContainerNode linkstate) {
-        final var builder = new CLinkstateDestinationBuilder();
-        // serialize common parts
-        final var distinguisher = linkstate.childByArg(DISTINGUISHER_NID);
-        if (distinguisher != null) {
-            builder.setRouteDistinguisher(RouteDistinguisherUtil.parseRouteDistinguisher(distinguisher.body()));
-        }
+        final var builder = new CLinkstateDestinationBuilder()
+            .setRouteDistinguisher(RouteDistinguisherUtil.extractRouteDistinguisher(linkstate, DISTINGUISHER_NID));
         final var protocolId = linkstate.childByArg(PROTOCOL_ID_NID);
         if (protocolId != null) {
             // DOM representation contains values as are in the model, not as are in generated enum
index 69a2e58a9a42d3d4a6f205e8a402acec012aa68a..376056860b9f932faf72d0129a65cf5d1c29cb83 100644 (file)
@@ -26,6 +26,9 @@ import com.google.common.collect.ImmutableList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
 import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
@@ -55,7 +58,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.tables.Routes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisher;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisherBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.SubsequentAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.next.hop.CNextHop;
 import org.opendaylight.yangtools.util.ImmutableOffsetMapTemplate;
@@ -527,13 +529,12 @@ public abstract class AbstractRIBSupport<
         return routeKeyTemplate;
     }
 
-    protected final String extractPrefix(final DataContainerNode route) {
+    protected final @NonNull String extractPrefix(final DataContainerNode route) {
         return (String) route.getChildByArg(prefixTypeNid).body();
     }
 
-    protected final RouteDistinguisher extractRouteDistinguisher(final DataContainerNode route) {
-        final DataContainerChild child = route.childByArg(rdNid);
-        return child == null ? null : RouteDistinguisherBuilder.getDefaultInstance((String) child.body());
+    protected final @Nullable RouteDistinguisher extractRouteDistinguisher(final DataContainerNode route) {
+        return RouteDistinguisherUtil.extractRouteDistinguisher(route, rdNid);
     }
 
     protected final YangInstanceIdentifier routesYangInstanceIdentifier(final YangInstanceIdentifier routesTablePaths) {
index 8c3aed03ec382d1dc5be822e3932e281b8ba0991..2d9080450ac02fa643899385070b91c999882d6c 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.bgpcep.bgp.topology.provider;
 import static org.junit.Assert.assertEquals;
 
 import org.junit.Test;
+import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.AreaIdentifier;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.DomainIdentifier;
@@ -29,7 +30,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.link
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev200120.node.identifier.c.router.identifier.ospf.node._case.OspfNodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.PathId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisher;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.RouteDistinguisherBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.IsoSystemIdentifier;
 import org.opendaylight.yangtools.yang.common.Uint16;
 import org.opendaylight.yangtools.yang.common.Uint32;
@@ -38,7 +38,7 @@ import org.opendaylight.yangtools.yang.common.Uint8;
 
 public class UriBuilderTest {
     private static final RouteDistinguisher DISTINGUISHER
-            = RouteDistinguisherBuilder.getDefaultInstance("1.2.3.4:258");
+            = RouteDistinguisherUtil.parseRouteDistinguisher("1.2.3.4:258");
 
     @Test
     public void test() {
@@ -78,8 +78,9 @@ public class UriBuilderTest {
                         .build()).setPsn(Uint8.TWO).build()).build());
         linkB.setRemoteNodeDescriptors(nodeR.build());
         c.add(linkB.build());
-        assertEquals("bgpls://1.2.3.4:258:Direct:10/type=foo&local-as=12&local-domain=15&local-area=17&"
-                + "local-router=22&remote-router=0102.0304.0506.02&ipv4-iface=127.0.0.1&ipv4-neigh=20.20.20.20&m"
-                + "t=55&local-id=1&remote-id=2", c.toString());
+        assertEquals("""
+            bgpls://1.2.3.4:258:Direct:10/type=foo&local-as=12&local-domain=15&local-area=17&local-router=22\
+            &remote-router=0102.0304.0506.02&ipv4-iface=127.0.0.1&ipv4-neigh=20.20.20.20&mt=55&local-id=1\
+            &remote-id=2""", c.toString());
     }
 }