From e0ae4f223028652a3c88a0a96e2c371d5d348daf Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Wed, 3 Jul 2019 10:40:26 +0200 Subject: [PATCH] Fix unsynchronized LSP counting Trying to copy values out of lspData without holding the lock can result it ConcurrentModificationException and was broken by the fix for BGPCEP-845. Restore the lock for the duration of the copy and count the items outside of the lock. JIRA: BGPCEP-875 Change-Id: Ic6e839cac51a73c0812aabb58e96cb2f4959c4d6 Signed-off-by: Robert Varga (cherry picked from commit 5089a36f11b2f9d249aeca53da867037be26fe1b) --- .../AbstractTopologySessionListener.java | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractTopologySessionListener.java b/pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractTopologySessionListener.java index 63ffa1e7ed..ccb4ccb8f2 100755 --- a/pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractTopologySessionListener.java +++ b/pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractTopologySessionListener.java @@ -30,6 +30,7 @@ import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Stream; import javax.annotation.concurrent.GuardedBy; import org.opendaylight.bgpcep.pcep.topology.provider.session.stats.SessionStateImpl; import org.opendaylight.bgpcep.pcep.topology.provider.session.stats.TopologySessionStats; @@ -437,8 +438,8 @@ public abstract class AbstractTopologySessionListener implements TopologyS this.lspData.put(name, rl); } - private List makeBeforeBreak(final ReportedLspBuilder rlb, final ReportedLsp previous, final String name, - final boolean remove) { + private static List makeBeforeBreak(final ReportedLspBuilder rlb, final ReportedLsp previous, + final String name, final boolean remove) { // just one path should be reported Preconditions.checkState(rlb.getPath().size() == 1); final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.LspId reportedLspId = @@ -594,14 +595,19 @@ public abstract class AbstractTopologySessionListener implements TopologyS @Override public int getDelegatedLspsCount() { - return Math.toIntExact(ImmutableList.copyOf(this.lspData.values()).stream() - .map(ReportedLsp::getPath).filter(Objects::nonNull).filter(pathList -> !pathList.isEmpty()) - // pick the first path, as delegate status should be same in each path - .map(pathList -> pathList.get(0)) - .map(path -> path.augmentation(Path1.class)).filter(Objects::nonNull) - .map(LspObject::getLsp).filter(Objects::nonNull) - .filter(Lsp::isDelegate) - .count()); + final Stream stream; + synchronized (this) { + stream = ImmutableList.copyOf(this.lspData.values()).stream(); + } + + return Math.toIntExact(stream + .map(ReportedLsp::getPath).filter(pathList -> pathList != null && !pathList.isEmpty()) + // pick the first path, as delegate status should be same in each path + .map(pathList -> pathList.get(0)) + .map(path -> path.augmentation(Path1.class)).filter(Objects::nonNull) + .map(LspObject::getLsp).filter(Objects::nonNull) + .filter(Lsp::isDelegate) + .count()); } @Override -- 2.36.6