BGPCEP-580: Implement PCEP stats DS rendering 37/65537/10
authorClaudio D. Gasparini <claudio.gasparini@pantheon.tech>
Wed, 29 Nov 2017 09:46:02 +0000 (10:46 +0100)
committerClaudio D. Gasparini <claudio.gasparini@pantheon.tech>
Wed, 29 Nov 2017 11:00:40 +0000 (12:00 +0100)
- create Pcep Topology stats models
- create new PCEP State interfaces
- augment network pcep topology
with pcep session state
- implement PCEP Stats Registry for register
Node Stats and store stats udner DS

Change-Id: Ib33a05c7e3fcb9ef7c485bed7a33e543ed6c7d14
Signed-off-by: Claudio D. Gasparini <claudio.gasparini@pantheon.tech>
39 files changed:
features/pcep/features-pcep/pom.xml
features/pcep/odl-bgpcep-pcep-topology-provider/pom.xml
features/pcep/odl-bgpcep-pcep-topology-stats/pom.xml [new file with mode: 0644]
features/pcep/pom.xml
pcep/api/src/main/java/org/opendaylight/protocol/pcep/PCEPSession.java
pcep/api/src/main/java/org/opendaylight/protocol/pcep/PCEPSessionState.java [new file with mode: 0644]
pcep/api/src/main/yang/pcep-session-stats.yang
pcep/ietf-stateful07/src/main/yang/odl-pcep-stateful-stats.yang [new file with mode: 0644]
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPSessionImpl.java
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPSessionNegotiator.java
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPSessionState.java
pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPSessionImplTest.java
pcep/pcep-artifacts/pom.xml
pcep/topology/pom.xml
pcep/topology/topology-api/pom.xml
pcep/topology/topology-api/src/main/yang/network-pcep-topology-config.yang
pcep/topology/topology-api/src/main/yang/network-pcep-topology-stats.yang [new file with mode: 0644]
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractTopologySessionListener.java
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPTopologyProvider.java
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/ServerSessionManager.java
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/SessionListenerState.java [deleted file]
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful07TopologySessionListener.java
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful07TopologySessionListenerFactory.java
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/TopologyNodeState.java
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyDeployerImpl.java
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyProviderBean.java
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyProviderDependenciesProvider.java
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/config/PCEPTopologyProviderUtil.java
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/session/stats/SessionStateImpl.java [new file with mode: 0644]
pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/session/stats/TopologySessionStats.java [new file with mode: 0644]
pcep/topology/topology-provider/src/main/resources/org/opendaylight/blueprint/pcep-topology.xml
pcep/topology/topology-provider/src/main/yang/odl-pcep-topology-provider-cfg.yang
pcep/topology/topology-provider/src/test/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractPCEPSessionTest.java
pcep/topology/topology-provider/src/test/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful07TopologySessionListenerTest.java
pcep/topology/topology-spi/src/main/java/org/opendaylight/bgpcep/pcep/topology/spi/stats/TopologySessionStatsRegistry.java [new file with mode: 0644]
pcep/topology/topology-stats/pom.xml [new file with mode: 0644]
pcep/topology/topology-stats/src/main/java/org/opendaylight/bgpcep/pcep/topology/stats/provider/TopologyStatsProviderImpl.java [new file with mode: 0644]
pcep/topology/topology-stats/src/main/resources/org/opendaylight/blueprint/pcep-provider-stats.xml [new file with mode: 0644]
pcep/topology/topology-stats/src/main/yang/odl-pcep-stats-provider.yang [new file with mode: 0644]

index 21dc93d1c61bb906808920d095301427c1dd0fb8..63c9859eed8be818820eb7629c508262103d2d68 100644 (file)
             <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>
 
     <!--
index a573d6086a4145f4768451859e12dd25e6b1a8db..82a89f2f305b90080e66563b9c53a9f9df13d80e 100644 (file)
             <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>
diff --git a/features/pcep/odl-bgpcep-pcep-topology-stats/pom.xml b/features/pcep/odl-bgpcep-pcep-topology-stats/pom.xml
new file mode 100644 (file)
index 0000000..68e6bda
--- /dev/null
@@ -0,0 +1,67 @@
+<?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>
index fa1549e69e29fe6c373706a0cda7bf1001d642f3..3cff415f5b96b8ac1c3d7901ae8eb1dc118c681c 100644 (file)
@@ -37,6 +37,7 @@
         <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>
 
     <!--
index 656daaf25a8cd1ed42eee1175ffeac3c716989e8..305fa911e371c086db4b1f12667d089d614a4b67 100644 (file)
@@ -9,7 +9,9 @@ package org.opendaylight.protocol.pcep;
 
 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;
 
@@ -19,7 +21,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.typ
  * 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
@@ -37,10 +39,9 @@ public interface PCEPSession extends AutoCloseable, PcepSessionState {
 
     InetAddress getRemoteAddress();
 
-    void resetStats();
-
     /**
      * Returns session characteristics of the local PCEP Speaker
+     *
      * @return Open message TLVs
      */
     Tlvs localSessionCharacteristics();
diff --git a/pcep/api/src/main/java/org/opendaylight/protocol/pcep/PCEPSessionState.java b/pcep/api/src/main/java/org/opendaylight/protocol/pcep/PCEPSessionState.java
new file mode 100644 (file)
index 0000000..d0b93f6
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * 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();
+}
index 035ebb3a3f591718190e37692ba012bb454544db..238da5b6ff810cad3abde9dd4d854f149eca3334 100644 (file)
@@ -1,7 +1,7 @@
 // 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.";
@@ -19,6 +19,11 @@ module pcep-session-stats {
         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";
@@ -62,53 +67,105 @@ module pcep-session-stats {
         }
     }
 
+    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 {
@@ -120,5 +177,18 @@ module pcep-session-stats {
             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
diff --git a/pcep/ietf-stateful07/src/main/yang/odl-pcep-stateful-stats.yang b/pcep/ietf-stateful07/src/main/yang/odl-pcep-stateful-stats.yang
new file mode 100644 (file)
index 0000000..4c4eaf8
--- /dev/null
@@ -0,0 +1,93 @@
+// 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
index e85362b386b30dfa3e83f3740fd7ac43dbb4bd94..dc565823722da1e99dda4d6f54fc4650d1c77fcf 100644 (file)
@@ -26,6 +26,7 @@ import java.util.Date;
 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;
@@ -33,12 +34,12 @@ import org.opendaylight.protocol.pcep.PCEPSessionListener;
 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;
@@ -49,7 +50,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.typ
 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;
 
@@ -91,7 +91,7 @@ public class PCEPSessionImpl extends SimpleChannelInboundHandler<Message> implem
 
     // 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;
 
@@ -100,7 +100,7 @@ public class PCEPSessionImpl extends SimpleChannelInboundHandler<Message> implem
     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);
@@ -121,7 +121,7 @@ public class PCEPSessionImpl extends SimpleChannelInboundHandler<Message> implem
         }
 
         LOG.info("Session {}[{}] <-> {}[{}] started", channel.localAddress(), localOpen.getSessionId(), channel.remoteAddress(),
-            remoteOpen.getSessionId());
+                remoteOpen.getSessionId());
         this.sessionState = new PCEPSessionState(remoteOpen, localOpen, channel);
     }
 
@@ -160,7 +160,7 @@ public class PCEPSessionImpl extends SimpleChannelInboundHandler<Message> implem
      * 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());
@@ -221,7 +221,7 @@ public class PCEPSessionImpl extends SimpleChannelInboundHandler<Message> implem
 
     @VisibleForTesting
     public synchronized boolean isClosed() {
-        return this.closed;
+        return this.closed.get();
     }
 
     /**
@@ -239,11 +239,10 @@ public class PCEPSessionImpl extends SimpleChannelInboundHandler<Message> implem
      */
     @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);
@@ -266,7 +265,7 @@ public class PCEPSessionImpl extends SimpleChannelInboundHandler<Message> implem
     }
 
     private synchronized void terminate(final TerminationReason reason) {
-        if (this.closed) {
+        if (this.closed.get()) {
             LOG.debug("Session {} is already closed.", this);
             return;
         }
@@ -274,10 +273,9 @@ public class PCEPSessionImpl extends SimpleChannelInboundHandler<Message> implem
         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;
         }
     }
 
@@ -309,7 +307,7 @@ public class PCEPSessionImpl extends SimpleChannelInboundHandler<Message> implem
         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) {
@@ -325,7 +323,7 @@ public class PCEPSessionImpl extends SimpleChannelInboundHandler<Message> implem
      * @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;
         }
@@ -399,16 +397,6 @@ public class PCEPSessionImpl extends SimpleChannelInboundHandler<Message> implem
         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());
index e8c8967cb3e73fc43dd1a6da8e8b1dc1c2b315d5..77f2619eed740af934ab8b8b61983d6061bccc2f 100644 (file)
@@ -33,7 +33,8 @@ public class PCEPSessionNegotiator extends AbstractSessionNegotiator {
     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;
@@ -74,7 +75,8 @@ public class PCEPSessionNegotiator extends AbstractSessionNegotiator {
             }
 
             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() {
index d3bee9df041c68200bee482b6c4c83f0fa9598b0..285b5a8adb68ed43afa13bd3bab85eee0576e926 100644 (file)
@@ -13,15 +13,15 @@ import static java.util.Objects.requireNonNull;
 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;
@@ -40,7 +40,7 @@ final class PCEPSessionState {
     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);
@@ -52,7 +52,7 @@ final class PCEPSessionState {
         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());
@@ -65,7 +65,7 @@ final class PCEPSessionState {
         return this.msgsBuilder.build();
     }
 
-    public void reset() {
+    void reset() {
         this.receivedMsgCount = 0;
         this.sentMsgCount = 0;
         this.receivedErrMsgCount = 0;
@@ -81,37 +81,37 @@ final class PCEPSessionState {
         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();
     }
 
index c6267f455e0d774a23f78d3f4de445642b9bc563..2986eb060be17d68765da33f53ca39f70b6338b7 100644 (file)
@@ -18,13 +18,13 @@ 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.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;
 
@@ -61,9 +61,6 @@ public class PCEPSessionImplTest extends AbstractPCEPSessionTest {
         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
index 38dc8b909b0f30fc60468fce811df540f78e29ba..be9cf904609c6c3fca8345658ff68da1ac9aa1e2 100644 (file)
                 <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>
 
index 6cbf9d256cc823aef555292229d2863a4a7e40c5..0ebc47755071f01839b2c446eb4be4894af7beb6 100644 (file)
@@ -21,6 +21,7 @@
         <module>topology-api</module>
         <module>topology-spi</module>
         <module>topology-provider</module>
+        <module>topology-stats</module>
     </modules>
 
     <!--
index 35fe57eb7f423374e41bfc711a6e589192fc0dd1..d8a8fa5094d89e0e3a263f375b89976f745ceaf5 100644 (file)
@@ -63,7 +63,6 @@
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>concepts</artifactId>
         </dependency>
-
         <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
index 759122b2b854fabcf046ac886f19258ea7424b4e..eb884018a3d75805414092ed4e3728a8b7906979 100644 (file)
@@ -1,7 +1,7 @@
 // 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; }
diff --git a/pcep/topology/topology-api/src/main/yang/network-pcep-topology-stats.yang b/pcep/topology/topology-api/src/main/yang/network-pcep-topology-stats.yang
new file mode 100644 (file)
index 0000000..7a8e7d7
--- /dev/null
@@ -0,0 +1,36 @@
+// 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
index 3cbf2426a33fd33d9820a5ea56c2bfcf1f1d8b96..ffacb7caa5d54e545ee2e0e5962dd535434038a5 100755 (executable)
@@ -28,11 +28,8 @@ import java.util.Timer;
 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;
@@ -78,8 +75,8 @@ import org.slf4j.LoggerFactory;
  * @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
@@ -92,28 +89,28 @@ public abstract class AbstractTopologySessionListener<S, L> implements TopologyS
             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
@@ -128,7 +125,9 @@ public abstract class AbstractTopologySessionListener<S, L> implements TopologyS
 
         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);
@@ -143,9 +142,9 @@ public abstract class AbstractTopologySessionListener<S, L> implements TopologyS
             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());
 
@@ -162,7 +161,8 @@ public abstract class AbstractTopologySessionListener<S, L> implements TopologyS
         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);
@@ -181,18 +181,20 @@ public abstract class AbstractTopologySessionListener<S, L> implements TopologyS
         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);
@@ -219,7 +221,7 @@ public abstract class AbstractTopologySessionListener<S, L> implements TopologyS
         }, MoreExecutors.directExecutor());
     }
 
-    protected boolean isTriggeredSyncInProcess() {
+    boolean isTriggeredSyncInProcess() {
         return this.triggeredResyncInProcess;
     }
 
@@ -231,15 +233,20 @@ public abstract class AbstractTopologySessionListener<S, L> implements TopologyS
      */
     @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;
@@ -321,7 +328,7 @@ public abstract class AbstractTopologySessionListener<S, L> implements TopologyS
         }
     }
 
-    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());
@@ -330,7 +337,7 @@ public abstract class AbstractTopologySessionListener<S, L> implements TopologyS
         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);
@@ -530,7 +537,7 @@ public abstract class AbstractTopologySessionListener<S, L> implements TopologyS
      */
     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);
     }
@@ -542,7 +549,8 @@ public abstract class AbstractTopologySessionListener<S, L> implements TopologyS
      * @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;
         }
@@ -551,16 +559,17 @@ public abstract class AbstractTopologySessionListener<S, L> implements TopologyS
 
     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();
         }
@@ -573,21 +582,21 @@ public abstract class AbstractTopologySessionListener<S, L> implements TopologyS
      *
      * @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();
         }
@@ -601,12 +610,8 @@ public abstract class AbstractTopologySessionListener<S, L> implements TopologyS
         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
@@ -618,42 +623,17 @@ public abstract class AbstractTopologySessionListener<S, L> implements TopologyS
     }
 
     @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;
 
index e079e717562839fe344338ee074c89aca8302caf..a823735b0d87c844b1b28da32d31e7aedfa9a4ad 100755 (executable)
@@ -38,7 +38,7 @@ public final class PCEPTopologyProvider extends DefaultTopologyReference {
     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;
@@ -50,9 +50,9 @@ public final class PCEPTopologyProvider extends DefaultTopologyReference {
     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()) {
@@ -67,18 +67,22 @@ public final class PCEPTopologyProvider extends DefaultTopologyReference {
         }
 
         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;
@@ -92,17 +96,17 @@ public final class PCEPTopologyProvider extends DefaultTopologyReference {
         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) {
@@ -114,7 +118,7 @@ public final class PCEPTopologyProvider extends DefaultTopologyReference {
     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();
index 793c58717164c24bf1b65eb7a54ff399febc7f0c..5efdfca25264e7082bd7caa39d9c334e67997394 100755 (executable)
@@ -22,6 +22,7 @@ import java.util.Map;
 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;
@@ -29,6 +30,7 @@ import org.opendaylight.protocol.pcep.PCEPPeerProposal;
 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;
@@ -45,23 +47,24 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 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")
@@ -71,11 +74,16 @@ final class ServerSessionManager implements PCEPSessionListenerFactory, Topology
     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;
@@ -249,4 +257,15 @@ final class ServerSessionManager implements PCEPSessionListenerFactory, Topology
     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
diff --git a/pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/SessionListenerState.java b/pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/SessionListenerState.java
deleted file mode 100644 (file)
index bf9c868..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * 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;
-    }
-}
index 1bfc5012885bcf566afcba7604c8a4dbec9b27f3..b9f8f59149e9bb0c207c6c8ce34acb293104b890 100644 (file)
@@ -21,9 +21,9 @@ import java.util.ArrayList;
 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;
@@ -98,6 +98,10 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
     @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.
      *
@@ -115,7 +119,7 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
         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);
@@ -144,7 +148,7 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
     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);
@@ -240,7 +244,8 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
             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());
             }
 
@@ -264,7 +269,8 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
     }
 
     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()) {
@@ -356,7 +362,8 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
 
         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);
@@ -372,15 +379,21 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
     }
 
     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());
         }
@@ -396,12 +409,14 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
             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();
@@ -415,8 +430,9 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
         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;
@@ -442,10 +458,11 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
         @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();
             }
 
@@ -466,33 +483,36 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
                 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());
@@ -505,7 +525,8 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
 
     @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());
@@ -521,22 +542,24 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
             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();
     }
 
@@ -562,14 +585,16 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
             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());
                 }
             }
@@ -585,7 +610,8 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
         }
     }
 
-    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;
@@ -622,7 +648,8 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
 
     @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());
@@ -635,7 +662,8 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
 
     @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) {
@@ -654,7 +682,8 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
         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());
@@ -702,19 +731,6 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
         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
      *
@@ -723,7 +739,8 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
      * @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();
@@ -765,4 +782,30 @@ class Stateful07TopologySessionListener extends AbstractTopologySessionListener<
         }
         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());
+        }
+    }
 }
index fb86d2d38e6cf4dda656533eadf558228d3ad0c8..187b29958c9a426d76c15ec396687f2662b1b059 100644 (file)
@@ -7,9 +7,9 @@
  */
 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);
     }
 }
index b0eccac071d865b50d58e769719cd39437518e26..6e9ad881aabb2034a0b4919dcce4d776f891089b 100644 (file)
@@ -16,6 +16,7 @@ import com.google.common.util.concurrent.MoreExecutors;
 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;
@@ -49,22 +50,24 @@ final class TopologyNodeState implements AutoCloseable, TransactionChainListener
     //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 {
@@ -72,11 +75,11 @@ final class TopologyNodeState implements AutoCloseable, TransactionChainListener
         }
     }
 
-    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) {
@@ -98,7 +101,7 @@ final class TopologyNodeState implements AutoCloseable, TransactionChainListener
         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) {
@@ -108,7 +111,6 @@ final class TopologyNodeState implements AutoCloseable, TransactionChainListener
         //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()) {
@@ -129,7 +131,7 @@ final class TopologyNodeState implements AutoCloseable, TransactionChainListener
         }
     }
 
-    public synchronized Node getInitialNodeState() {
+    synchronized Node getInitialNodeState() {
         return this.initialNodeState;
     }
 
index 15d81a1a1ebd20dd4d8e88081cfd888c7dd7c696..fc76adf5401a040e954c1dae73ae127a58960351 100644 (file)
@@ -28,7 +28,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
 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;
index 55197eea57a2375ea02ae7193c203169afd97539..a8d8f6a0fedc8dd2cd46c5d741b940499c0c1e43 100644 (file)
@@ -19,6 +19,7 @@ import javax.annotation.Nonnull;
 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;
@@ -44,20 +45,27 @@ public final class PCEPTopologyProviderBean implements PCEPTopologyProviderDepen
     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);
@@ -81,7 +89,7 @@ public final class PCEPTopologyProviderBean implements PCEPTopologyProviderDepen
 
     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) {
@@ -109,6 +117,11 @@ public final class PCEPTopologyProviderBean implements PCEPTopologyProviderDepen
         return this.sessionListenerFactory;
     }
 
+    @Override
+    public TopologySessionStatsRegistry getStateRegistry() {
+        return this.stateRegistry;
+    }
+
     private class PCEPTopologyProviderBeanCSS implements ClusterSingletonService, AutoCloseable {
         private final ServiceGroupIdentifier sgi;
         private ServiceRegistration<?> serviceRegistration;
@@ -118,13 +131,13 @@ public final class PCEPTopologyProviderBean implements PCEPTopologyProviderDepen
         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);
index bb63b274797ab2cda0dd0143bb6c516ad97817b0..ed6b7053a5d1213e363441e98efb9c0af4fdc4e1 100644 (file)
@@ -7,7 +7,9 @@
  */
 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;
@@ -17,26 +19,32 @@ 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();
 }
index b9d0fff7549b5ecab18d57123204442eb48834e4..d89242977d87e63faa16ea70a2379cc48aeb5102 100644 (file)
@@ -20,7 +20,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 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;
diff --git a/pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/session/stats/SessionStateImpl.java b/pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/session/stats/SessionStateImpl.java
new file mode 100644 (file)
index 0000000..cfe7462
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * 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;
+    }
+}
diff --git a/pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/session/stats/TopologySessionStats.java b/pcep/topology/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/session/stats/TopologySessionStats.java
new file mode 100644 (file)
index 0000000..3fa91a8
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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();
+}
index 0d6beec38bf7ec43bc6aa417bb21c90c6e906daa..0b136ed219b81cd08f11868d00b7e65ab6588d82 100644 (file)
@@ -24,6 +24,8 @@
     <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"
@@ -43,5 +45,6 @@
         <argument ref="pcepDispatcher"/>
         <argument ref="rpcRegistry"/>
         <argument ref="Stateful07TopologySessionListenerFactory"/>
+        <argument ref="topologySessionStatsRegistry"/>
     </bean>
 </blueprint>
\ No newline at end of file
index 2c3ab403b34ffd82793606866ae7ba8d5e0fa10b..403f6ca72425e52e365778bcf13256352e6418b0 100644 (file)
@@ -11,7 +11,6 @@ module odl-pcep-topology-provider-cfg {
     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.";
@@ -185,7 +184,6 @@ module odl-pcep-topology-provider-cfg {
                         description "Elapsed time (in d:H:m:s) from session-up until now.";
                         type string;
                     }
-                    uses pcep-stats:pcep-session-state;
                 }
 
                 container peer-capabilities {
index 6350aa3ea52ee652a89075cb7e55e4a0317199e0..5f61246bc217e577516b36653650b4c3d1b6ec44 100644 (file)
@@ -34,11 +34,7 @@ import org.junit.Before;
 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;
@@ -72,8 +68,8 @@ public abstract class AbstractPCEPSessionTest<T extends TopologySessionListenerF
     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;
@@ -102,6 +98,9 @@ public abstract class AbstractPCEPSessionTest<T extends TopologySessionListenerF
     @Mock
     private ChannelFuture channelFuture;
 
+    @Mock
+    private TopologySessionStatsRegistry statsRegistry;
+
     private final Open localPrefs = new OpenBuilder().setDeadTimer((short) 30).setKeepalive((short) 10)
         .setSessionId((short) 0).build();
 
@@ -128,6 +127,8 @@ public abstract class AbstractPCEPSessionTest<T extends TopologySessionListenerF
         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();
@@ -140,7 +141,8 @@ public abstract class AbstractPCEPSessionTest<T extends TopologySessionListenerF
 
         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);
index 6c1c0fc94000eba365420c2a7431947c5a058892..3ad407263ad122d66b07c161e6010cdae82307b3 100755 (executable)
@@ -14,12 +14,11 @@ import static org.junit.Assert.assertNotNull;
 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;
@@ -31,7 +30,6 @@ import java.util.concurrent.TimeUnit;
 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;
@@ -72,6 +70,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.iet
 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;
@@ -118,18 +122,21 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
     @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());
@@ -139,13 +146,13 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         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());
@@ -168,24 +175,27 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         });
 
         // 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);
@@ -193,11 +203,11 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         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
@@ -209,36 +219,41 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
             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);
@@ -246,10 +261,10 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         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
@@ -258,12 +273,16 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
             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
@@ -281,7 +300,7 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         this.listener.onMessage(this.session, errorMsg);
 
         final AddLspOutput output = futureOutput.get().getResult();
-        assertEquals(FailureType.Failed ,output.getFailure());
+        assertEquals(FailureType.Failedoutput.getFailure());
         assertEquals(1, output.getError().size());
         final ErrorObject err = output.getError().get(0).getErrorObject();
         assertEquals(PCEPErrors.NON_ZERO_PLSPID.getErrorType(), err.getType().shortValue());
@@ -309,7 +328,7 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
      */
     @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());
@@ -332,7 +351,7 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
      */
     @Test
     public void testOnServerSessionManagerUnstarted() throws InterruptedException, ExecutionException,
-        TransactionCommitFailedException, ReadFailedException {
+            TransactionCommitFailedException, ReadFailedException {
         stopSessionManager();
         assertFalse(this.session.isClosed());
         this.listener.onSessionUp(this.session);
@@ -383,10 +402,10 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         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());
@@ -407,10 +426,10 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         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());
@@ -445,10 +464,10 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         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());
@@ -465,14 +484,14 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
     @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 -> {
@@ -485,14 +504,14 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
     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());
@@ -505,7 +524,7 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
     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());
@@ -524,11 +543,14 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         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
@@ -538,7 +560,7 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         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
@@ -552,7 +574,7 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
             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);
@@ -569,14 +591,18 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         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
@@ -589,26 +615,31 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         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
@@ -620,12 +651,12 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         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();
     }
 }
diff --git a/pcep/topology/topology-spi/src/main/java/org/opendaylight/bgpcep/pcep/topology/spi/stats/TopologySessionStatsRegistry.java b/pcep/topology/topology-spi/src/main/java/org/opendaylight/bgpcep/pcep/topology/spi/stats/TopologySessionStatsRegistry.java
new file mode 100644 (file)
index 0000000..d662dc1
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * 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);
+}
diff --git a/pcep/topology/topology-stats/pom.xml b/pcep/topology/topology-stats/pom.xml
new file mode 100644 (file)
index 0000000..41730f0
--- /dev/null
@@ -0,0 +1,82 @@
+<?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
diff --git a/pcep/topology/topology-stats/src/main/java/org/opendaylight/bgpcep/pcep/topology/stats/provider/TopologyStatsProviderImpl.java b/pcep/topology/topology-stats/src/main/java/org/opendaylight/bgpcep/pcep/topology/stats/provider/TopologyStatsProviderImpl.java
new file mode 100644 (file)
index 0000000..935a4cc
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * 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());
+        }
+    }
+}
diff --git a/pcep/topology/topology-stats/src/main/resources/org/opendaylight/blueprint/pcep-provider-stats.xml b/pcep/topology/topology-stats/src/main/resources/org/opendaylight/blueprint/pcep-provider-stats.xml
new file mode 100644 (file)
index 0000000..e2c6466
--- /dev/null
@@ -0,0 +1,27 @@
+<?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
diff --git a/pcep/topology/topology-stats/src/main/yang/odl-pcep-stats-provider.yang b/pcep/topology/topology-stats/src/main/yang/odl-pcep-stats-provider.yang
new file mode 100644 (file)
index 0000000..fc69144
--- /dev/null
@@ -0,0 +1,34 @@
+// 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