.count());
}
+ @Override
+ public final long updateInterval() {
+ return serverSessionManager.updateInterval();
+ }
+
@Override
public final boolean isSessionSynchronized() {
return synced.get();
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.protocol.concepts.KeyMapping;
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.PortNumber;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.graph.rev220720.graph.topology.GraphKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.pcep.stats.provider.config.rev220730.TopologyPcep1;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev220730.Node1;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev220730.TopologyTypes1;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import org.opendaylight.yangtools.concepts.Immutable;
final class PCEPTopologyConfiguration implements Immutable {
+ private static final long DEFAULT_UPDATE_INTERVAL = TimeUnit.SECONDS.toNanos(5);
+
private final @NonNull InetSocketAddress address;
+ private final @NonNull GraphKey graphKey;
private final @NonNull KeyMapping keys;
+ private final long updateIntervalNanos;
private final short rpcTimeout;
- private final GraphKey graphKey;
- PCEPTopologyConfiguration(final @NonNull InetSocketAddress address, final short rpcTimeout,
- final @NonNull KeyMapping keys, final @NonNull GraphKey graphKey) {
+ PCEPTopologyConfiguration(final @NonNull InetSocketAddress address, final @NonNull KeyMapping keys,
+ final @NonNull GraphKey graphKey, final short rpcTimeout, final long updateIntervalNanos) {
this.address = requireNonNull(address);
this.keys = requireNonNull(keys);
- this.rpcTimeout = rpcTimeout;
this.graphKey = requireNonNull(graphKey);
+ this.rpcTimeout = rpcTimeout;
+ this.updateIntervalNanos = updateIntervalNanos;
}
static @Nullable PCEPTopologyConfiguration of(final @NonNull Topology topology) {
return null;
}
+ final var updateAug = topologyPcep.augmentation(TopologyPcep1.class);
+ final long updateInterval = updateAug != null ? TimeUnit.SECONDS.toNanos(updateAug.requireTimer().toJava())
+ : DEFAULT_UPDATE_INTERVAL;
+
return new PCEPTopologyConfiguration(
getInetSocketAddress(sessionConfig.getListenAddress(), sessionConfig.getListenPort()),
- sessionConfig.getRpcTimeout(), constructKeys(topology.getNode()),
- constructGraphKey(sessionConfig.getTedName()));
+ constructKeys(topology.getNode()), constructGraphKey(sessionConfig.getTedName()),
+ sessionConfig.getRpcTimeout(), updateInterval);
}
short getRpcTimeout() {
return rpcTimeout;
}
+ long getUpdateInterval() {
+ return updateIntervalNanos;
+ }
+
@NonNull InetSocketAddress getAddress() {
return address;
}
if (sessionConfig != null) {
final var rfc2385KeyPassword = sessionConfig.getPassword();
if (rfc2385KeyPassword != null) {
- final String password = rfc2385KeyPassword.getValue();
+ final var password = rfc2385KeyPassword.getValue();
if (!password.isEmpty()) {
passwords.put(nodeAddress(node), password);
}
.collect(Collectors.toUnmodifiableList());
manager.setRpcTimeout(newConfiguration.getRpcTimeout());
+ manager.setUpdateInterval(newConfiguration.getUpdateInterval());
if (!outdatedNodes.isEmpty()) {
LOG.info("Topology Provider {} updating {} TCP-MD5 keys", topologyId(), outdatedNodes.size());
if (channel.config().setOption(EpollChannelOption.TCP_MD5SIG, newKeys)) {
currentConfig = newConfiguration;
// First start the manager
- manager = new ServerSessionManager(instanceIdentifier, dependencies, newConfiguration.getRpcTimeout(),
- newConfiguration.getGraphKey());
+ manager = new ServerSessionManager(instanceIdentifier, dependencies, newConfiguration.getGraphKey(),
+ newConfiguration.getRpcTimeout(), newConfiguration.getUpdateInterval());
final var managerStart = manager.start();
managerStart.addListener(() -> enableChannel(future, Futures.getUnchecked(managerStart)),
MoreExecutors.directExecutor());
public PCEPTopologyTracker(final DataBroker dataBroker, final ClusterSingletonServiceProvider singletonService,
final RpcProviderService rpcProviderRegistry, final PCEPDispatcher pcepDispatcher,
- final InstructionSchedulerFactory instructionSchedulerFactory, final PceServerProvider pceServerProvider,
- final int updateIntervalSeconds) {
+ final InstructionSchedulerFactory instructionSchedulerFactory, final PceServerProvider pceServerProvider) {
this.dataBroker = requireNonNull(dataBroker);
this.singletonService = requireNonNull(singletonService);
this.rpcProviderRegistry = requireNonNull(rpcProviderRegistry);
this.pcepDispatcher = requireNonNull(pcepDispatcher);
this.instructionSchedulerFactory = requireNonNull(instructionSchedulerFactory);
this.pceServerProvider = requireNonNull(pceServerProvider);
- statsProvider = new TopologyStatsProvider(timer, updateIntervalSeconds);
+ statsProvider = new TopologyStatsProvider(timer);
statsRpcs = new TopologyStatsRpcServiceImpl(dataBroker);
statsReg = rpcProviderRegistry.registerRpcImplementation(PcepTopologyStatsRpcService.class, statsRpcs);
@GuardedBy("this")
private final Map<NodeId, TopologyNodeState> state = new HashMap<>();
+ private volatile long updateInterval;
private volatile short rpcTimeout;
private volatile boolean closed;
ServerSessionManager(final KeyedInstanceIdentifier<Topology, TopologyKey> topology,
- final PCEPTopologyProviderDependencies dependencies, final short rpcTimeout, final GraphKey graphKey) {
+ final PCEPTopologyProviderDependencies dependencies, final GraphKey graphKey,
+ final short rpcTimeout, final long updateInterval) {
this.dependencies = requireNonNull(dependencies);
this.topology = requireNonNull(topology);
- this.rpcTimeout = rpcTimeout;
this.graphKey = requireNonNull(graphKey);
+ this.rpcTimeout = rpcTimeout;
+ this.updateInterval = updateInterval;
}
// Initialize the operational view of the topology.
: dependencies.getTimer().newTimeout(ignored -> task.run(requestId), localTimeout, TimeUnit.SECONDS);
}
+ final long updateInterval() {
+ return isClosed() ? 0 : updateInterval;
+ }
+
final void setRpcTimeout(final short rpcTimeout) {
this.rpcTimeout = rpcTimeout;
}
+ final void setUpdateInterval(final long updateInterval) {
+ this.updateInterval = updateInterval;
+ }
+
final void tearDownSessions(final List<InetAddress> outdatedNodes) {
for (var address : outdatedNodes) {
tearDownSession(new TearDownSessionInputBuilder().setNode(createNodeId(address)).build());
return null;
}
+ long updateInterval() {
+ return topologySessionStats.updateInterval();
+ }
+
@NonNull FluentFuture<? extends @NonNull CommitInfo> updateStatistics() {
// Lockless
final var aug = new PcepTopologyNodeStatsAugBuilder().setPcepSessionState(toPcepSessionState()).build();
package org.opendaylight.bgpcep.pcep.topology.provider;
-import com.google.common.annotations.Beta;
-
/**
* Provide access to topology session stats without expose variables.
*/
-@Beta
-public interface TopologySessionStats {
-
+interface TopologySessionStats {
/**
* Returns true if session is synchronized.
*
* @return status
*/
int getDelegatedLspsCount();
+
+ long updateInterval();
}
*/
package org.opendaylight.bgpcep.pcep.topology.provider;
-import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Objects.requireNonNull;
import com.google.common.base.Stopwatch;
private final Set<Task> tasks = ConcurrentHashMap.newKeySet();
private final ExecutorService executor;
- private final long updateIntervalNanos;
private final Timer timer;
- TopologyStatsProvider(final Timer timer, final int updateIntervalSeconds) {
+ TopologyStatsProvider(final Timer timer) {
this.timer = requireNonNull(timer);
- updateIntervalNanos = TimeUnit.SECONDS.toNanos(updateIntervalSeconds);
- checkArgument(updateIntervalNanos > 0, "Invalid update interval %s", updateIntervalNanos);
-
executor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder()
.setDaemon(true)
.setNameFormat("odl-pcep-stats-%d")
.build());
- LOG.info("TopologyStatsProvider updating every {} seconds", updateIntervalSeconds);
+ LOG.info("TopologyStatsProvider started");
}
void shutdown() {
Task(final @NonNull SessionStateUpdater instance) {
super(instance);
- state = timer.newTimeout(this, updateIntervalNanos, TimeUnit.NANOSECONDS);
+
+ final long updateInterval = instance.updateInterval();
+ if (updateInterval > 0) {
+ state = timer.newTimeout(this, updateInterval, TimeUnit.NANOSECONDS);
+ } else {
+ LOG.debug("Task {} has non-positive interval {}, not scheduling it", this, updateInterval);
+ }
}
@Override
return;
}
- long remainingNanos = updateIntervalNanos - elapsedNanos;
- if (remainingNanos < 0) {
- remainingNanos = updateIntervalNanos;
+ final var updateInterval = getInstance().updateInterval();
+ if (updateInterval > 0) {
+ long remainingNanos = updateInterval - elapsedNanos;
+ if (remainingNanos < 0) {
+ remainingNanos = updateInterval;
+ }
+ state = timer.newTimeout(this, remainingNanos, TimeUnit.NANOSECONDS);
+ } else {
+ LOG.debug("Task {} has non-positive interval {}, skipping reschedule", this, updateInterval);
}
- state = timer.newTimeout(this, remainingNanos, TimeUnit.NANOSECONDS);
}
@Override
terms of the Eclipse Public License v1.0 which accompanies this distribution,
and is available at http://www.eclipse.org/legal/epl-v10.html
-->
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
- xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0">
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<reference id="dataBroker" interface="org.opendaylight.mdsal.binding.api.DataBroker"/>
<reference id="rpcProviderService" interface="org.opendaylight.mdsal.binding.api.RpcProviderService"/>
<reference id="pcepDispatcher" interface="org.opendaylight.protocol.pcep.PCEPDispatcher"/>
<reference id="intructionFactory" interface="org.opendaylight.bgpcep.programming.spi.InstructionSchedulerFactory"/>
<reference id="pceServerProvider" interface="org.opendaylight.bgpcep.pcep.server.PceServerProvider"/>
- <odl:clustered-app-config id="pcepStatsConfig"
- binding-class="org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.odl.pcep.stats.provider.config.rev171113.PcepProvider"/>
-
<bean id="pcepTopologyTracker"
class="org.opendaylight.bgpcep.pcep.topology.provider.PCEPTopologyTracker"
destroy-method="close">
<argument ref="pcepDispatcher"/>
<argument ref="intructionFactory"/>
<argument ref="pceServerProvider"/>
- <argument>
- <bean factory-ref="pcepStatsConfig" factory-method="getTimer"/>
- </argument>
</bean>
</blueprint>
namespace "urn:opendaylight:params:xml:ns:yang:odl:pcep:stats:provider:config";
prefix pspc;
+ import network-topology { prefix nt; revision-date 2013-10-21; }
+ import network-topology-pcep { prefix pn; revision-date 2022-07-30; }
+
description
"This module contains the base YANG definitions for
PCEP Stats Provider Configuration.
accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html";
+ revision "2022-07-30" {
+ description
+ "Integrated with PCEP network topology";
+ }
+
revision "2017-11-13" {
description
"Initial revision.";
}
- container pcep-provider {
- leaf config-name {
- type string;
- mandatory true;
- }
-
+ augment "/nt:network-topology/nt:topology/nt:topology-types/pn:topology-pcep" {
leaf timer {
- type uint16;
+ type uint16 {
+ range 1..max;
+ }
default 5;
units "seconds";
}
}
-}
\ No newline at end of file
+}
doReturn(timer).when(topologyDependencies).getTimer();
doReturn(null).when(topologyDependencies).getPceServerProvider();
- manager = customizeSessionManager(new ServerSessionManager(TOPO_IID, topologyDependencies, RPC_TIMEOUT,
- new GraphKey("graph-test")));
+ manager = customizeSessionManager(new ServerSessionManager(TOPO_IID, topologyDependencies,
+ new GraphKey("graph-test"), RPC_TIMEOUT, TimeUnit.SECONDS.toNanos(5)));
startSessionManager();
neg = new DefaultPCEPSessionNegotiator(promise, clientListener, manager.getSessionListener(), (short) 1, 5,
localPrefs);