<type>xml</type>
<classifier>features</classifier>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-bgpcep-pcep-topology-stats</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
</dependencies>
<!--
<type>xml</type>
<classifier>features</classifier>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-bgpcep-pcep-topology-stats</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
<dependency>
<groupId>org.opendaylight.controller</groupId>
<artifactId>odl-mdsal-broker</artifactId>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (c) 2017 AT&T Intellectual Property. 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
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.odlparent</groupId>
+ <artifactId>single-feature-parent</artifactId>
+ <version>2.0.5</version>
+ <relativePath/>
+ </parent>
+
+ <groupId>org.opendaylight.bgpcep</groupId>
+ <artifactId>odl-bgpcep-pcep-topology-stats</artifactId>
+ <version>0.9.0-SNAPSHOT</version>
+ <packaging>feature</packaging>
+
+ <name>OpenDaylight :: PCEP :: Topology Stats</name>
+
+ <dependencyManagement>
+ <dependencies>
+ <!-- ODL-BGP-ARTIFACTS -->
+ <dependency>
+ <groupId>org.opendaylight.bgpcep</groupId>
+ <artifactId>bgpcep-artifacts</artifactId>
+ <version>${project.version}</version>
+ <type>pom</type>
+ <scope>import</scope>
+ </dependency>
+ </dependencies>
+ </dependencyManagement>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>pcep-topology-stats</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-bgpcep-pcep-topology</artifactId>
+ <type>xml</type>
+ <classifier>features</classifier>
+ </dependency>
+ </dependencies>
+ <!--
+ Maven Site Configuration
+
+ The following configuration is necessary for maven-site-plugin to
+ correctly identify the correct deployment path for OpenDaylight Maven
+ sites.
+ -->
+ <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+ <distributionManagement>
+ <site>
+ <id>opendaylight-site</id>
+ <url>${nexus.site.url}/${project.artifactId}/</url>
+ </site>
+ </distributionManagement>
+</project>
<module>odl-bgpcep-pcep-tunnel-provider</module>
<module>odl-bgpcep-pcep-segment-routing</module>
<module>odl-bgpcep-pcep-auto-bandwidth</module>
+ <module>odl-bgpcep-pcep-topology-stats</module>
</modules>
<!--
import io.netty.util.concurrent.Future;
import java.net.InetAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev141006.PcepSessionState;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.LocalPref;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.Messages;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.PeerPref;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.open.Tlvs;
* manually. If the session is up, it has to redirect messages to/from user. Handles also malformed messages and unknown
* requests.
*/
-public interface PCEPSession extends AutoCloseable, PcepSessionState {
+public interface PCEPSession extends PCEPSessionState, AutoCloseable {
/**
* Sends message from user to PCE/PCC. If the user sends an Open Message, the session returns an error (open message
InetAddress getRemoteAddress();
- void resetStats();
-
/**
* Returns session characteristics of the local PCEP Speaker
+ *
* @return Open message TLVs
*/
Tlvs localSessionCharacteristics();
--- /dev/null
+/*
+ * Copyright (c) 2017 AT&T Intellectual Property. 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.protocol.pcep;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.LocalPref;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.Messages;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.PeerPref;
+
+/**
+ * Exposes Session state
+ */
+public interface PCEPSessionState {
+ /**
+ * The statistics of PCEP received/sent messages from the PCE point of view.
+ *
+ * @return <code>org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev171113.pcep.session.state.Messages</code> <code>messages</code>, or <code>null</code> if not present
+ */
+ Messages getMessages();
+
+ /**
+ * The local (PCE) preferences.
+ *
+ * @return <code>org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev171113.pcep.session.state.LocalPref</code> <code>localPref</code>, or <code>null</code> if not present
+ */
+ LocalPref getLocalPref();
+
+ /**
+ * The remote peer (PCC) preferences.
+ *
+ * @return <code>org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev171113.pcep.session.state.PeerPref</code> <code>peerPref</code>, or <code>null</code> if not present
+ */
+ PeerPref getPeerPref();
+}
// vi: set smarttab et sw=4 tabstop=4:
module pcep-session-stats {
yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:pcep:stats";
+ namespace "urn:opendaylight:params:xml:ns:yang:pcep:stats";
prefix "pcep-stats";
organization "Cisco Systems, Inc.";
accompanies this distribution, and is available at
http://www.eclipse.org/legal/epl-v10.html";
+ revision "2017-11-13" {
+ description
+ "Update namespace and add default values";
+ }
+
revision "2014-10-06" {
description
"Initial revision";
}
}
+ grouping error-messages-grouping {
+ container error-messages {
+ description "The message statistics of received/sent PCErr messages.";
+ leaf received-error-msg-count {
+ description "Total number of received PCErr messages.";
+ type uint32;
+ default 0;
+ }
+
+ leaf sent-error-msg-count {
+ description "Total number of sent PCErr messages.";
+ type uint32;
+ default 0;
+ }
+
+ container last-received-error {
+ description "Type/value tuple of last received error.";
+ uses error;
+ }
+
+ container last-sent-error {
+ description "Type/value tuple of last sent error.";
+ uses error;
+ }
+ }
+ }
+
+ grouping reply-time-grouping {
+ container reply-time {
+ description "Measures time elapsed from request's send to reply's received.";
+
+ leaf average-time {
+ description "Average time (in milliseconds) of gauged values.";
+ type uint32;
+ default 0;
+ }
+
+ leaf min-time {
+ description "Minimal measured time value (in milliseconds).";
+ type uint32;
+ default 0;
+ }
+
+ leaf max-time {
+ description "Maximal measured time value (in milliseconds).";
+ type uint32;
+ default 0;
+ }
+ }
+ }
+
grouping pcep-session-state {
description "PCEP session statistics.";
+ leaf session-duration {
+ description "Elapsed time (in d:H:m:s) from session-up until now.";
+ type string;
+ }
+
+ leaf synchronized {
+ description "Represents synchronization status.";
+ type boolean;
+ default false;
+ }
+
+ container peer-capabilities {
+ description "Remote peer's (PCC) advertised capabilities.";
+ }
+
container messages {
description "The statistics of PCEP received/sent messages from the PCE point of view.";
+
+ uses reply-time-grouping;
+
leaf received-msg-count {
description "Total number of received PCEP messages.";
type uint32;
+ default 0;
}
leaf sent-msg-count {
description "Total number of sent PCEP messages.";
type uint32;
+ default 0;
}
leaf last-sent-msg-timestamp {
description "The timestamp of last sent message.";
type uint32;
+ default 0;
}
leaf unknown-msg-received {
description "The number of received unknown messages.";
type uint16;
+ default 0;
}
- container error-messages {
- description "The message statistics of received/sent PCErr messages.";
- leaf received-error-msg-count {
- description "Total number of received PCErr messages.";
- type uint32;
- }
-
- leaf sent-error-msg-count {
- description "Total number of sent PCErr messages.";
- type uint32;
- }
-
- container last-received-error {
- description "Type/value tuple of last received error.";
- uses error;
- }
-
- container last-sent-error {
- description "Type/value tuple of last sent error.";
- uses error;
- }
- }
+ uses error-messages-grouping;
}
container local-pref {
description "The remote peer (PCC) preferences.";
uses preferences;
}
+
+
+ leaf delegated-lsps-count {
+ description "The number of delegated LSPs (tunnels) from PCC.";
+ type uint16;
+ default 0;
+ }
+ }
+
+ grouping pcep-session-state-grouping {
+ container pcep-session-state {
+ uses pcep-session-state;
+ }
}
}
\ No newline at end of file
--- /dev/null
+// vi: set smarttab et sw=4 tabstop=4:
+module odl-pcep-stateful-stats {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:pcep:stateful:stats";
+ prefix pspc;
+
+ import network-topology { prefix nt; revision-date 2013-10-21; }
+ import network-topology-pcep { prefix pn; revision-date 2017-10-25; }
+ import yang-ext { prefix ext; revision-date 2013-07-09; }
+ import pcep-session-stats { prefix pss; revision-date 2017-11-13; }
+ import network-pcep-topology-stats { prefix npts; revision-date 2017-11-13; }
+
+ description
+ "This module contains the PCEP Stateful stats YANG definitions for
+ PCEP Topology Node Stats.
+ Copyright (c)2017 AT&T Services, Inc. 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";
+
+ organization "AT&T Services, Inc.";
+ contact "Claudio D. Gasparini <claudio.gasparini@pantheon.sk>";
+
+ revision "2017-11-13" {
+ description
+ "Initial revision.";
+ }
+
+ grouping stateful-messages-grouping {
+ description "The statistics of sent/received PCEP stateful messages.";
+ leaf last-received-rpt-msg-timestamp {
+ description "The timestamp of last received PCRpt message.";
+ type uint32;
+ default 0;
+ }
+
+ leaf received-rpt-msg-count {
+ description "The number of received PcRpt messages.";
+ type uint32;
+ default 0;
+ }
+
+ leaf sent-upd-msg-count {
+ description "The number of sent PCUpd messages.";
+ type uint32;
+ default 0;
+ }
+
+ leaf sent-init-msg-count {
+ description "The number of sent PCInitiate messages.";
+ type uint32;
+ default 0;
+ }
+ }
+
+ augment "/nt:network-topology/nt:topology/nt:node/npts:pcep-session-state/npts:messages" {
+ when "../../../nt:topology-types/pn:topology-pcep";
+ ext:augment-identifier stateful-messages-stats-aug;
+ description "Augment Pcep topology node with Stateful session stats";
+
+ uses stateful-messages-grouping;
+ }
+
+ grouping stateful-preferences {
+ leaf instantiation {
+ description "Represents peer's instantiation capability.";
+ type boolean;
+ default "false";
+ }
+
+ leaf stateful {
+ description "Represents peer's stateful/stateless capability.";
+ type boolean;
+ default "false";
+ }
+
+ leaf active {
+ description "Represents peer's LSP update capability.";
+ type boolean;
+ default "false";
+ }
+ }
+
+ augment "/nt:network-topology/nt:topology/nt:node/npts:pcep-session-state/npts:peer-capabilities" {
+ when "../../../nt:topology-types/pn:topology-pcep";
+ ext:augment-identifier stateful-capabilities-stats-aug;
+ description "Remote peer's (PCC) advertised stateful capabilities.";
+
+ uses stateful-preferences;
+ }
+}
\ No newline at end of file
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.concurrent.GuardedBy;
import org.opendaylight.protocol.pcep.PCEPCloseTermination;
import org.opendaylight.protocol.pcep.PCEPSession;
import org.opendaylight.protocol.pcep.TerminationReason;
import org.opendaylight.protocol.pcep.impl.spi.Util;
import org.opendaylight.protocol.pcep.spi.PCEPErrors;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev141006.pcep.session.state.LocalPref;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev141006.pcep.session.state.Messages;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev141006.pcep.session.state.PeerPref;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.CloseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Keepalive;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.KeepaliveBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.LocalPref;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.Messages;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.PeerPref;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.CloseMessage;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.KeepaliveMessage;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.keepalive.message.KeepaliveMessageBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.Open;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.open.Tlvs;
-import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// True if the listener should not be notified about events
@GuardedBy("this")
- private boolean closed = false;
+ private AtomicBoolean closed = new AtomicBoolean(false);
private final Channel channel;
private final PCEPSessionState sessionState;
PCEPSessionImpl(final PCEPSessionListener listener, final int maxUnknownMessages, final Channel channel,
- final Open localOpen, final Open remoteOpen) {
+ final Open localOpen, final Open remoteOpen) {
this.listener = requireNonNull(listener);
this.channel = requireNonNull(channel);
this.localOpen = requireNonNull(localOpen);
}
LOG.info("Session {}[{}] <-> {}[{}] started", channel.localAddress(), localOpen.getSessionId(), channel.remoteAddress(),
- remoteOpen.getSessionId());
+ remoteOpen.getSessionId());
this.sessionState = new PCEPSessionState(remoteOpen, localOpen, channel);
}
* KeepAlive timer to the time at which the message was sent. If the session was closed by the time this method
* starts to execute (the session state will become IDLE), that rescheduling won't occur.
*/
- private void handleKeepaliveTimer() {
+ private void handleKeepaliveTimer() {
final long ct = TICKER.read();
long nextKeepalive = this.lastMessageSentAt + TimeUnit.SECONDS.toNanos(getKeepAliveTimerValue());
@VisibleForTesting
public synchronized boolean isClosed() {
- return this.closed;
+ return this.closed.get();
}
/**
*/
@Override
public synchronized void close(final TerminationReason reason) {
- if (this.closed) {
+ if (this.closed.getAndSet(true)) {
LOG.debug("Session is already closed.");
return;
}
- this.closed = true;
// only send close message when the reason is provided
if (reason != null) {
LOG.info("Closing PCEP session with reason {}: {}", reason, this);
}
private synchronized void terminate(final TerminationReason reason) {
- if (this.closed) {
+ if (this.closed.get()) {
LOG.debug("Session {} is already closed.", this);
return;
}
this.listener.onSessionTerminated(this, new PCEPCloseTermination(reason));
}
- public synchronized void endOfInput() {
- if (!this.closed) {
+ synchronized void endOfInput() {
+ if (!this.closed.getAndSet(true)) {
this.listener.onSessionDown(this, new IOException("End of input detected. Close the session."));
- this.closed = true;
}
}
this.sendErrorMessage(error);
if (error == PCEPErrors.CAPABILITY_NOT_SUPPORTED) {
this.unknownMessagesTimes.add(ct);
- while ( ct - this.unknownMessagesTimes.peek() > MINUTE) {
+ while (ct - this.unknownMessagesTimes.peek() > MINUTE) {
this.unknownMessagesTimes.poll();
}
if (this.unknownMessagesTimes.size() > this.maxUnknownMessages) {
* @param msg incoming message
*/
public synchronized void handleMessage(final Message msg) {
- if (this.closed) {
+ if (this.closed.get()) {
LOG.debug("PCEP Session {} is already closed, skip handling incoming message {}", this, msg);
return;
}
return this.sessionState.getPeerPref();
}
- @Override
- public Class<? extends DataContainer> getImplementedInterface() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void resetStats() {
- this.sessionState.reset();
- }
-
@Override
public final void channelInactive(final ChannelHandlerContext ctx) {
LOG.debug("Channel {} inactive.", ctx.channel());
private final AbstractPCEPSessionNegotiatorFactory negFactory;
private final PCEPPeerProposal peerProposal;
- public PCEPSessionNegotiator(final Channel channel, final Promise<PCEPSessionImpl> promise, final PCEPSessionListenerFactory factory,
+ public PCEPSessionNegotiator(final Channel channel, final Promise<PCEPSessionImpl> promise,
+ final PCEPSessionListenerFactory factory,
final AbstractPCEPSessionNegotiatorFactory negFactory, final PCEPPeerProposal peerProposal) {
super(promise, channel);
this.factory = factory;
}
final Short sessionId = sessionReg.nextSession(clientAddress);
- final AbstractPCEPSessionNegotiator n = this.negFactory.createNegotiator(this.promise, this.factory.getSessionListener(),
+ final AbstractPCEPSessionNegotiator n = this.negFactory
+ .createNegotiator(this.promise, this.factory.getSessionListener(),
this.channel, sessionId, this.peerProposal);
sessionReg.putSessionReference(clientAddress, new SessionReference() {
import io.netty.channel.Channel;
import java.net.InetSocketAddress;
import org.opendaylight.protocol.util.StatisticsUtil;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev141006.pcep.session.state.LocalPref;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev141006.pcep.session.state.LocalPrefBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev141006.pcep.session.state.Messages;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev141006.pcep.session.state.MessagesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev141006.pcep.session.state.PeerPref;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev141006.pcep.session.state.PeerPrefBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev141006.pcep.session.state.messages.ErrorMessagesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev141006.pcep.session.state.messages.error.messages.LastReceivedErrorBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev141006.pcep.session.state.messages.error.messages.LastSentErrorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.error.messages.grouping.ErrorMessagesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.error.messages.grouping.error.messages.LastReceivedErrorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.error.messages.grouping.error.messages.LastSentErrorBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.LocalPref;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.LocalPrefBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.Messages;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.MessagesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.PeerPref;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.PeerPrefBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.PcerrMessage;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.Open;
private final ErrorMessagesBuilder errorsBuilder;
private final MessagesBuilder msgsBuilder;
- public PCEPSessionState(final Open remoteOpen, final Open localOpen, final Channel channel) {
+ PCEPSessionState(final Open remoteOpen, final Open localOpen, final Channel channel) {
requireNonNull(remoteOpen);
requireNonNull(localOpen);
requireNonNull(channel);
this.msgsBuilder = new MessagesBuilder();
}
- public Messages getMessages(final int unknownMessagesCount) {
+ Messages getMessages(final int unknownMessagesCount) {
this.errorsBuilder.setReceivedErrorMsgCount(this.receivedErrMsgCount);
this.errorsBuilder.setSentErrorMsgCount(this.sentErrMsgCount);
this.errorsBuilder.setLastReceivedError(this.lastReceivedErrorBuilder.build());
return this.msgsBuilder.build();
}
- public void reset() {
+ void reset() {
this.receivedMsgCount = 0;
this.sentMsgCount = 0;
this.receivedErrMsgCount = 0;
return this.localPref;
}
- public PeerPref getPeerPref() {
+ PeerPref getPeerPref() {
return this.peerPref;
}
- public void setLastSentError(final Message msg) {
+ void setLastSentError(final Message msg) {
this.sentErrMsgCount++;
final ErrorObject errObj = getErrorObject(msg);
this.lastSentErrorBuilder.setErrorType(errObj.getType());
this.lastSentErrorBuilder.setErrorValue(errObj.getValue());
}
- public void setLastReceivedError(final Message msg) {
+ void setLastReceivedError(final Message msg) {
final ErrorObject errObj = getErrorObject(msg);
this.receivedErrMsgCount++;
this.lastReceivedErrorBuilder.setErrorType(errObj.getType());
this.lastReceivedErrorBuilder.setErrorValue(errObj.getValue());
}
- public void updateLastReceivedMsg() {
+ void updateLastReceivedMsg() {
this.receivedMsgCount++;
}
- public void updateLastSentMsg() {
+ void updateLastSentMsg() {
this.lastSentMsgTimestamp = StatisticsUtil.getCurrentTimestampInSeconds();
this.sentMsgCount++;
}
private static ErrorObject getErrorObject(final Message msg) {
requireNonNull(msg);
- final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.PcerrMessage errMsg =
- ((PcerrMessage) msg).getPcerrMessage();
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message
+ .PcerrMessage errMsg = ((PcerrMessage) msg).getPcerrMessage();
return errMsg.getErrors().get(errMsg.getErrors().size() - 1).getErrorObject();
}
import org.opendaylight.protocol.pcep.TerminationReason;
import org.opendaylight.protocol.pcep.impl.spi.Util;
import org.opendaylight.protocol.pcep.spi.PCEPErrors;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev141006.pcep.session.state.LocalPref;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev141006.pcep.session.state.Messages;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev141006.pcep.session.state.PeerPref;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.stats.rev141006.pcep.session.state.messages.ErrorMessages;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Pcerr;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Pcreq;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.PcreqBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.error.messages.grouping.ErrorMessages;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.LocalPref;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.Messages;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.PeerPref;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.CloseMessage;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcep.error.object.ErrorObject;
Assert.assertEquals(1, this.listener.messages.size());
Assert.assertTrue(this.channel.isActive());
Mockito.verify(this.channel, Mockito.times(1)).close();
-
- this.session.resetStats();
- Assert.assertEquals(0, this.session.getMessages().getReceivedMsgCount().longValue());
}
@Test
<artifactId>pcep-auto-bandwidth-extension</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>pcep-topology-stats</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<!-- PCEP Features artifacts -->
<dependency>
- <groupId>org.opendaylight.bgpcep</groupId>
+ <groupId>${project.groupId}</groupId>
<artifactId>features-pcep</artifactId>
<classifier>features</classifier>
<type>xml</type>
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.opendaylight.bgpcep</groupId>
+ <groupId>${project.groupId}</groupId>
<artifactId>odl-bgpcep-pcep</artifactId>
<classifier>features</classifier>
<type>xml</type>
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.opendaylight.bgpcep</groupId>
+ <groupId>${project.groupId}</groupId>
<artifactId>odl-bgpcep-pcep-dependencies</artifactId>
<classifier>features</classifier>
<type>xml</type>
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.opendaylight.bgpcep</groupId>
+ <groupId>${project.groupId}</groupId>
<artifactId>odl-bgpcep-pcep-api</artifactId>
<classifier>features</classifier>
<type>xml</type>
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.opendaylight.bgpcep</groupId>
+ <groupId>${project.groupId}</groupId>
<artifactId>odl-bgpcep-pcep-impl</artifactId>
<classifier>features</classifier>
<type>xml</type>
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.opendaylight.bgpcep</groupId>
+ <groupId>${project.groupId}</groupId>
<artifactId>odl-bgpcep-pcep-topology</artifactId>
<classifier>features</classifier>
<type>xml</type>
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.opendaylight.bgpcep</groupId>
+ <groupId>${project.groupId}</groupId>
<artifactId>odl-bgpcep-pcep-stateful07</artifactId>
<classifier>features</classifier>
<type>xml</type>
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.opendaylight.bgpcep</groupId>
+ <groupId>${project.groupId}</groupId>
<artifactId>odl-bgpcep-pcep-topology-provider</artifactId>
<classifier>features</classifier>
<type>xml</type>
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.opendaylight.bgpcep</groupId>
+ <groupId>${project.groupId}</groupId>
<artifactId>odl-bgpcep-pcep-tunnel-provider</artifactId>
<classifier>features</classifier>
<type>xml</type>
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.opendaylight.bgpcep</groupId>
+ <groupId>${project.groupId}</groupId>
<artifactId>odl-bgpcep-pcep-segment-routing</artifactId>
<classifier>features</classifier>
<type>xml</type>
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>org.opendaylight.bgpcep</groupId>
+ <groupId>${project.groupId}</groupId>
<artifactId>odl-bgpcep-pcep-auto-bandwidth</artifactId>
<classifier>features</classifier>
<type>xml</type>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>odl-bgpcep-pcep-topology-stats</artifactId>
+ <classifier>features</classifier>
+ <type>xml</type>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
</dependencyManagement>
<module>topology-api</module>
<module>topology-spi</module>
<module>topology-provider</module>
+ <module>topology-stats</module>
</modules>
<!--
<groupId>org.opendaylight.yangtools</groupId>
<artifactId>concepts</artifactId>
</dependency>
-
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
// vi: set smarttab et sw=4 tabstop=4:
module network-pcep-topology-config {
yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:topology:pce:config";
+ namespace "urn:opendaylight:params:xml:ns:yang:topology:pcep:config";
prefix pnc;
import network-topology { prefix nt; revision-date 2013-10-21; }
--- /dev/null
+// vi: set smarttab et sw=4 tabstop=4:
+module network-pcep-topology-stats {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:topology:pcep:stats";
+ prefix npts;
+
+ import network-topology { prefix nt; revision-date 2013-10-21; }
+ import network-topology-pcep { prefix pn; revision-date 2017-10-25; }
+ import yang-ext { prefix ext; revision-date 2013-07-09; }
+ import pcep-session-stats { prefix pss; revision-date 2017-11-13; }
+
+ description
+ "This module contains the PCEP stats extensions to base topology model.
+ Copyright (c)2017 AT&T Services, Inc. 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";
+
+ organization "AT&T Services, Inc.";
+ contact "Claudio D. Gasparini <claudio.gasparini@pantheon.sk>";
+
+ revision "2017-11-13" {
+ description
+ "Initial revision.";
+ }
+
+ augment "/nt:network-topology/nt:topology/nt:node" {
+ when "../nt:topology-types/pn:topology-pcep";
+ ext:augment-identifier pcep-topology-node-stats-aug;
+ description "Augment Pcep topology node with session stats";
+
+ uses pss:pcep-session-state-grouping;
+ }
+}
\ No newline at end of file
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import javax.annotation.concurrent.GuardedBy;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.ListenerStateRuntimeMXBean;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.PeerCapabilities;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.ReplyTime;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.SessionState;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.StatefulMessages;
+import org.opendaylight.bgpcep.pcep.topology.provider.session.stats.SessionStateImpl;
+import org.opendaylight.bgpcep.pcep.topology.provider.session.stats.TopologySessionStats;
import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
* @param <S> identifier type of requests
* @param <L> identifier type for LSPs
*/
-public abstract class AbstractTopologySessionListener<S, L> implements TopologySessionListener, ListenerStateRuntimeMXBean {
- protected static final MessageHeader MESSAGE_HEADER = new MessageHeader() {
+public abstract class AbstractTopologySessionListener<S, L> implements TopologySessionListener, TopologySessionStats {
+ static final MessageHeader MESSAGE_HEADER = new MessageHeader() {
private final ProtocolVersion version = new ProtocolVersion((short) 1);
@Override
return this.version;
}
};
- protected static final String MISSING_XML_TAG = "Mandatory XML tags are missing.";
+ static final String MISSING_XML_TAG = "Mandatory XML tags are missing.";
private static final Logger LOG = LoggerFactory.getLogger(AbstractTopologySessionListener.class);
@GuardedBy("this")
- protected final Map<L, String> lsps = new HashMap<>();
+ final Map<L, String> lsps = new HashMap<>();
+ @GuardedBy("this")
+ final SessionStateImpl listenerState;
@GuardedBy("this")
private final Map<S, PCEPRequest> requests = new HashMap<>();
-
@GuardedBy("this")
private final Map<String, ReportedLsp> lspData = new HashMap<>();
private final ServerSessionManager serverSessionManager;
- @GuardedBy("this")
- private final SessionListenerState listenerState;
private InstanceIdentifier<PathComputationClient> pccIdentifier;
private TopologyNodeState nodeState;
+ @GuardedBy("this")
private boolean synced = false;
private PCEPSession session;
private SyncOptimization syncOptimization;
private boolean triggeredResyncInProcess;
- protected AbstractTopologySessionListener(final ServerSessionManager serverSessionManager) {
+ AbstractTopologySessionListener(final ServerSessionManager serverSessionManager) {
this.serverSessionManager = requireNonNull(serverSessionManager);
- this.listenerState = new SessionListenerState();
+ this.listenerState = new SessionStateImpl(this);
}
@Override
this.syncOptimization = new SyncOptimization(session);
- final TopologyNodeState state = this.serverSessionManager.takeNodeState(peerAddress, this, isLspDbRetreived());
+ final TopologyNodeState state = this.serverSessionManager.takeNodeState(peerAddress,
+ this, isLspDbRetreived());
+
// takeNodeState(..) may fail when the server session manager is being restarted due to configuration change
if (state == null) {
LOG.error("Unable to fetch topology node state for PCEP session. Closing session {}", session);
this.onSessionTerminated(session, new PCEPCloseTermination(TerminationReason.UNKNOWN));
return;
}
-
this.session = session;
this.nodeState = state;
+ this.serverSessionManager.bind(this.nodeState.getNodeId(), this.listenerState);
LOG.trace("Peer {} resolved to topology node {}", peerAddress, state.getNodeId());
final boolean isNodePresent = isLspDbRetreived() && initialNodeState != null;
if (isNodePresent) {
loadLspData(initialNodeState, this.lspData, this.lsps, isIncrementalSynchro());
- pccBuilder.setReportedLsp(initialNodeState.getAugmentation(Node1.class).getPathComputationClient().getReportedLsp());
+ pccBuilder.setReportedLsp(initialNodeState.getAugmentation(Node1.class)
+ .getPathComputationClient().getReportedLsp());
}
writeNode(pccBuilder, state, topologyAugment);
this.listenerState.init(session);
Futures.addCallback(trans.submit(), new FutureCallback<Void>() {
@Override
public void onSuccess(final Void result) {
- LOG.trace("Internal state for session {} updated successfully", AbstractTopologySessionListener.this.session);
+ LOG.trace("Internal state for session {} updated successfully",
+ AbstractTopologySessionListener.this.session);
}
@Override
public void onFailure(final Throwable t) {
- LOG.error("Failed to update internal state for session {}, terminating it", AbstractTopologySessionListener.this.session, t);
+ LOG.error("Failed to update internal state for session {}, terminating it",
+ AbstractTopologySessionListener.this.session, t);
AbstractTopologySessionListener.this.session.close(TerminationReason.UNKNOWN);
}
}, MoreExecutors.directExecutor());
}
- protected void updatePccState(final PccSyncState pccSyncState) {
+ void updatePccState(final PccSyncState pccSyncState) {
if (this.nodeState == null) {
LOG.info("Server Session Manager is closed.");
AbstractTopologySessionListener.this.session.close(TerminationReason.UNKNOWN);
}, MoreExecutors.directExecutor());
}
- protected boolean isTriggeredSyncInProcess() {
+ boolean isTriggeredSyncInProcess() {
return this.triggeredResyncInProcess;
}
*/
@GuardedBy("this")
private synchronized void tearDown(final PCEPSession session) {
+
requireNonNull(session);
this.serverSessionManager.releaseNodeState(this.nodeState, session, isLspDbPersisted());
- this.nodeState = null;
+ if (this.nodeState != null) {
+ this.serverSessionManager.unbind(this.nodeState.getNodeId());
+ this.nodeState = null;
+ }
+
try {
if (this.session != null) {
this.session.close();
}
session.close();
- } catch (Exception e) {
+ } catch (final Exception e) {
LOG.error("Session {} cannot be closed.", session, e);
}
this.session = null;
}
}
- protected final synchronized PCEPRequest removeRequest(final S id) {
+ final synchronized PCEPRequest removeRequest(final S id) {
final PCEPRequest ret = this.requests.remove(id);
if (ret != null) {
this.listenerState.processRequestStats(ret.getElapsedMillis());
return ret;
}
- protected final synchronized ListenableFuture<OperationResult> sendMessage(final Message message, final S requestId,
+ final synchronized ListenableFuture<OperationResult> sendMessage(final Message message, final S requestId,
final Metadata metadata) {
final io.netty.util.concurrent.Future<Void> f = this.session.sendMessage(message);
this.listenerState.updateStatefulSentMsg(message);
*/
protected abstract boolean onMessage(MessageContext ctx, Message message);
- protected final String lookupLspName(final L id) {
+ final String lookupLspName(final L id) {
requireNonNull(id, "ID parameter null.");
return this.lsps.get(id);
}
* @param id InstanceIdentifier of the node
* @return null if the node does not exists, or operational data
*/
- protected final synchronized <T extends DataObject> ListenableFuture<Optional<T>> readOperationalData(final InstanceIdentifier<T> id) {
+ final synchronized <T extends DataObject> ListenableFuture<Optional<T>>
+ readOperationalData(final InstanceIdentifier<T> id) {
if (this.nodeState == null) {
return null;
}
protected abstract Object validateReportedLsp(final Optional<ReportedLsp> rep, final LspId input);
- protected abstract void loadLspData(final Node node, final Map<String, ReportedLsp> lspData, final Map<L, String> lsps, final boolean incrementalSynchro);
+ protected abstract void loadLspData(final Node node, final Map<String, ReportedLsp> lspData,
+ final Map<L, String> lsps, final boolean incrementalSynchro);
- protected final boolean isLspDbPersisted() {
+ final boolean isLspDbPersisted() {
if (this.syncOptimization != null) {
return this.syncOptimization.isSyncAvoidanceEnabled();
}
return false;
}
- protected final boolean isLspDbRetreived() {
+ final boolean isLspDbRetreived() {
if (this.syncOptimization != null) {
return this.syncOptimization.isDbVersionPresent();
}
*
* @return
*/
- protected final boolean isIncrementalSynchro() {
+ final boolean isIncrementalSynchro() {
if (this.syncOptimization != null) {
return this.syncOptimization.isSyncAvoidanceEnabled() && this.syncOptimization.isDeltaSyncEnabled();
}
return false;
}
- protected final boolean isTriggeredInitialSynchro() {
+ final boolean isTriggeredInitialSynchro() {
if (this.syncOptimization != null) {
return this.syncOptimization.isTriggeredInitSyncEnabled();
}
return false;
}
- protected final boolean isTriggeredReSyncEnabled() {
+ final boolean isTriggeredReSyncEnabled() {
if (this.syncOptimization != null) {
return this.syncOptimization.isTriggeredReSyncEnabled();
}
return false;
}
- protected synchronized SessionListenerState getSessionListenerState() {
- return this.listenerState;
- }
-
@Override
- public synchronized Integer getDelegatedLspsCount() {
+ public int getDelegatedLspsCount() {
return Math.toIntExact(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
}
@Override
- public Boolean getSynchronized() {
+ public synchronized boolean isSessionSynchronized() {
return this.synced;
}
- @Override
- public StatefulMessages getStatefulMessages() {
- return this.listenerState.getStatefulMessages();
- }
-
- @Override
- public synchronized ReplyTime getReplyTime() {
- return this.listenerState.getReplyTime();
- }
-
- @Override
- public synchronized PeerCapabilities getPeerCapabilities() {
- return this.listenerState.getPeerCapabilities();
- }
-
@Override
public synchronized ListenableFuture<RpcResult<Void>> tearDownSession(final TearDownSessionInput input) {
close();
return Futures.immediateFuture(RpcResultBuilder.<Void>success().build());
}
- @Override
- public synchronized SessionState getSessionState() {
- return this.listenerState.getSessionState(this.session);
- }
-
- @Override
- public synchronized String getPeerId() {
- return this.session.getPeerPref().getIpAddress();
- }
-
- protected static final class MessageContext {
+ static final class MessageContext {
private final Collection<PCEPRequest> requests = new ArrayList<>();
private final WriteTransaction trans;
private static final Logger LOG = LoggerFactory.getLogger(PCEPTopologyProvider.class);
private static final String STATEFUL_NOT_DEFINED = "Stateful capability not defined, aborting PCEP Topology" +
- " Provider instantiation";
+ " Provider instantiation";
private final InstanceIdentifier<Topology> topology;
private final ServerSessionManager manager;
private final InetSocketAddress address;
private Channel channel;
public static PCEPTopologyProvider create(final PCEPTopologyProviderDependenciesProvider dependenciesProvider,
- final PCEPTopologyConfigDependencies configDependencies) {
+ final PCEPTopologyConfigDependencies configDependencies) {
final List<PCEPCapability> capabilities = dependenciesProvider.getPCEPDispatcher()
- .getPCEPSessionNegotiatorFactory().getPCEPSessionProposalFactory().getCapabilities();
+ .getPCEPSessionNegotiatorFactory().getPCEPSessionProposalFactory().getCapabilities();
boolean statefulCapability = false;
for (final PCEPCapability capability : capabilities) {
if (capability.isStateful()) {
}
final InstanceIdentifier<Topology> topology = InstanceIdentifier.builder(NetworkTopology.class)
- .child(Topology.class, new TopologyKey(configDependencies.getTopologyId())).build();
- final ServerSessionManager manager = new ServerSessionManager(dependenciesProvider.getDataBroker(), topology,
- listenerFactory, configDependencies.getRpcTimeout());
+ .child(Topology.class, new TopologyKey(configDependencies.getTopologyId())).build();
+ final ServerSessionManager manager = new ServerSessionManager(
+ dependenciesProvider.getDataBroker(),
+ topology,
+ listenerFactory,
+ dependenciesProvider.getStateRegistry(),
+ configDependencies.getRpcTimeout());
return new PCEPTopologyProvider(configDependencies.getAddress(), configDependencies.getKeys(),
- dependenciesProvider, topology, manager, configDependencies.getSchedulerDependency());
+ dependenciesProvider, topology, manager, configDependencies.getSchedulerDependency());
}
private PCEPTopologyProvider(final InetSocketAddress address, final KeyMapping keys,
- final PCEPTopologyProviderDependenciesProvider dependenciesProvider,
- final InstanceIdentifier<Topology> topology, final ServerSessionManager manager,
- final InstructionScheduler scheduler) {
+ final PCEPTopologyProviderDependenciesProvider dependenciesProvider,
+ final InstanceIdentifier<Topology> topology, final ServerSessionManager manager,
+ final InstructionScheduler scheduler) {
super(topology);
this.dependenciesProvider = requireNonNull(dependenciesProvider);
this.address = address;
final RpcProviderRegistry rpcRegistry = this.dependenciesProvider.getRpcProviderRegistry();
this.element = requireNonNull(rpcRegistry
- .addRoutedRpcImplementation(NetworkTopologyPcepService.class, new TopologyRPCs(this.manager)));
+ .addRoutedRpcImplementation(NetworkTopologyPcepService.class, new TopologyRPCs(this.manager)));
this.element.registerPath(NetworkTopologyContext.class, this.topology);
this.network = requireNonNull(rpcRegistry
- .addRoutedRpcImplementation(NetworkTopologyPcepProgrammingService.class,
- new TopologyProgramming(this.scheduler, this.manager)));
+ .addRoutedRpcImplementation(NetworkTopologyPcepProgrammingService.class,
+ new TopologyProgramming(this.scheduler, this.manager)));
this.network.registerPath(NetworkTopologyContext.class, this.topology);
try {
this.manager.instantiateServiceInstance().get();
final ChannelFuture channelFuture = this.dependenciesProvider.getPCEPDispatcher()
- .createServer(this.address, this.keys, this.manager, this.manager);
+ .createServer(this.address, this.keys, this.manager, this.manager);
channelFuture.get();
this.channel = channelFuture.channel();
} catch (final Exception e) {
public ListenableFuture<Void> closeServiceInstance() {
//FIXME return also channelClose once ListenableFuture implements wildcard
this.channel.close().addListener((ChannelFutureListener) future ->
- checkArgument(future.isSuccess(), "Channel failed to close: %s", future.cause()));
+ checkArgument(future.isSuccess(), "Channel failed to close: %s", future.cause()));
if (this.network != null) {
this.network.close();
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.bgpcep.pcep.topology.spi.stats.TopologySessionStatsRegistry;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
import org.opendaylight.protocol.pcep.PCEPSession;
import org.opendaylight.protocol.pcep.PCEPSessionListener;
import org.opendaylight.protocol.pcep.PCEPSessionListenerFactory;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.PcepSessionState;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.open.TlvsBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.AddLspArgs;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.EnsureLspOperationalInput;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyBuilder;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.TopologyTypesBuilder;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.opendaylight.yangtools.yang.common.RpcError;
import org.opendaylight.yangtools.yang.common.RpcResult;
import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-/**
- *
- */
-final class ServerSessionManager implements PCEPSessionListenerFactory, TopologySessionRPCs, PCEPPeerProposal {
+final class ServerSessionManager implements PCEPSessionListenerFactory, TopologySessionRPCs, PCEPPeerProposal,
+ TopologySessionStatsRegistry {
private static final Logger LOG = LoggerFactory.getLogger(ServerSessionManager.class);
private static final long DEFAULT_HOLD_STATE_NANOS = TimeUnit.MINUTES.toNanos(5);
private static final String FAILURE_MSG = "Failed to find session";
@VisibleForTesting
- public final AtomicBoolean isClosed = new AtomicBoolean(false);
+ final AtomicBoolean isClosed = new AtomicBoolean(false);
@GuardedBy("this")
private final Map<NodeId, TopologySessionListener> nodes = new HashMap<>();
@GuardedBy("this")
private final DataBroker broker;
private final PCEPStatefulPeerProposal peerProposal;
private final short rpcTimeout;
+ private final TopologySessionStatsRegistry statsRegistry;
- public ServerSessionManager(final DataBroker broker, final InstanceIdentifier<Topology> topology,
- final TopologySessionListenerFactory listenerFactory, final short rpcTimeout) {
+ public ServerSessionManager(final DataBroker broker,
+ final InstanceIdentifier<Topology> topology,
+ final TopologySessionListenerFactory listenerFactory,
+ final TopologySessionStatsRegistry statsRegistry,
+ final short rpcTimeout) {
this.broker = requireNonNull(broker);
this.topology = requireNonNull(topology);
+ this.statsRegistry = requireNonNull(statsRegistry);
this.listenerFactory = requireNonNull(listenerFactory);
this.peerProposal = PCEPStatefulPeerProposal.createStatefulPeerProposal(this.broker, this.topology);
this.rpcTimeout = rpcTimeout;
short getRpcTimeout() {
return this.rpcTimeout;
}
+
+ @Override
+ public synchronized void bind(final KeyedInstanceIdentifier<Node, NodeKey> nodeId,
+ final PcepSessionState sessionState) {
+ this.statsRegistry.bind(nodeId, sessionState);
+ }
+
+ @Override
+ public synchronized void unbind(final KeyedInstanceIdentifier<Node, NodeKey> nodeId) {
+ this.statsRegistry.unbind(nodeId);
+ }
}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014 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.bgpcep.pcep.topology.provider;
-
-import static java.util.Objects.requireNonNull;
-
-import com.google.common.base.Stopwatch;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.LongAdder;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.ErrorMessages;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.LastReceivedError;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.LastSentError;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.LocalPref;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.Messages;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.PeerCapabilities;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.PeerPref;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.ReplyTime;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.SessionState;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.StatefulMessages;
-import org.opendaylight.protocol.pcep.PCEPSession;
-import org.opendaylight.protocol.util.StatisticsUtil;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev171025.Pcinitiate;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.Pcupd;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
-
-final class SessionListenerState {
- private final LongAdder lastReceivedRptMsgTimestamp = new LongAdder();
- private final LongAdder receivedRptMsgCount = new LongAdder();
- private final LongAdder sentUpdMsgCount = new LongAdder();
- private final LongAdder sentInitMsgCount = new LongAdder();
- private PeerCapabilities capa;
- private LocalPref localPref;
- private PeerPref peerPref;
- private final Stopwatch sessionUpDuration;
-
- private final LongAdder minReplyTime = new LongAdder();
- private final LongAdder maxReplyTime = new LongAdder();
- private final LongAdder totalTime = new LongAdder();
- private final LongAdder reqCount = new LongAdder();
-
- SessionListenerState() {
- this.sessionUpDuration = Stopwatch.createUnstarted();
- this.capa = new PeerCapabilities();
- }
-
- synchronized void init(final PCEPSession session) {
- requireNonNull(session);
- this.localPref = getLocalPref(session.getLocalPref());
- this.peerPref = getPeerPref(session.getPeerPref());
- this.sessionUpDuration.start();
- }
-
- synchronized void processRequestStats(final long duration) {
- if (this.minReplyTime.longValue() == 0) {
- this.minReplyTime.reset();
- this.minReplyTime.add(duration);
- } else if (duration < this.minReplyTime.longValue()) {
- this.minReplyTime.reset();
- this.minReplyTime.add(duration);
- }
- if (duration > this.maxReplyTime.longValue()) {
- this.maxReplyTime.reset();
- this.maxReplyTime.add(duration);
- }
- this.totalTime.add(duration);
- this.reqCount.increment();
- }
-
- synchronized StatefulMessages getStatefulMessages() {
- final StatefulMessages msgs = new StatefulMessages();
- msgs.setLastReceivedRptMsgTimestamp(this.lastReceivedRptMsgTimestamp.longValue());
- msgs.setReceivedRptMsgCount(this.receivedRptMsgCount.longValue());
- msgs.setSentInitMsgCount(this.sentInitMsgCount.longValue());
- msgs.setSentUpdMsgCount(this.sentUpdMsgCount.longValue());
- return msgs;
- }
-
- synchronized ReplyTime getReplyTime() {
- final ReplyTime time = new ReplyTime();
- long avg = 0;
- if (this.reqCount.longValue() != 0) {
- avg = Math.round((double)this.totalTime.longValue()/this.reqCount.longValue());
- }
- time.setAverageTime(avg);
- time.setMaxTime(this.maxReplyTime.longValue());
- time.setMinTime(this.minReplyTime.longValue());
- return time;
- }
-
- synchronized PeerCapabilities getPeerCapabilities() {
- return this.capa;
- }
-
- synchronized SessionState getSessionState(final PCEPSession session) {
- requireNonNull(session);
- final SessionState state = new SessionState();
- state.setLocalPref(this.localPref);
- state.setPeerPref(this.peerPref);
- state.setMessages(getMessageStats(session.getMessages()));
- state.setSessionDuration(StatisticsUtil.formatElapsedTime(this.sessionUpDuration.elapsed(TimeUnit.SECONDS)));
- return state;
- }
-
- synchronized void setPeerCapabilities(final PeerCapabilities capabilities) {
- this.capa = requireNonNull(capabilities);
- }
-
- synchronized void updateLastReceivedRptMsg() {
- this.lastReceivedRptMsgTimestamp.reset();
- this.lastReceivedRptMsgTimestamp.add(StatisticsUtil.getCurrentTimestampInSeconds());
- this.receivedRptMsgCount.increment();
- }
-
- synchronized void updateStatefulSentMsg(final Message msg) {
- if (msg instanceof Pcinitiate) {
- this.sentInitMsgCount.increment();
- } else if (msg instanceof Pcupd) {
- this.sentUpdMsgCount.increment();
- }
- }
-
- private static LocalPref getLocalPref(final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
- .controller.pcep.stats.rev141006.pcep.session.state.LocalPref localPref) {
- final LocalPref local = new LocalPref();
- local.setDeadtimer(localPref.getDeadtimer());
- local.setIpAddress(localPref.getIpAddress());
- local.setKeepalive(localPref.getKeepalive());
- local.setSessionId(localPref.getSessionId());
- return local;
- }
-
- private static PeerPref getPeerPref(final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
- .controller.pcep.stats.rev141006.pcep.session.state.PeerPref peerPref) {
- final PeerPref peer = new PeerPref();
- peer.setDeadtimer(peerPref.getDeadtimer());
- peer.setIpAddress(peerPref.getIpAddress());
- peer.setKeepalive(peerPref.getKeepalive());
- peer.setSessionId(peerPref.getSessionId());
- return peer;
- }
-
- private static Messages getMessageStats(final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
- .controller.pcep.stats.rev141006.pcep.session.state.Messages messages) {
- final LastReceivedError lastReceivedError = new LastReceivedError();
- lastReceivedError.setErrorType(messages.getErrorMessages().getLastReceivedError().getErrorType());
- lastReceivedError.setErrorValue(messages.getErrorMessages().getLastReceivedError().getErrorValue());
- final LastSentError lastSentError = new LastSentError();
- lastSentError.setErrorType(messages.getErrorMessages().getLastSentError().getErrorType());
- lastSentError.setErrorValue(messages.getErrorMessages().getLastSentError().getErrorValue());
- final ErrorMessages errMsgs = new ErrorMessages();
- errMsgs.setLastReceivedError(lastReceivedError);
- errMsgs.setLastSentError(lastSentError);
- errMsgs.setReceivedErrorMsgCount(messages.getErrorMessages().getReceivedErrorMsgCount());
- errMsgs.setSentErrorMsgCount(messages.getErrorMessages().getSentErrorMsgCount());
- final Messages msgs = new Messages();
- msgs.setErrorMessages(errMsgs);
- msgs.setLastSentMsgTimestamp(messages.getLastSentMsgTimestamp());
- msgs.setReceivedMsgCount(messages.getReceivedMsgCount());
- msgs.setSentMsgCount(messages.getSentMsgCount());
- msgs.setUnknownMsgReceived(msgs.getUnknownMsgReceived());
- return msgs;
- }
-}
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import javax.annotation.concurrent.GuardedBy;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.PeerCapabilities;
import org.opendaylight.protocol.pcep.PCEPSession;
import org.opendaylight.protocol.pcep.spi.PCEPErrors;
import org.opendaylight.protocol.pcep.spi.PSTUtil;
@GuardedBy("this")
private final List<PlspId> staleLsps = new ArrayList<>();
+ private AtomicBoolean statefulCapability = new AtomicBoolean(false);
+ private AtomicBoolean lspUpdateCapability = new AtomicBoolean(false);
+ private AtomicBoolean initiationCapability = new AtomicBoolean(false);
+
/**
* Creates a new stateful topology session listener for given server session manager.
*
if (tlvs != null && tlvs.getAugmentation(Tlvs1.class) != null) {
final Stateful stateful = tlvs.getAugmentation(Tlvs1.class).getStateful();
if (stateful != null) {
- getSessionListenerState().setPeerCapabilities(getCapabilities(stateful));
+ setStatefulCapabilities(stateful);
pccBuilder.setReportedLsp(Collections.emptyList());
if (isSynchronized()) {
pccBuilder.setStateSync(PccSyncState.Synchronized);
public synchronized ListenableFuture<OperationResult> triggerSync(final TriggerSyncArgs input) {
if (isTriggeredInitialSynchro() && !isSynchronized()) {
return triggerSynchronization(input);
- } else if (getSynchronized() && isTriggeredReSyncEnabled()) {
+ } else if (isSessionSynchronized() && isTriggeredReSyncEnabled()) {
Preconditions.checkArgument(input != null && input.getNode() != null, MISSING_XML_TAG);
if (input.getName() == null) {
return triggerResyncronization(input);
final Optional<PathSetupType> maybePST = getPST(rep);
if (maybePST.isPresent()) {
srpBuilder.setTlvs(
- new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.srp.object.srp.TlvsBuilder()
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful
+ .rev171025.srp.object.srp.TlvsBuilder()
.setPathSetupType(maybePST.get()).build());
}
}
private boolean handleErrorMessage(final PcerrMessage message) {
- final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message.PcerrMessage errMsg = message.getPcerrMessage();
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcerr.message
+ .PcerrMessage errMsg = message.getPcerrMessage();
if (errMsg.getErrorType() instanceof StatefulCase) {
final StatefulCase stat = (StatefulCase) errMsg.getErrorType();
for (final Srps srps : stat.getStateful().getSrps()) {
String name = lookupLspName(plspid);
if (lsp.getTlvs() != null && lsp.getTlvs().getSymbolicPathName() != null) {
- name = StandardCharsets.UTF_8.decode(ByteBuffer.wrap(lsp.getTlvs().getSymbolicPathName().getPathName().getValue())).toString();
+ name = StandardCharsets.UTF_8.decode(ByteBuffer.wrap(lsp.getTlvs().getSymbolicPathName().getPathName()
+ .getValue())).toString();
}
//get LspDB from LSP and write it to pcc's node
final LspDbVersion lspDbVersion = geLspDbVersionTlv(lsp);
}
private static LspDbVersion geLspDbVersionTlv(final Lsp lsp) {
- final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.lsp.object.lsp.Tlvs tlvs = lsp.getTlvs();
- if (tlvs != null && tlvs.getAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev171025.Tlvs1.class) != null) {
- return tlvs.getAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev171025.Tlvs1.class).getLspDbVersion();
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.lsp.object
+ .lsp.Tlvs tlvs = lsp.getTlvs();
+ if (tlvs != null && tlvs.getAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
+ .controller.pcep.sync.optimizations.rev171025.Tlvs1.class) != null) {
+ return tlvs.getAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller
+ .pcep.sync.optimizations.rev171025.Tlvs1.class).getLspDbVersion();
}
return null;
}
private Path buildPath(final Reports report, final Srp srp, final Lsp lsp) {
- final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.pcep.client.attributes.path.computation.client.reported.lsp.PathBuilder pb = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.pcep.client.attributes.path.computation.client.reported.lsp.PathBuilder();
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.pcep.client
+ .attributes.path.computation.client.reported.lsp.PathBuilder pb = new org.opendaylight.yang.gen.v1
+ .urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.pcep.client.attributes.path.computation
+ .client.reported.lsp.PathBuilder();
if (report.getPath() != null) {
pb.fieldsFrom(report.getPath());
}
pst = null;
}
pb.addAugmentation(Path1.class, p1Builder.build());
- final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.lsp.object.lsp.Tlvs tlvs = report.getLsp().getTlvs();
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.lsp
+ .object.lsp.Tlvs tlvs = report.getLsp().getTlvs();
if (tlvs != null) {
if (tlvs.getLspIdentifiers() != null) {
pb.setLspId(tlvs.getLspIdentifiers().getLspId());
} else if (!PSTUtil.isDefaultPST(pst)) {
- pb.setLspId(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820.LspId(lsp.getPlspId().getValue()));
+ pb.setLspId(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.rsvp.rev150820
+ .LspId(lsp.getPlspId().getValue()));
}
}
return pb.build();
if (!(message instanceof PcrptMessage)) {
return true;
}
- getSessionListenerState().updateLastReceivedRptMsg();
- final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.pcrpt.message.PcrptMessage rpt = ((PcrptMessage) message).getPcrptMessage();
+ this.listenerState.updateLastReceivedRptMsg();
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.pcrpt
+ .message.PcrptMessage rpt = ((PcrptMessage) message).getPcrptMessage();
for (final Reports report : rpt.getReports()) {
if (!manageNextReport(report, ctx)) {
return false;
@Override
public ListenableFuture<OperationResult> apply(final Optional<ReportedLsp> rep) {
if (rep.isPresent()) {
- LOG.debug("Node {} already contains lsp {} at {}", this.input.getNode(), this.input.getName(), this.lsp);
+ LOG.debug("Node {} already contains lsp {} at {}", this.input.getNode(), this.input.getName(),
+ this.lsp);
return OperationResults.createUnsent(PCEPErrors.USED_SYMBOLIC_PATH_NAME).future();
}
- if (!getPeerCapabilities().getInstantiation()) {
+ if (!Stateful07TopologySessionListener.this.initiationCapability.get()) {
return OperationResults.createUnsent(PCEPErrors.CAPABILITY_NOT_SUPPORTED).future();
}
tlvsBuilder = new TlvsBuilder();
}
tlvsBuilder.setSymbolicPathName(
- new SymbolicPathNameBuilder().setPathName(new SymbolicPathName(this.input.getName().getBytes(StandardCharsets.UTF_8))).build());
+ new SymbolicPathNameBuilder().setPathName(new SymbolicPathName(this.input.getName()
+ .getBytes(StandardCharsets.UTF_8))).build());
final SrpBuilder srpBuilder = new SrpBuilder();
srpBuilder.setOperationId(nextRequest());
srpBuilder.setProcessingRule(Boolean.TRUE);
if (!PSTUtil.isDefaultPST(args.getPathSetupType())) {
srpBuilder.setTlvs(
- new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.srp.object.srp.TlvsBuilder()
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf
+ .stateful.rev171025.srp.object.srp.TlvsBuilder()
.setPathSetupType(args.getPathSetupType()).build());
}
rb.setSrp(srpBuilder.build());
- rb.setLsp(new LspBuilder().setAdministrative(inputLsp.isAdministrative()).setDelegate(inputLsp.isDelegate()).setPlspId(
- new PlspId(0L)).setTlvs(tlvsBuilder.build()).build());
+ rb.setLsp(new LspBuilder().setAdministrative(inputLsp.isAdministrative()).setDelegate(
+ inputLsp.isDelegate()).setPlspId(new PlspId(0L)).setTlvs(tlvsBuilder.build()).build());
final PcinitiateMessageBuilder ib = new PcinitiateMessageBuilder(MESSAGE_HEADER);
ib.setRequests(Collections.singletonList(rb.build()));
// Send the message
- return sendMessage(new PcinitiateBuilder().setPcinitiateMessage(ib.build()).build(), rb.getSrp().getOperationId(),
- this.input.getArguments().getMetadata());
+ return sendMessage(new PcinitiateBuilder().setPcinitiateMessage(ib.build()).build(),
+ rb.getSrp().getOperationId(), this.input.getArguments().getMetadata());
}
}
@Override
public synchronized ListenableFuture<OperationResult> addLsp(final AddLspArgs input) {
- Preconditions.checkArgument(input != null && input.getName() != null && input.getNode() != null && input.getArguments() != null, MISSING_XML_TAG);
+ Preconditions.checkArgument(input != null && input.getName() != null && input.getNode() != null
+ && input.getArguments() != null, MISSING_XML_TAG);
LOG.trace("AddLspArgs {}", input);
// Make sure there is no such LSP
final InstanceIdentifier<ReportedLsp> lsp = lspIdentifier(input.getName());
@Override
public synchronized ListenableFuture<OperationResult> removeLsp(final RemoveLspArgs input) {
- Preconditions.checkArgument(input != null && input.getName() != null && input.getNode() != null, MISSING_XML_TAG);
+ Preconditions.checkArgument(input != null && input.getName() != null
+ && input.getNode() != null, MISSING_XML_TAG);
LOG.trace("RemoveLspArgs {}", input);
// Make sure the LSP exists, we need it for PLSP-ID
final InstanceIdentifier<ReportedLsp> lsp = lspIdentifier(input.getName());
final PcinitiateMessageBuilder ib = new PcinitiateMessageBuilder(MESSAGE_HEADER);
final Requests rb = buildRequest(rep, reportedLsp);
ib.setRequests(Collections.singletonList(rb));
- return sendMessage(new PcinitiateBuilder().setPcinitiateMessage(ib.build()).build(), rb.getSrp().getOperationId(), null);
+ return sendMessage(new PcinitiateBuilder().setPcinitiateMessage(ib.build()).build(),
+ rb.getSrp().getOperationId(), null);
});
}
private Requests buildRequest(final Optional<ReportedLsp> rep, final Lsp reportedLsp) {
// Build the request and send it
final RequestsBuilder rb = new RequestsBuilder();
- final SrpBuilder srpBuilder = new SrpBuilder().addAugmentation(Srp1.class, new Srp1Builder().setRemove(Boolean.TRUE).build()).setOperationId(nextRequest()).setProcessingRule(Boolean.TRUE);
+ final SrpBuilder srpBuilder = new SrpBuilder().addAugmentation(Srp1.class, new Srp1Builder()
+ .setRemove(Boolean.TRUE).build()).setOperationId(nextRequest()).setProcessingRule(Boolean.TRUE);
final Optional<PathSetupType> maybePST = getPST(rep);
if (maybePST.isPresent()) {
- srpBuilder.setTlvs(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.srp.object.srp.TlvsBuilder()
- .setPathSetupType(maybePST.get())
- .build());
+ srpBuilder.setTlvs(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful
+ .rev171025.srp.object.srp.TlvsBuilder().setPathSetupType(maybePST.get()).build());
}
rb.setSrp(srpBuilder.build());
- rb.setLsp(new LspBuilder().setRemove(Boolean.FALSE).setPlspId(reportedLsp.getPlspId()).setDelegate(reportedLsp.isDelegate()).build());
+ rb.setLsp(new LspBuilder().setRemove(Boolean.FALSE).setPlspId(reportedLsp.getPlspId())
+ .setDelegate(reportedLsp.isDelegate()).build());
return rb.build();
}
if ((args != null && args.getPathSetupType() != null)) {
if (!PSTUtil.isDefaultPST(args.getPathSetupType())) {
srpBuilder.setTlvs(
- new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.srp.object.srp.TlvsBuilder()
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful
+ .rev171025.srp.object.srp.TlvsBuilder()
.setPathSetupType(args.getPathSetupType()).build());
}
} else {
final Optional<PathSetupType> maybePST = getPST(rep);
if (maybePST.isPresent()) {
srpBuilder.setTlvs(
- new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.srp.object.srp.TlvsBuilder()
+ new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful
+ .rev171025.srp.object.srp.TlvsBuilder()
.setPathSetupType(maybePST.get()).build());
}
}
}
}
- private ListenableFuture<OperationResult> redelegate(final Lsp reportedLsp, final Srp srp, final Lsp lsp, final UpdateLspArgs input) {
+ private ListenableFuture<OperationResult> redelegate(final Lsp reportedLsp, final Srp srp, final Lsp lsp,
+ final UpdateLspArgs input) {
// the D bit that was reported decides the type of PCE message sent
requireNonNull(reportedLsp.isDelegate());
final Message msg;
@Override
public synchronized ListenableFuture<OperationResult> updateLsp(final UpdateLspArgs input) {
- Preconditions.checkArgument(input != null && input.getName() != null && input.getNode() != null && input.getArguments() != null, MISSING_XML_TAG);
+ Preconditions.checkArgument(input != null && input.getName() != null && input.getNode() != null
+ && input.getArguments() != null, MISSING_XML_TAG);
LOG.trace("UpdateLspArgs {}", input);
// Make sure the LSP exists
final InstanceIdentifier<ReportedLsp> lsp = lspIdentifier(input.getName());
@Override
public synchronized ListenableFuture<OperationResult> ensureLspOperational(final EnsureLspOperationalInput input) {
- Preconditions.checkArgument(input != null && input.getName() != null && input.getNode() != null && input.getArguments() != null, MISSING_XML_TAG);
+ Preconditions.checkArgument(input != null && input.getName() != null && input.getNode() != null
+ && input.getArguments() != null, MISSING_XML_TAG);
final OperationalStatus op;
final Arguments1 aa = input.getArguments().getAugmentation(Arguments1.class);
if (aa != null) {
return listenableFuture(f, input, op);
}
- private ListenableFuture<OperationResult> listenableFuture(final ListenableFuture<Optional<ReportedLsp>> f, final EnsureLspOperationalInput input, final OperationalStatus op) {
+ private ListenableFuture<OperationResult> listenableFuture(final ListenableFuture<Optional<ReportedLsp>> f,
+ final EnsureLspOperationalInput input, final OperationalStatus op) {
return Futures.transform(f, rep -> {
if (!rep.isPresent()) {
LOG.debug("Node {} does not contain LSP {}", input.getNode(), input.getName());
return Optional.absent();
}
- private static PeerCapabilities getCapabilities(final Stateful stateful) {
- final PeerCapabilities capa = new PeerCapabilities();
- capa.setStateful(true);
- if (stateful.isLspUpdateCapability() != null) {
- capa.setActive(stateful.isLspUpdateCapability());
- }
- final Stateful1 stateful1 = stateful.getAugmentation(Stateful1.class);
- if (stateful1 != null && stateful1.isInitiation() != null) {
- capa.setInstantiation(stateful1.isInitiation());
- }
- return capa;
- }
-
/**
* Recover lspData and mark any LSPs in the LSP database that were previously reported by the PCC as stale
*
* @param incrementalSynchro
*/
@Override
- protected synchronized void loadLspData(final Node node, final Map<String, ReportedLsp> lspData, final Map<PlspId, String> lsps, final boolean incrementalSynchro) {
+ protected synchronized void loadLspData(final Node node, final Map<String, ReportedLsp> lspData,
+ final Map<PlspId, String> lsps, final boolean incrementalSynchro) {
//load node's lsps from DS
final PathComputationClient pcc = node.getAugmentation(Node1.class).getPathComputationClient();
final List<ReportedLsp> reportedLsps = pcc.getReportedLsp();
}
this.staleLsps.clear();
}
+
+ @Override
+ public synchronized boolean isInitiationCapability() {
+ return this.initiationCapability.get();
+ }
+
+ @Override
+ public synchronized boolean isStatefulCapability() {
+ return this.statefulCapability.get();
+ }
+
+ @Override
+ public synchronized boolean isLspUpdateCapability() {
+ return this.lspUpdateCapability.get();
+ }
+
+ private synchronized void setStatefulCapabilities(final Stateful stateful) {
+ this.statefulCapability.set(true);
+ if (stateful.isLspUpdateCapability() != null) {
+ this.lspUpdateCapability.set(stateful.isLspUpdateCapability());
+ }
+ final Stateful1 stateful1 = stateful.getAugmentation(Stateful1.class);
+ if (stateful1 != null && stateful1.isInitiation() != null) {
+ this.initiationCapability.set(stateful1.isInitiation());
+ }
+ }
}
*/
package org.opendaylight.bgpcep.pcep.topology.provider;
-public class Stateful07TopologySessionListenerFactory implements TopologySessionListenerFactory {
+public final class Stateful07TopologySessionListenerFactory implements TopologySessionListenerFactory {
@Override
- public final TopologySessionListener createTopologySessionListener(final ServerSessionManager manager) {
+ public TopologySessionListener createTopologySessionListener(final ServerSessionManager manager) {
return new Stateful07TopologySessionListener(manager);
}
}
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
+import javax.annotation.Nonnull;
import javax.annotation.concurrent.ThreadSafe;
import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
//cache initial node state, if any node was persisted
private Node initialNodeState = null;
- public TopologyNodeState(final DataBroker broker, final InstanceIdentifier<Topology> topology, final NodeId id, final long holdStateNanos) {
+ TopologyNodeState(final DataBroker broker, final InstanceIdentifier<Topology> topology, final NodeId id,
+ final long holdStateNanos) {
Preconditions.checkArgument(holdStateNanos >= 0);
this.nodeId = topology.child(Node.class, new NodeKey(id));
this.holdStateNanos = holdStateNanos;
this.chain = broker.createTransactionChain(this);
}
- public KeyedInstanceIdentifier<Node, NodeKey> getNodeId() {
+ @Nonnull
+ KeyedInstanceIdentifier<Node, NodeKey> getNodeId() {
return this.nodeId;
}
- public synchronized Metadata getLspMetadata(final String name) {
+ synchronized Metadata getLspMetadata(final String name) {
return this.metadata.get(name);
}
- public synchronized void setLspMetadata(final String name, final Metadata value) {
+ synchronized void setLspMetadata(final String name, final Metadata value) {
if (value == null) {
this.metadata.remove(name);
} else {
}
}
- public synchronized void cleanupExcept(final Collection<String> values) {
+ synchronized void cleanupExcept(final Collection<String> values) {
this.metadata.keySet().removeIf(s -> !values.contains(s));
}
- public synchronized void released(final boolean persist) {
+ synchronized void released(final boolean persist) {
// The session went down. Undo all the Topology changes we have done.
// We might want to persist topology node for later re-use.
if (!persist) {
this.lastReleased = System.nanoTime();
}
- public synchronized void taken(final boolean retrieveNode) {
+ synchronized void taken(final boolean retrieveNode) {
final long now = System.nanoTime();
if (now - this.lastReleased > this.holdStateNanos) {
//try to get the topology's node
if (retrieveNode) {
Futures.addCallback(readOperationalData(this.nodeId), new FutureCallback<Optional<Node>>() {
-
@Override
public void onSuccess(final Optional<Node> result) {
if (!result.isPresent()) {
}
}
- public synchronized Node getInitialNodeState() {
+ synchronized Node getInitialNodeState() {
return this.initialNodeState;
}
import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
import org.opendaylight.protocol.concepts.KeyMapping;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.config.rev171025.pcep.config.SessionConfig;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pce.config.rev171025.PcepTopologyTypeConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.config.rev171025.PcepTopologyTypeConfig;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
import javax.annotation.concurrent.GuardedBy;
import org.opendaylight.bgpcep.pcep.topology.provider.PCEPTopologyProvider;
import org.opendaylight.bgpcep.pcep.topology.provider.TopologySessionListenerFactory;
+import org.opendaylight.bgpcep.pcep.topology.spi.stats.TopologySessionStatsRegistry;
import org.opendaylight.bgpcep.topology.DefaultTopologyReference;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
private final RpcProviderRegistry rpcProviderRegistry;
private final BundleContext bundleContext;
private final ClusterSingletonServiceProvider cssp;
+ private final TopologySessionStatsRegistry stateRegistry;
@GuardedBy("this")
private PCEPTopologyProviderBeanCSS pcepTopoProviderCSS;
- public PCEPTopologyProviderBean(final ClusterSingletonServiceProvider cssp, final BundleContext bundleContext,
- final DataBroker dataBroker, final PCEPDispatcher pcepDispatcher, final RpcProviderRegistry rpcProviderRegistry,
- final TopologySessionListenerFactory sessionListenerFactory) {
+ public PCEPTopologyProviderBean(
+ final ClusterSingletonServiceProvider cssp,
+ final BundleContext bundleContext,
+ final DataBroker dataBroker,
+ final PCEPDispatcher pcepDispatcher,
+ final RpcProviderRegistry rpcProviderRegistry,
+ final TopologySessionListenerFactory sessionListenerFactory,
+ final TopologySessionStatsRegistry stateRegistry) {
this.cssp = requireNonNull(cssp);
this.bundleContext = requireNonNull(bundleContext);
this.pcepDispatcher = requireNonNull(pcepDispatcher);
this.dataBroker = requireNonNull(dataBroker);
this.sessionListenerFactory = requireNonNull(sessionListenerFactory);
this.rpcProviderRegistry = requireNonNull(rpcProviderRegistry);
+ this.stateRegistry = requireNonNull(stateRegistry);
final List<PCEPCapability> capabilities = this.pcepDispatcher.getPCEPSessionNegotiatorFactory()
- .getPCEPSessionProposalFactory().getCapabilities();
+ .getPCEPSessionProposalFactory().getCapabilities();
final boolean statefulCapability = capabilities.stream().anyMatch(PCEPCapability::isStateful);
if (!statefulCapability) {
throw new IllegalStateException(STATEFUL_NOT_DEFINED);
synchronized void start(final PCEPTopologyConfigDependencies configDependencies) {
Preconditions.checkState(this.pcepTopoProviderCSS == null,
- "Previous instance %s was not closed.", this);
+ "Previous instance %s was not closed.", this);
try {
this.pcepTopoProviderCSS = new PCEPTopologyProviderBeanCSS(configDependencies);
} catch (final Exception e) {
return this.sessionListenerFactory;
}
+ @Override
+ public TopologySessionStatsRegistry getStateRegistry() {
+ return this.stateRegistry;
+ }
+
private class PCEPTopologyProviderBeanCSS implements ClusterSingletonService, AutoCloseable {
private final ServiceGroupIdentifier sgi;
private ServiceRegistration<?> serviceRegistration;
private boolean serviceInstantiated;
PCEPTopologyProviderBeanCSS(final PCEPTopologyConfigDependencies configDependencies) {
- this.sgi = configDependencies.getSchedulerDependency().getIdentifier();
- this.pcepTopoProvider = PCEPTopologyProvider
- .create(PCEPTopologyProviderBean.this, configDependencies);
+ this.sgi = configDependencies.getSchedulerDependency().getIdentifier();
+ this.pcepTopoProvider = PCEPTopologyProvider
+ .create(PCEPTopologyProviderBean.this, configDependencies);
- final Dictionary<String, String> properties = new Hashtable<>();
- properties.put(PCEPTopologyProvider.class.getName(), configDependencies.getTopologyId().getValue());
- this.serviceRegistration = PCEPTopologyProviderBean.this.bundleContext
+ final Dictionary<String, String> properties = new Hashtable<>();
+ properties.put(PCEPTopologyProvider.class.getName(), configDependencies.getTopologyId().getValue());
+ this.serviceRegistration = PCEPTopologyProviderBean.this.bundleContext
.registerService(DefaultTopologyReference.class.getName(), this.pcepTopoProvider, properties);
LOG.info("PCEP Topology Provider service {} registered", getIdentifier().getValue());
this.cssRegistration = PCEPTopologyProviderBean.this.cssp.registerClusterSingletonService(this);
*/
package org.opendaylight.bgpcep.pcep.topology.provider.config;
+import javax.annotation.Nonnull;
import org.opendaylight.bgpcep.pcep.topology.provider.TopologySessionListenerFactory;
+import org.opendaylight.bgpcep.pcep.topology.spi.stats.TopologySessionStatsRegistry;
import org.opendaylight.controller.md.sal.binding.api.DataBroker;
import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
import org.opendaylight.protocol.pcep.PCEPDispatcher;
*/
public interface PCEPTopologyProviderDependenciesProvider {
/**
- *
* @return PCEPDispatcher
*/
+ @Nonnull
PCEPDispatcher getPCEPDispatcher();
/**
- *
* @return RpcProviderRegistry
*/
+ @Nonnull
RpcProviderRegistry getRpcProviderRegistry();
/**
- *
* @return DataBroker
*/
+ @Nonnull
DataBroker getDataBroker();
/**
- *
* @return TopologySessionListenerFactory
*/
+ @Nonnull
TopologySessionListenerFactory getTopologySessionListenerFactory();
+
+ /**
+ * @return TopologySessionStateRegistry
+ */
+ @Nonnull
+ TopologySessionStatsRegistry getStateRegistry();
}
import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
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.controller.rfc2385.cfg.rev160324.Rfc2385Key;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pce.config.rev171025.PcepNodeConfig;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.config.rev171025.PcepNodeConfig;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.TopologyTypes1;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
--- /dev/null
+/*
+ * Copyright (c) 2014 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.bgpcep.pcep.topology.provider.session.stats;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.base.Stopwatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.LongAdder;
+import org.opendaylight.protocol.pcep.PCEPSessionState;
+import org.opendaylight.protocol.util.StatisticsUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev171025.Pcinitiate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.Pcupd;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev171113.StatefulCapabilitiesStatsAug;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev171113.StatefulCapabilitiesStatsAugBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev171113.StatefulMessagesStatsAug;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev171113.StatefulMessagesStatsAugBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.PcepSessionState;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.LocalPref;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.Messages;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.MessagesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.PeerCapabilities;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.PeerCapabilitiesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.PeerPref;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.reply.time.grouping.ReplyTime;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.reply.time.grouping.ReplyTimeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+
+public final class SessionStateImpl implements PcepSessionState {
+ private final LongAdder lastReceivedRptMsgTimestamp = new LongAdder();
+ private final LongAdder receivedRptMsgCount = new LongAdder();
+ private final LongAdder sentUpdMsgCount = new LongAdder();
+ private final LongAdder sentInitMsgCount = new LongAdder();
+ private final Stopwatch sessionUpDuration;
+
+ private final LongAdder minReplyTime = new LongAdder();
+ private final LongAdder maxReplyTime = new LongAdder();
+ private final LongAdder totalTime = new LongAdder();
+ private final LongAdder reqCount = new LongAdder();
+ private final TopologySessionStats topologySessionStats;
+ private LocalPref localPref;
+ private PeerPref peerPref;
+ private PCEPSessionState pcepSessionState;
+
+ public SessionStateImpl(final TopologySessionStats topologySessionStats) {
+ this.sessionUpDuration = Stopwatch.createUnstarted();
+ this.topologySessionStats = requireNonNull(topologySessionStats);
+ }
+
+ public synchronized void init(final PCEPSessionState session) {
+ requireNonNull(session);
+ this.pcepSessionState = session;
+ this.localPref = session.getLocalPref();
+ this.peerPref = session.getPeerPref();
+ this.sessionUpDuration.start();
+ }
+
+ public synchronized void processRequestStats(final long duration) {
+ if (this.minReplyTime.longValue() == 0) {
+ this.minReplyTime.reset();
+ this.minReplyTime.add(duration);
+ } else if (duration < this.minReplyTime.longValue()) {
+ this.minReplyTime.reset();
+ this.minReplyTime.add(duration);
+ }
+ if (duration > this.maxReplyTime.longValue()) {
+ this.maxReplyTime.reset();
+ this.maxReplyTime.add(duration);
+ }
+ this.totalTime.add(duration);
+ this.reqCount.increment();
+ }
+
+ public synchronized void updateLastReceivedRptMsg() {
+ this.lastReceivedRptMsgTimestamp.reset();
+ this.lastReceivedRptMsgTimestamp.add(StatisticsUtil.getCurrentTimestampInSeconds());
+ this.receivedRptMsgCount.increment();
+ }
+
+ public synchronized void updateStatefulSentMsg(final Message msg) {
+ if (msg instanceof Pcinitiate) {
+ this.sentInitMsgCount.increment();
+ } else if (msg instanceof Pcupd) {
+ this.sentUpdMsgCount.increment();
+ }
+ }
+
+ public synchronized String getSessionDuration() {
+ return StatisticsUtil.formatElapsedTime(this.sessionUpDuration.elapsed(TimeUnit.SECONDS));
+ }
+
+ @Override
+ public synchronized Boolean isSynchronized() {
+ return this.topologySessionStats.isSessionSynchronized();
+ }
+
+ @Override
+ public synchronized PeerCapabilities getPeerCapabilities() {
+ return new PeerCapabilitiesBuilder()
+ .addAugmentation(StatefulCapabilitiesStatsAug.class, createStatefulCapabilities())
+ .build();
+ }
+
+ private synchronized StatefulCapabilitiesStatsAug createStatefulCapabilities() {
+ return new StatefulCapabilitiesStatsAugBuilder()
+ .setActive(this.topologySessionStats.isLspUpdateCapability())
+ .setInstantiation(this.topologySessionStats.isInitiationCapability())
+ .setStateful(this.topologySessionStats.isStatefulCapability())
+ .build();
+ }
+
+ @Override
+ public synchronized Messages getMessages() {
+ return new MessagesBuilder(this.pcepSessionState.getMessages())
+ .setReplyTime(setReplyTime())
+ .addAugmentation(StatefulMessagesStatsAug.class, createStatefulMessages())
+ .build();
+ }
+
+ private synchronized StatefulMessagesStatsAug createStatefulMessages() {
+ return new StatefulMessagesStatsAugBuilder()
+ .setLastReceivedRptMsgTimestamp(this.lastReceivedRptMsgTimestamp.longValue())
+ .setReceivedRptMsgCount(this.receivedRptMsgCount.longValue())
+ .setSentInitMsgCount(this.sentInitMsgCount.longValue())
+ .setSentUpdMsgCount(this.sentUpdMsgCount.longValue())
+ .build();
+ }
+
+ private synchronized ReplyTime setReplyTime() {
+ long avg = 0;
+ if (this.reqCount.longValue() != 0) {
+ avg = Math.round((double) this.totalTime.longValue() / this.reqCount.longValue());
+ }
+ return new ReplyTimeBuilder()
+ .setAverageTime(avg)
+ .setMaxTime(this.maxReplyTime.longValue())
+ .setMinTime(this.minReplyTime.longValue())
+ .build();
+ }
+
+ @Override
+ public synchronized LocalPref getLocalPref() {
+ return this.localPref;
+ }
+
+ @Override
+ public synchronized PeerPref getPeerPref() {
+ return this.peerPref;
+ }
+
+ @Override
+ public synchronized Integer getDelegatedLspsCount() {
+ return this.topologySessionStats.getDelegatedLspsCount();
+ }
+
+ @Override
+ public Class<? extends DataContainer> getImplementedInterface() {
+ return null;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 AT&T AT&T Intellectual Property. 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.bgpcep.pcep.topology.provider.session.stats;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * Provide access to topology session stats without expose variables.
+ */
+@Beta
+public interface TopologySessionStats {
+
+ /**
+ * Returns true if session is synchronized
+ *
+ * @return status
+ */
+ boolean isSessionSynchronized();
+
+ /**
+ * return true if Initiation Capability is advertized
+ *
+ * @return status
+ */
+ boolean isInitiationCapability();
+
+ /**
+ * return true if Stateful Capability is advertized
+ *
+ * @return status
+ */
+ boolean isStatefulCapability();
+
+ /**
+ * return true if Lsp Update Capability is advertized
+ *
+ * @return status
+ */
+ boolean isLspUpdateCapability();
+
+ /**
+ * return the number of delegated LSPs (tunnels) from PCC
+ *
+ * @return status
+ */
+ int getDelegatedLspsCount();
+}
<reference id="clusterSingletonServiceProvider"
interface="org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider"/>
<reference id="intructionFactory" interface="org.opendaylight.bgpcep.programming.spi.InstructionSchedulerFactory"/>
+ <reference id="topologySessionStatsRegistry"
+ interface="org.opendaylight.bgpcep.pcep.topology.spi.stats.TopologySessionStatsRegistry"/>
<bean id="pcepTopologyDeployer"
class="org.opendaylight.bgpcep.pcep.topology.provider.config.PCEPTopologyDeployerImpl"
<argument ref="pcepDispatcher"/>
<argument ref="rpcRegistry"/>
<argument ref="Stateful07TopologySessionListenerFactory"/>
+ <argument ref="topologySessionStatsRegistry"/>
</bean>
</blueprint>
\ No newline at end of file
import network-topology { prefix nt; revision-date 2013-10-21; }
import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
import rpc-context { prefix rpcx; revision-date 2013-06-17; }
- import pcep-session-stats { prefix pcep-stats; revision-date 2014-10-06; }
import rfc2385 { prefix rfc2385; revision-date 2016-03-24; }
organization "Cisco Systems, Inc.";
description "Elapsed time (in d:H:m:s) from session-up until now.";
type string;
}
- uses pcep-stats:pcep-session-state;
}
container peer-capabilities {
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.ListenerStateRuntimeMXBean;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.ListenerStateRuntimeRegistration;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.PCEPTopologyProviderRuntimeMXBean;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.PCEPTopologyProviderRuntimeRegistration;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.PCEPTopologyProviderRuntimeRegistrator;
+import org.opendaylight.bgpcep.pcep.topology.spi.stats.TopologySessionStatsRegistry;
import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest;
import org.opendaylight.protocol.pcep.PCEPSessionListener;
import org.opendaylight.protocol.pcep.impl.DefaultPCEPSessionNegotiator;
extends AbstractConcurrentDataBrokerTest {
private static final String TEST_TOPOLOGY_NAME = "testtopo";
- static final InstanceIdentifier<Topology> TOPO_IID = InstanceIdentifier.builder(NetworkTopology.class).child(
- Topology.class, new TopologyKey(new TopologyId(TEST_TOPOLOGY_NAME))).build();
+ static final InstanceIdentifier<Topology> TOPO_IID = InstanceIdentifier.builder(NetworkTopology.class)
+ .child(Topology.class, new TopologyKey(new TopologyId(TEST_TOPOLOGY_NAME))).build();
private static final String IPV4_MASK = "/32";
static final short DEAD_TIMER = 30;
static final short KEEP_ALIVE = 10;
@Mock
private ChannelFuture channelFuture;
+ @Mock
+ private TopologySessionStatsRegistry statsRegistry;
+
private final Open localPrefs = new OpenBuilder().setDeadTimer((short) 30).setKeepalive((short) 10)
.setSessionId((short) 0).build();
doReturn(this.pipeline).when(this.pipeline).replace(any(ChannelHandler.class), any(String.class),
any(ChannelHandler.class));
doReturn(this.eventLoop).when(this.clientListener).eventLoop();
+ doNothing().when(this.statsRegistry).bind(any(), any());
+ doNothing().when(this.statsRegistry).unbind(any());
doReturn(null).when(this.eventLoop).schedule(any(Runnable.class), any(long.class),
any(TimeUnit.class));
doReturn(true).when(this.clientListener).isActive();
final T listenerFactory = (T) ((Class) ((ParameterizedType) this.getClass().getGenericSuperclass())
.getActualTypeArguments()[0]).newInstance();
- this.manager = new ServerSessionManager(getDataBroker(), TOPO_IID, listenerFactory, RPC_TIMEOUT);
+ this.manager = new ServerSessionManager(getDataBroker(), TOPO_IID, listenerFactory, this.statsRegistry,
+ RPC_TIMEOUT);
startSessionManager();
this.neg = new DefaultPCEPSessionNegotiator(mock(Promise.class), this.clientListener,
this.manager.getSessionListener(), (short) 1, 5, this.localPrefs);
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
import static org.opendaylight.protocol.pcep.pcc.mock.spi.MsgBuilderUtil.createLspTlvs;
import static org.opendaylight.protocol.util.CheckUtil.checkEquals;
import static org.opendaylight.protocol.util.CheckUtil.checkNotPresentOperational;
import static org.opendaylight.protocol.util.CheckUtil.readDataOperational;
+
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import java.net.UnknownHostException;
import java.util.concurrent.TimeoutException;
import org.junit.Before;
import org.junit.Test;
-import org.opendaylight.controller.config.yang.pcep.topology.provider.SessionState;
import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
import org.opendaylight.protocol.pcep.PCEPCloseTermination;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.stateful.capability.tlv.StatefulBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev171025.symbolic.path.name.tlv.SymbolicPathNameBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.message.rev131007.Close;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev171113.StatefulCapabilitiesStatsAug;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stateful.stats.rev171113.StatefulMessagesStatsAug;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.PcepSessionState;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.LocalPref;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.PeerPref;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.reply.time.grouping.ReplyTime;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.address.family.Ipv4CaseBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.endpoints.address.family.ipv4._case.Ipv4Builder;
@Test
public void testStateful07TopologySessionListener() throws Exception {
this.listener.onSessionUp(this.session);
-
- assertEquals(this.testAddress, this.listener.getPeerId());
- final SessionState state = this.listener.getSessionState();
+ final PcepSessionState listenerState = this.listener.listenerState;
+ assertEquals(this.testAddress, listenerState.getPeerPref().getIpAddress());
+ final LocalPref state = this.listener.listenerState.getLocalPref();
assertNotNull(state);
- assertEquals(DEAD_TIMER, state.getLocalPref().getDeadtimer().shortValue());
- assertEquals(KEEP_ALIVE, state.getLocalPref().getKeepalive().shortValue());
- assertEquals(0, state.getLocalPref().getSessionId().intValue());
- assertEquals(this.testAddress, state.getLocalPref().getIpAddress());
- assertEquals(DEAD_TIMER, state.getPeerPref().getDeadtimer().shortValue());
- assertEquals(KEEP_ALIVE, state.getPeerPref().getKeepalive().shortValue());
- assertEquals(0, state.getPeerPref().getSessionId().intValue());
- assertEquals(this.testAddress, state.getPeerPref().getIpAddress());
+ assertEquals(DEAD_TIMER, state.getDeadtimer().shortValue());
+ assertEquals(KEEP_ALIVE, state.getKeepalive().shortValue());
+ assertEquals(0, state.getSessionId().intValue());
+ assertEquals(this.testAddress, state.getIpAddress());
+
+ final PeerPref peerState = listenerState.getPeerPref();
+
+ assertEquals(DEAD_TIMER, peerState.getDeadtimer().shortValue());
+ assertEquals(KEEP_ALIVE, peerState.getKeepalive().shortValue());
+ assertEquals(0, peerState.getSessionId().intValue());
+ assertEquals(this.testAddress, peerState.getIpAddress());
// add-lsp
this.topologyRpcs.addLsp(createAddLspInput());
final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
final long srpId = req.getSrp().getOperationId().getValue();
final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
- this.testAddress, this.testAddress, this.testAddress, Optional.absent());
+ this.testAddress, this.testAddress, this.testAddress, Optional.absent());
final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp())
- .setTlvs(tlvs).setPlspId(new PlspId(1L)).setSync(false).setRemove(false)
- .setOperational(OperationalStatus.Active).build(), Optional.of(MsgBuilderUtil.createSrp(srpId)),
- MsgBuilderUtil.createPath(req.getEro().getSubobject()));
+ .setTlvs(tlvs).setPlspId(new PlspId(1L)).setSync(false).setRemove(false)
+ .setOperational(OperationalStatus.Active).build(), Optional.of(MsgBuilderUtil.createSrp(srpId)),
+ MsgBuilderUtil.createPath(req.getEro().getSubobject()));
final Pcrpt esm = MsgBuilderUtil.createPcRtpMessage(new LspBuilder().setSync(false).build(),
- Optional.of(MsgBuilderUtil.createSrp(0L)), null);
+ Optional.of(MsgBuilderUtil.createSrp(0L)), null);
this.listener.onMessage(this.session, esm);
readDataOperational(getDataBroker(), this.pathComputationClientIId, pcc -> {
assertEquals(this.testAddress, pcc.getIpAddress().getIpv4Address().getValue());
});
// check stats
- checkEquals(()->assertEquals(1, this.listener.getDelegatedLspsCount().intValue()));
- checkEquals(()->assertTrue(this.listener.getSynchronized()));
- checkEquals(()->assertTrue(this.listener.getStatefulMessages().getLastReceivedRptMsgTimestamp() > 0));
- checkEquals(()->assertEquals(2, this.listener.getStatefulMessages().getReceivedRptMsgCount().intValue()));
- checkEquals(()->assertEquals(1, this.listener.getStatefulMessages().getSentInitMsgCount().intValue()));
- checkEquals(()->assertEquals(0, this.listener.getStatefulMessages().getSentUpdMsgCount().intValue()));
- checkEquals(()->assertNotNull(this.listener.getSessionState()));
+ checkEquals(() -> assertEquals(1, listenerState.getDelegatedLspsCount().intValue()));
+ checkEquals(() -> assertTrue(this.listener.isSessionSynchronized()));
+ checkEquals(() -> assertTrue(listenerState.getMessages()
+ .getAugmentation(StatefulMessagesStatsAug.class).getLastReceivedRptMsgTimestamp() > 0));
+ checkEquals(() -> assertEquals(2, listenerState.getMessages()
+ .getAugmentation(StatefulMessagesStatsAug.class).getReceivedRptMsgCount().intValue()));
+ checkEquals(() -> assertEquals(1, listenerState.getMessages()
+ .getAugmentation(StatefulMessagesStatsAug.class).getSentInitMsgCount().intValue()));
+ checkEquals(() -> assertEquals(0, listenerState.getMessages()
+ .getAugmentation(StatefulMessagesStatsAug.class).getSentUpdMsgCount().intValue()));
// update-lsp
final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.update.lsp.args
- .ArgumentsBuilder updArgsBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.
- topology.pcep.rev171025.update.lsp.args.ArgumentsBuilder();
+ .ArgumentsBuilder updArgsBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.
+ topology.pcep.rev171025.update.lsp.args.ArgumentsBuilder();
updArgsBuilder.setEro(createEroWithIpPrefixes(Lists.newArrayList(this.eroIpPrefix, this.dstIpPrefix)));
updArgsBuilder.addAugmentation(Arguments3.class, new Arguments3Builder().setLsp(new LspBuilder()
- .setDelegate(true).setAdministrative(true).build()).build());
+ .setDelegate(true).setAdministrative(true).build()).build());
final UpdateLspInput update = new UpdateLspInputBuilder().setArguments(updArgsBuilder.build())
- .setName(this.TUNNEL_NAME).setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID))
- .setNode(this.nodeId).build();
+ .setName(this.TUNNEL_NAME).setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID))
+ .setNode(this.nodeId).build();
this.topologyRpcs.updateLsp(update);
assertEquals(2, this.receivedMsgs.size());
assertTrue(this.receivedMsgs.get(1) instanceof Pcupd);
final Updates upd = updateMsg.getPcupdMessage().getUpdates().get(0);
final long srpId2 = upd.getSrp().getOperationId().getValue();
final Tlvs tlvs2 = createLspTlvs(upd.getLsp().getPlspId().getValue(), false,
- this.newDestinationAddress, this.testAddress, this.testAddress, Optional.absent());
+ this.newDestinationAddress, this.testAddress, this.testAddress, Optional.absent());
final Pcrpt pcRpt2 = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(upd.getLsp()).setTlvs(tlvs2)
- .setSync(true).setRemove(false).setOperational(OperationalStatus.Active).build(),
- Optional.of(MsgBuilderUtil.createSrp(srpId2)), MsgBuilderUtil.createPath(upd.getPath()
- .getEro().getSubobject()));
+ .setSync(true).setRemove(false).setOperational(OperationalStatus.Active).build(),
+ Optional.of(MsgBuilderUtil.createSrp(srpId2)), MsgBuilderUtil.createPath(upd.getPath()
+ .getEro().getSubobject()));
this.listener.onMessage(this.session, pcRpt2);
//check updated lsp
final Path path = reportedLsp.getPath().get(0);
assertEquals(2, path.getEro().getSubobject().size());
assertEquals(this.dstIpPrefix, getLastEroIpPrefix(path.getEro()));
- assertEquals(1, this.listener.getDelegatedLspsCount().intValue());
- assertTrue(this.listener.getSynchronized());
- assertTrue(this.listener.getStatefulMessages().getLastReceivedRptMsgTimestamp() > 0);
- assertEquals(3, this.listener.getStatefulMessages().getReceivedRptMsgCount().intValue());
- assertEquals(1, this.listener.getStatefulMessages().getSentInitMsgCount().intValue());
- assertEquals(1, this.listener.getStatefulMessages().getSentUpdMsgCount().intValue());
- assertTrue(this.listener.getReplyTime().getAverageTime() > 0);
- assertTrue(this.listener.getReplyTime().getMaxTime() > 0);
- assertFalse(this.listener.getPeerCapabilities().getActive());
- assertTrue(this.listener.getPeerCapabilities().getInstantiation());
- assertTrue(this.listener.getPeerCapabilities().getStateful());
+ assertEquals(1, listenerState.getDelegatedLspsCount().intValue());
+ assertTrue(this.listener.isSessionSynchronized());
+ final StatefulMessagesStatsAug statefulstate = listenerState.getMessages()
+ .getAugmentation(StatefulMessagesStatsAug.class);
+ assertTrue(statefulstate.getLastReceivedRptMsgTimestamp() > 0);
+ assertEquals(3, statefulstate.getReceivedRptMsgCount().intValue());
+ assertEquals(1, statefulstate.getSentInitMsgCount().intValue());
+ assertEquals(1, statefulstate.getSentUpdMsgCount().intValue());
+ final ReplyTime replyTime = listenerState.getMessages().getReplyTime();
+ assertTrue(replyTime.getAverageTime() > 0);
+ assertTrue(replyTime.getMaxTime() > 0);
+ final StatefulCapabilitiesStatsAug statefulCapabilities = listenerState
+ .getPeerCapabilities().getAugmentation(StatefulCapabilitiesStatsAug.class);
+ assertFalse(statefulCapabilities.isActive());
+ assertTrue(statefulCapabilities.isInstantiation());
+ assertTrue(statefulCapabilities.isStateful());
return pcc;
});
// ensure-operational
final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.ensure.lsp.
- operational.args.ArgumentsBuilder ensureArgs = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.
- xml.ns.yang.topology.pcep.rev171025.ensure.lsp.operational.args.ArgumentsBuilder();
+ operational.args.ArgumentsBuilder ensureArgs = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.
+ xml.ns.yang.topology.pcep.rev171025.ensure.lsp.operational.args.ArgumentsBuilder();
ensureArgs.addAugmentation(Arguments1.class, new Arguments1Builder().setOperational(OperationalStatus.Active)
- .build());
+ .build());
final EnsureLspOperationalInput ensure = new EnsureLspOperationalInputBuilder().setArguments(ensureArgs.build())
- .setName(this.TUNNEL_NAME).setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID))
- .setNode(this.nodeId).build();
+ .setName(this.TUNNEL_NAME).setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID))
+ .setNode(this.nodeId).build();
final OperationResult result = this.topologyRpcs.ensureLspOperational(ensure).get().getResult();
//check result
assertNull(result.getFailure());
// remove-lsp
final RemoveLspInput remove = new RemoveLspInputBuilder().setName(this.TUNNEL_NAME)
- .setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID)).setNode(this.nodeId).build();
+ .setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID)).setNode(this.nodeId).build();
this.topologyRpcs.removeLsp(remove);
assertEquals(3, this.receivedMsgs.size());
assertTrue(this.receivedMsgs.get(2) instanceof Pcinitiate);
final Requests req2 = pcinitiate2.getPcinitiateMessage().getRequests().get(0);
final long srpId3 = req2.getSrp().getOperationId().getValue();
final Tlvs tlvs3 = createLspTlvs(req2.getLsp().getPlspId().getValue(), false,
- this.testAddress, this.testAddress, this.testAddress, Optional.absent());
+ this.testAddress, this.testAddress, this.testAddress, Optional.absent());
final Pcrpt pcRpt3 = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req2.getLsp()).setTlvs(tlvs3)
- .setRemove(true).setSync(true).setOperational(OperationalStatus.Down).build(),
- Optional.of(MsgBuilderUtil.createSrp(srpId3)), MsgBuilderUtil.createPath(Collections.emptyList()));
+ .setRemove(true).setSync(true).setOperational(OperationalStatus.Down).build(),
+ Optional.of(MsgBuilderUtil.createSrp(srpId3)), MsgBuilderUtil.createPath(Collections.emptyList()));
this.listener.onMessage(this.session, pcRpt3);
// check if lsp was removed
return pcc;
});
// check stats
- checkEquals(()->assertEquals(0, this.listener.getDelegatedLspsCount().intValue()));
- checkEquals(()->assertTrue(this.listener.getSynchronized()));
- checkEquals(()->assertTrue(this.listener.getStatefulMessages().getLastReceivedRptMsgTimestamp() > 0));
- checkEquals(()->assertEquals(4, this.listener.getStatefulMessages().getReceivedRptMsgCount().intValue()));
- checkEquals(()->assertEquals(2, this.listener.getStatefulMessages().getSentInitMsgCount().intValue()));
- checkEquals(()->assertEquals(1, this.listener.getStatefulMessages().getSentUpdMsgCount().intValue()));
+ checkEquals(() -> assertEquals(0, listenerState.getDelegatedLspsCount().intValue()));
+ checkEquals(() -> assertTrue(this.listener.isSessionSynchronized()));
+ checkEquals(() -> assertTrue(listenerState.getMessages()
+ .getAugmentation(StatefulMessagesStatsAug.class).getLastReceivedRptMsgTimestamp() > 0));
+ checkEquals(() -> assertEquals(4, listenerState.getMessages()
+ .getAugmentation(StatefulMessagesStatsAug.class).getReceivedRptMsgCount().intValue()));
+ checkEquals(() -> assertEquals(2, listenerState.getMessages()
+ .getAugmentation(StatefulMessagesStatsAug.class).getSentInitMsgCount().intValue()));
+ checkEquals(() -> assertEquals(1, listenerState.getMessages()
+ .getAugmentation(StatefulMessagesStatsAug.class).getSentUpdMsgCount().intValue()));
}
@Test
this.listener.onMessage(this.session, errorMsg);
final AddLspOutput output = futureOutput.get().getResult();
- assertEquals(FailureType.Failed ,output.getFailure());
+ assertEquals(FailureType.Failed, output.getFailure());
assertEquals(1, output.getError().size());
final ErrorObject err = output.getError().get(0).getErrorObject();
assertEquals(PCEPErrors.NON_ZERO_PLSPID.getErrorType(), err.getType().shortValue());
*/
@Test
public void testOnServerSessionManagerDown() throws InterruptedException, ExecutionException,
- TransactionCommitFailedException {
+ TransactionCommitFailedException {
this.listener.onSessionUp(this.session);
// the session should not be closed when session manager is up
assertFalse(this.session.isClosed());
*/
@Test
public void testOnServerSessionManagerUnstarted() throws InterruptedException, ExecutionException,
- TransactionCommitFailedException, ReadFailedException {
+ TransactionCommitFailedException, ReadFailedException {
stopSessionManager();
assertFalse(this.session.isClosed());
this.listener.onSessionUp(this.session);
final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
final long srpId = req.getSrp().getOperationId().getValue();
final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
- this.testAddress, this.testAddress, this.testAddress, Optional.absent());
+ this.testAddress, this.testAddress, this.testAddress, Optional.absent());
final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs).setSync(true)
- .setRemove(false).setOperational(OperationalStatus.Active).build(),
- Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(req.getEro().getSubobject()));
+ .setRemove(false).setOperational(OperationalStatus.Active).build(),
+ Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(req.getEro().getSubobject()));
this.listener.onMessage(this.session, pcRpt);
readDataOperational(getDataBroker(), TOPO_IID, topology -> {
assertEquals(1, topology.getNode().size());
final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
final long srpId = req.getSrp().getOperationId().getValue();
final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
- this.testAddress, this.testAddress, this.testAddress, Optional.absent());
+ this.testAddress, this.testAddress, this.testAddress, Optional.absent());
final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs).setSync(true)
- .setRemove(false).setOperational(OperationalStatus.Active).build(),
- Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(req.getEro().getSubobject()));
+ .setRemove(false).setOperational(OperationalStatus.Active).build(),
+ Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(req.getEro().getSubobject()));
this.listener.onMessage(this.session, pcRpt);
readDataOperational(getDataBroker(), TOPO_IID, topology -> {
assertEquals(1, topology.getNode().size());
final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
final long srpId = req.getSrp().getOperationId().getValue();
final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
- this.testAddress, this.testAddress, this.testAddress, Optional.absent());
+ this.testAddress, this.testAddress, this.testAddress, Optional.absent());
final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs).setSync(true)
- .setRemove(false).setOperational(OperationalStatus.Active).build(),
- Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(req.getEro().getSubobject()));
+ .setRemove(false).setOperational(OperationalStatus.Active).build(),
+ Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(req.getEro().getSubobject()));
this.listener.onMessage(this.session, pcRpt);
readDataOperational(getDataBroker(), TOPO_IID, topology -> {
assertEquals(1, topology.getNode().size());
@Test
public void testUnknownLsp() throws Exception {
final List<Reports> reports = Lists.newArrayList(new ReportsBuilder().setPath(new PathBuilder()
- .setEro(new EroBuilder().build()).build()).setLsp(new LspBuilder().setPlspId(new PlspId(5L))
- .setSync(false).setRemove(false).setTlvs(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.
- yang.pcep.ietf.stateful.rev171025.lsp.object.lsp.TlvsBuilder().setLspIdentifiers(
- new LspIdentifiersBuilder().setLspId(new LspId(1L)).build()).setSymbolicPathName(
- new SymbolicPathNameBuilder().setPathName(new SymbolicPathName(new byte[] { 22, 34 }))
- .build()).build()).build()).build());
+ .setEro(new EroBuilder().build()).build()).setLsp(new LspBuilder().setPlspId(new PlspId(5L))
+ .setSync(false).setRemove(false).setTlvs(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml
+ .ns.yang.pcep.ietf.stateful.rev171025.lsp.object.lsp.TlvsBuilder().setLspIdentifiers(
+ new LspIdentifiersBuilder().setLspId(new LspId(1L)).build()).setSymbolicPathName(
+ new SymbolicPathNameBuilder().setPathName(new SymbolicPathName(new byte[]{22, 34}))
+ .build()).build()).build()).build());
final Pcrpt rptmsg = new PcrptBuilder().setPcrptMessage(new PcrptMessageBuilder().setReports(reports).build())
- .build();
+ .build();
this.listener.onSessionUp(this.session);
this.listener.onMessage(this.session, rptmsg);
readDataOperational(getDataBroker(), TOPO_IID, node -> {
public void testUpdateUnknownLsp() throws InterruptedException, ExecutionException {
this.listener.onSessionUp(this.session);
final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev171025.update.lsp.args
- .ArgumentsBuilder updArgsBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.
- topology.pcep.rev171025.update.lsp.args.ArgumentsBuilder();
+ .ArgumentsBuilder updArgsBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.
+ topology.pcep.rev171025.update.lsp.args.ArgumentsBuilder();
updArgsBuilder.setEro(createEroWithIpPrefixes(Lists.newArrayList(this.eroIpPrefix, this.dstIpPrefix)));
updArgsBuilder.addAugmentation(Arguments3.class, new Arguments3Builder().setLsp(new LspBuilder()
- .setDelegate(true).setAdministrative(true).build()).build());
+ .setDelegate(true).setAdministrative(true).build()).build());
final UpdateLspInput update = new UpdateLspInputBuilder().setArguments(updArgsBuilder.build())
- .setName(this.TUNNEL_NAME).setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID)).setNode(this.nodeId)
- .build();
+ .setName(this.TUNNEL_NAME).setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID)).setNode(this.nodeId)
+ .build();
final UpdateLspOutput result = this.topologyRpcs.updateLsp(update).get().getResult();
assertEquals(FailureType.Unsent, result.getFailure());
assertEquals(1, result.getError().size());
public void testRemoveUnknownLsp() throws InterruptedException, ExecutionException {
this.listener.onSessionUp(this.session);
final RemoveLspInput remove = new RemoveLspInputBuilder().setName(this.TUNNEL_NAME).setNetworkTopologyRef(
- new NetworkTopologyRef(TOPO_IID)).setNode(this.nodeId).build();
+ new NetworkTopologyRef(TOPO_IID)).setNode(this.nodeId).build();
final OperationResult result = this.topologyRpcs.removeLsp(remove).get().getResult();
assertEquals(FailureType.Unsent, result.getFailure());
assertEquals(1, result.getError().size());
final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
final long srpId = req.getSrp().getOperationId().getValue();
final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
- this.testAddress, this.testAddress, this.testAddress, Optional.absent());
+ this.testAddress, this.testAddress, this.testAddress, Optional.absent());
final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs)
- .setPlspId(new PlspId(1L)).setSync(false).setRemove(false).setOperational(OperationalStatus.Active)
- .build(), Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(req.getEro()
- .getSubobject()));
+ .setPlspId(new PlspId(1L))
+ .setSync(false)
+ .setRemove(false)
+ .setOperational(OperationalStatus.Active)
+ .build(), Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(req.getEro()
+ .getSubobject()));
this.listener.onMessage(this.session, pcRpt);
//try to add already existing LSP
final ErrorObject errorObject = result.getError().get(0).getErrorObject();
assertNotNull(errorObject);
assertEquals(PCEPErrors.USED_SYMBOLIC_PATH_NAME, PCEPErrors.forValue(errorObject.getType(),
- errorObject.getValue()));
+ errorObject.getValue()));
}
@Test
assertTrue(e instanceof TimeoutException);
}
Thread.sleep(AbstractPCEPSessionTest.RPC_TIMEOUT);
- CheckUtil.checkEquals(()-> {
+ CheckUtil.checkEquals(() -> {
final RpcResult<AddLspOutput> rpcResult = addLspResult.get();
assertNotNull(rpcResult);
assertEquals(rpcResult.getResult().getFailure(), FailureType.Unsent);
final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
final long srpId = req.getSrp().getOperationId().getValue();
final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
- this.testAddress, this.testAddress, this.testAddress, Optional.absent());
+ this.testAddress, this.testAddress, this.testAddress, Optional.absent());
//delegate set to true
final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs)
- .setPlspId(new PlspId(1L)).setSync(false).setRemove(false).setOperational(OperationalStatus.Active)
- .setDelegate(true).build(), Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(
- req.getEro().getSubobject()));
+ .setPlspId(new PlspId(1L))
+ .setSync(false)
+ .setRemove(false)
+ .setOperational(OperationalStatus.Active)
+ .setDelegate(true)
+ .build(), Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(
+ req.getEro().getSubobject()));
this.listener.onMessage(this.session, pcRpt);
- checkEquals(()->assertEquals(1, this.listener.getDelegatedLspsCount().intValue()));
+ checkEquals(() -> assertEquals(1, this.listener.listenerState.getDelegatedLspsCount().intValue()));
}
@Test
final Requests req = pcinitiate.getPcinitiateMessage().getRequests().get(0);
final long srpId = req.getSrp().getOperationId().getValue();
final Tlvs tlvs = createLspTlvs(req.getLsp().getPlspId().getValue(), true,
- this.testAddress, this.testAddress, this.testAddress, Optional.absent());
+ this.testAddress, this.testAddress, this.testAddress, Optional.absent());
//delegate set to false
final Pcrpt pcRpt = MsgBuilderUtil.createPcRtpMessage(new LspBuilder(req.getLsp()).setTlvs(tlvs)
- .setPlspId(new PlspId(1L)).setSync(false).setRemove(false).setOperational(OperationalStatus.Active)
- .setDelegate(false).build(), Optional.of(MsgBuilderUtil.createSrp(srpId)), MsgBuilderUtil.createPath(
- req.getEro().getSubobject()));
+ .setPlspId(
+ new PlspId(1L))
+ .setSync(false)
+ .setRemove(false)
+ .setOperational(OperationalStatus.Active)
+ .setDelegate(false)
+ .build(), Optional.of(MsgBuilderUtil.createSrp(srpId)),
+ MsgBuilderUtil.createPath(req.getEro().getSubobject()));
this.listener.onMessage(this.session, pcRpt);
- checkEquals(()->assertEquals(0, this.listener.getDelegatedLspsCount().intValue()));
+ checkEquals(() -> assertEquals(0, this.listener.listenerState.getDelegatedLspsCount().intValue()));
}
@Override
protected Open getLocalPref() {
return new OpenBuilder(super.getLocalPref()).setTlvs(new TlvsBuilder().addAugmentation(Tlvs1.class,
- new Tlvs1Builder().setStateful(new StatefulBuilder()
- .addAugmentation(Stateful1.class, new Stateful1Builder().setInitiation(Boolean.TRUE).build())
- .addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.
- optimizations.rev171025.Stateful1.class, new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.
- ns.yang.controller.pcep.sync.optimizations.rev171025.Stateful1Builder()
- .setTriggeredInitialSync(Boolean.TRUE).build())
- .build()).build()).build()).build();
+ new Tlvs1Builder().setStateful(new StatefulBuilder()
+ .addAugmentation(Stateful1.class, new Stateful1Builder().setInitiation(Boolean.TRUE).build())
+ .addAugmentation(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller
+ .pcep.sync.optimizations.rev171025.Stateful1.class, new org.opendaylight.yang.gen.v1
+ .urn.opendaylight.params.xml.ns.yang.controller.pcep.sync.optimizations.rev171025
+ .Stateful1Builder().setTriggeredInitialSync(Boolean.TRUE).build())
+ .build()).build()).build()).build();
}
@Override
final ArgumentsBuilder argsBuilder = new ArgumentsBuilder();
final Ipv4CaseBuilder ipv4Builder = new Ipv4CaseBuilder();
ipv4Builder.setIpv4(new Ipv4Builder().setSourceIpv4Address(new Ipv4Address(this.testAddress))
- .setDestinationIpv4Address(new Ipv4Address(this.testAddress)).build());
+ .setDestinationIpv4Address(new Ipv4Address(this.testAddress)).build());
argsBuilder.setEndpointsObj(new EndpointsObjBuilder().setAddressFamily(ipv4Builder.build()).build());
argsBuilder.setEro(createEroWithIpPrefixes(Lists.newArrayList(this.eroIpPrefix)));
argsBuilder.addAugmentation(Arguments2.class, new Arguments2Builder().setLsp(new LspBuilder()
- .setDelegate(true).setAdministrative(true).build()).build());
+ .setDelegate(true).setAdministrative(true).build()).build());
return new AddLspInputBuilder().setName(this.TUNNEL_NAME).setArguments(argsBuilder.build())
- .setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID)).setNode(this.nodeId).build();
+ .setNetworkTopologyRef(new NetworkTopologyRef(TOPO_IID)).setNode(this.nodeId).build();
}
}
--- /dev/null
+/*
+ * Copyright (c) 2017 AT&T Intellectual Property. 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.bgpcep.pcep.topology.spi.stats;
+
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.PcepSessionState;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+
+/**
+ * Topology Node Sessions stats handler. Will store Session stats on DS per each Topology Node registered.
+ */
+public interface TopologySessionStatsRegistry {
+ /**
+ * Register session to Session stats Registry handler
+ *
+ * @param nodeId Identifier of the topology node where it will be stored session stats under DS
+ * @param sessionState containing all Stats Session information
+ */
+ void bind(final KeyedInstanceIdentifier<Node, NodeKey> nodeId, PcepSessionState sessionState);
+
+ /**
+ * Unregister Node from Stats Registry handler
+ *
+ * @param nodeId Identifier of the topology node to be removed from registry
+ */
+ void unbind(final KeyedInstanceIdentifier<Node, NodeKey> nodeId);
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (c) 2017 AT&T Intellectual Property. 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
+ -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.bgpcep</groupId>
+ <artifactId>binding-parent</artifactId>
+ <version>0.9.0-SNAPSHOT</version>
+ <relativePath>../../../binding-parent</relativePath>
+ </parent>
+
+ <artifactId>pcep-topology-stats</artifactId>
+ <description>PCEP Topology Stats</description>
+ <packaging>bundle</packaging>
+ <name>${project.artifactId}</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>pcep-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-topology</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>pcep-topology-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>pcep-topology-spi</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>pcep-ietf-stateful07</artifactId>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-checkstyle-plugin</artifactId>
+ <configuration>
+ <propertyExpansion>checkstyle.violationSeverity=error</propertyExpansion>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>findbugs-maven-plugin</artifactId>
+ <configuration>
+ <failOnError>true</failOnError>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/bgpcep.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/bgpcep.git</developerConnection>
+ <url>https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main</url>
+ <tag>HEAD</tag>
+ </scm>
+
+ <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+ <distributionManagement>
+ <site>
+ <id>opendaylight-site</id>
+ <url>${nexus.site.url}/${project.artifactId}/</url>
+ </site>
+ </distributionManagement>
+</project>
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2017 AT&T Intellectual Property. 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.bgpcep.pcep.topology.stats.provider;
+
+import static java.util.Objects.requireNonNull;
+
+import io.netty.util.concurrent.GlobalEventExecutor;
+import io.netty.util.concurrent.ScheduledFuture;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TimerTask;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.Nonnull;
+import javax.annotation.concurrent.GuardedBy;
+import org.opendaylight.bgpcep.pcep.topology.spi.stats.TopologySessionStatsRegistry;
+import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.PcepSessionState;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.stats.rev171113.pcep.session.state.grouping.PcepSessionStateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.stats.rev171113.PcepTopologyNodeStatsAug;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.stats.rev171113.PcepTopologyNodeStatsAugBuilder;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
+import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class TopologyStatsProviderImpl implements TransactionChainListener,
+ TopologySessionStatsRegistry, AutoCloseable {
+
+ private static final Logger LOG = LoggerFactory.getLogger(TopologyStatsProviderImpl.class);
+ @GuardedBy("this")
+ private final Map<KeyedInstanceIdentifier<Node, NodeKey>, PcepSessionState> statsMap = new HashMap<>();
+ private final DataBroker dataBroker;
+ private final int timeout;
+ private BindingTransactionChain transactionChain;
+ private ScheduledFuture<?> scheduleTask;
+
+ public TopologyStatsProviderImpl(@Nonnull final DataBroker dataBroker, final int timeout) {
+ this.dataBroker = requireNonNull(dataBroker);
+ this.timeout = timeout;
+ }
+
+ public void init() {
+ LOG.info("Initializing TopologyStatsProvider service.", this);
+ this.transactionChain = this.dataBroker.createTransactionChain(this);
+ final TimerTask task = new TimerTask() {
+ @Override
+ public void run() {
+ synchronized (TopologyStatsProviderImpl.this) {
+ final WriteTransaction tx = TopologyStatsProviderImpl
+ .this.transactionChain.newWriteOnlyTransaction();
+
+ TopologyStatsProviderImpl.this.statsMap
+ .forEach((key, value) -> updatePCEPStats(key, value, tx));
+ tx.submit();
+ }
+ }
+ };
+
+ this.scheduleTask = GlobalEventExecutor.INSTANCE.scheduleAtFixedRate(task, 0, this.timeout,
+ TimeUnit.SECONDS);
+ }
+
+ private synchronized void updatePCEPStats(
+ final KeyedInstanceIdentifier<Node, NodeKey> nodeIId,
+ final PcepSessionState stats,
+ final WriteTransaction tx) {
+
+ final PcepTopologyNodeStatsAug nodeStatsAug = new PcepTopologyNodeStatsAugBuilder()
+ .setPcepSessionState(new PcepSessionStateBuilder(stats).build()).build();
+ final InstanceIdentifier<PcepTopologyNodeStatsAug> statId =
+ nodeIId.augmentation(PcepTopologyNodeStatsAug.class);
+ tx.put(LogicalDatastoreType.OPERATIONAL, statId, nodeStatsAug);
+ }
+
+ @Override
+ public void close() throws Exception {
+ LOG.info("Closing TopologyStatsProvider service.", this);
+ this.scheduleTask.cancel(true);
+ final WriteTransaction wTx = this.transactionChain.newWriteOnlyTransaction();
+ this.statsMap.keySet().iterator().forEachRemaining(statId ->
+ wTx.delete(LogicalDatastoreType.OPERATIONAL, statId));
+ wTx.submit().get();
+ this.statsMap.clear();
+ this.transactionChain.close();
+ }
+
+ @Override
+ public void onTransactionChainFailed(final TransactionChain<?, ?> chain, final AsyncTransaction<?, ?> transaction,
+ final Throwable cause) {
+ LOG.error("Transaction chain failed {}.", transaction != null ? transaction.getIdentifier() : null, cause);
+ }
+
+ @Override
+ public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
+ LOG.debug("Transaction chain {} successful.", chain);
+ }
+
+ @Override
+ public synchronized void bind(final KeyedInstanceIdentifier<Node, NodeKey> nodeId,
+ final PcepSessionState sessionState) {
+ this.statsMap.put(nodeId, sessionState);
+ }
+
+ @Override
+ public synchronized void unbind(final KeyedInstanceIdentifier<Node, NodeKey> nodeId) {
+ this.statsMap.remove(nodeId);
+ final WriteTransaction wTx = this.transactionChain.newWriteOnlyTransaction();
+ wTx.delete(LogicalDatastoreType.OPERATIONAL, nodeId);
+ try {
+ wTx.submit().get();
+ } catch (final InterruptedException | ExecutionException e) {
+ LOG.warn("Failed to remove Pcep Node stats {}.", nodeId.getKey().getNodeId());
+ }
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (c) 2017. AT&T Intellectual Property. 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
+ -->
+
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
+ xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0">
+ <reference id="dataBroker" interface="org.opendaylight.controller.md.sal.binding.api.DataBroker"
+ odl:type="pingpong"/>
+ <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="topologyStatsRegistry"
+ class="org.opendaylight.bgpcep.pcep.topology.stats.provider.TopologyStatsProviderImpl"
+ init-method="init" destroy-method="close">
+ <argument ref="dataBroker"/>
+ <argument>
+ <bean factory-ref="pcepStatsConfig" factory-method="getTimer"/>
+ </argument>
+ </bean>
+ <service ref="topologyStatsRegistry"
+ interface="org.opendaylight.bgpcep.pcep.topology.spi.stats.TopologySessionStatsRegistry"/>
+</blueprint>
\ No newline at end of file
--- /dev/null
+// vi: set smarttab et sw=4 tabstop=4:
+module odl-pcep-stats-provider {
+ yang-version 1;
+ namespace "urn:opendaylight:params:xml:ns:yang:odl:pcep:stats:provider:config";
+ prefix pspc;
+
+ description
+ "This module contains the base YANG definitions for
+ PCEP Stats Provider Configuration.
+ Copyright (c)2017 AT&T Services, Inc. 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";
+
+ revision "2017-11-13" {
+ description
+ "Initial revision.";
+ }
+
+ container pcep-provider {
+ leaf config-name {
+ type string;
+ mandatory true;
+ }
+
+ leaf timer {
+ type uint16;
+ default 5;
+ units "seconds";
+ }
+ }
+}
\ No newline at end of file