From 2d0a37f0d29f7b6a52a65f38344bd83164411c6c Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Thu, 17 Oct 2019 15:00:59 +0200 Subject: [PATCH] Rework prependAS() We cannot modify lists in-place, so make a proper copy and create a new list. Fixes the following splat: java.lang.UnsupportedOperationException: null at com.google.common.collect.ImmutableList.remove(ImmutableList.java:534) ~[36:com.google.guava:27.1.0.jre] at org.opendaylight.protocol.bgp.openconfig.routing.policy.statement.actions.AbstractPrependAsPath.prependAS(AbstractPrependAsPath.java:38) ~[232:org.opendaylight.bgpcep.bgp-openconfig-rp-statement:0.13.0.SNAPSHOT] at org.opendaylight.protocol.bgp.openconfig.routing.policy.statement.actions.LocalAsPathPrependHandler.applyImportAction(LocalAsPathPrependHandler.java:37) ~[232:org.opendaylight.bgpcep.bgp-openconfig-rp-statement:0.13.0.SNAPSHOT] at org.opendaylight.protocol.bgp.openconfig.routing.policy.statement.actions.LocalAsPathPrependHandler.applyImportAction(LocalAsPathPrependHandler.java:18) ~[232:org.opendaylight.bgpcep.bgp-openconfig-rp-statement:0.13.0.SNAPSHOT] at org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.registry.ActionsRegistryImpl.applyImportAction(ActionsRegistryImpl.java:314) ~[231:org.opendaylight.bgpcep.bgp-openconfig-rp-spi:0.13.0.SNAPSHOT] at org.opendaylight.protocol.bgp.openconfig.routing.policy.spi.registry.StatementRegistry.applyImportStatement(StatementRegistry.java:82) ~[231:org.opendaylight.bgpcep.bgp-openconfig-rp-spi:0.13.0.SNAPSHOT] Change-Id: I6f604e8abdb223fe09e44ac92a752bb6e410ed7f Signed-off-by: Robert Varga --- .../actions/AbstractPrependAsPath.java | 52 ++++++++++++------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/bgp/openconfig-rp-statement/src/main/java/org/opendaylight/protocol/bgp/openconfig/routing/policy/statement/actions/AbstractPrependAsPath.java b/bgp/openconfig-rp-statement/src/main/java/org/opendaylight/protocol/bgp/openconfig/routing/policy/statement/actions/AbstractPrependAsPath.java index c1662a6f1c..ac732b5d26 100644 --- a/bgp/openconfig-rp-statement/src/main/java/org/opendaylight/protocol/bgp/openconfig/routing/policy/statement/actions/AbstractPrependAsPath.java +++ b/bgp/openconfig-rp-statement/src/main/java/org/opendaylight/protocol/bgp/openconfig/routing/policy/statement/actions/AbstractPrependAsPath.java @@ -7,7 +7,9 @@ */ package org.opendaylight.protocol.bgp.openconfig.routing.policy.statement.actions; +import com.google.common.collect.ImmutableList; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import org.opendaylight.protocol.util.Values; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.AsNumber; @@ -20,33 +22,47 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mess abstract class AbstractPrependAsPath { static final Attributes prependAS(final Attributes attributes, final AsNumber as) { - final List oldSegments = attributes.getAsPath().getSegments(); + return new AttributesBuilder(attributes) + .setAsPath(new AsPathBuilder() + .setSegments(prependAS(attributes.getAsPath().getSegments(), as)) + .build()) + .build(); + } + + private static List prependAS(final List oldSegments, final AsNumber as) { + if (oldSegments == null || oldSegments.isEmpty()) { + return ImmutableList.of(singleSequence(as)); + } + /* * We need to check the first segment. * If it has as-set then new as-sequence with local AS is prepended. * If it has as-sequence, we may add local AS when it has less than 255 elements. * Otherwise we need to create new as-sequence for local AS. */ - final ArrayList newAsSequence = new ArrayList<>(); - newAsSequence.add(new AsNumber(as)); + final Iterator it = oldSegments.iterator(); + final Segments firstSegment = it.next(); + final List firstAsSequence = firstSegment.getAsSequence(); - List newSegments = new ArrayList<>(); - if (oldSegments == null || oldSegments.isEmpty()) { - newSegments = new ArrayList<>(); + final List newSegments; + if (firstAsSequence != null && firstAsSequence.size() < Values.UNSIGNED_BYTE_MAX_VALUE) { + final ArrayList newAsSequence = new ArrayList<>(firstAsSequence.size() + 1); + newAsSequence.add(as); + newAsSequence.addAll(firstAsSequence); + + newSegments = new ArrayList<>(oldSegments.size()); newSegments.add(new SegmentsBuilder().setAsSequence(newAsSequence).build()); } else { - final Segments firstSegment = oldSegments.remove(0); - final List firstAsSequence = firstSegment.getAsSequence(); - if (firstAsSequence != null && firstAsSequence.size() < Values.UNSIGNED_BYTE_MAX_VALUE) { - newAsSequence.addAll(firstAsSequence); - newSegments.add(new SegmentsBuilder().setAsSequence(newAsSequence).build()); - } else { - newSegments.add(new SegmentsBuilder().setAsSequence(newAsSequence).build()); - newSegments.add(firstSegment); - } - newSegments.addAll(oldSegments); + newSegments = new ArrayList<>(oldSegments.size() + 1); + newSegments.add(singleSequence(as)); + newSegments.add(firstSegment); } - return new AttributesBuilder(attributes).setAsPath(new AsPathBuilder() - .setSegments(newSegments).build()).build(); + + it.forEachRemaining(newSegments::add); + return newSegments; + } + + private static Segments singleSequence(final AsNumber as) { + return new SegmentsBuilder().setAsSequence(ImmutableList.of(as)).build(); } } -- 2.36.6