Bug-2081: PCEP statistics 67/11767/7
authorMilos Fabian <milfabia@cisco.com>
Mon, 6 Oct 2014 07:19:01 +0000 (09:19 +0200)
committerMilos Fabian <milfabia@cisco.com>
Thu, 16 Oct 2014 08:17:39 +0000 (10:17 +0200)
-PCEP session statistics:
-received/sent messages count
-received/sent error msgs count
-last sent msg timestamp
-last received/sent error type/value
-unknown msgs received count
-local and remote peer preferences
-keepalive, deadtimer, ip address, session-id
-PCEP session listener statistics
-remote peer stateful preferences
-session duration
-delegated lsps count
-synchronization status
-last received report msg timestamp
-received report msg count
-sent init/update msg count
-request time measurement
-tear down session op.
-reset statistics op.

-statistics are related to pcep-topology-provider config module
-reachable via JMX, NETCONF, Restconf as operational data

Change-Id: I40fd658028e386040fd6c90d805a5724aff6bddd
Signed-off-by: Milos Fabian <milfabia@cisco.com>
19 files changed:
pcep/api/src/main/java/org/opendaylight/protocol/pcep/PCEPSession.java
pcep/api/src/main/yang/pcep-session-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/PCEPSessionRuntimeMXBean.java [deleted file]
pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPSessionState.java [new file with mode: 0644]
pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/AbstractPCEPSessionTest.java
pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPDispatcherImplTest.java
pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPSessionImplTest.java
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractTopologySessionListener.java
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPRequest.java
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPTopologyProvider.java
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/ServerSessionManager.java
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/SessionListenerState.java [new file with mode: 0644]
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful02TopologySessionListener.java
pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful07TopologySessionListener.java
pcep/topology-provider/src/main/java/org/opendaylight/controller/config/yang/pcep/topology/provider/PCEPTopologyProviderModule.java
pcep/topology-provider/src/main/yang/odl-pcep-topology-provider-cfg.yang
pcep/topology-provider/src/test/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractPCEPSessionTest.java
pcep/topology-provider/src/test/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful07TopologySessionListenerTest.java

index bb15c92b02627bd7b375db2f618d1d611c81e112..1d5efe2548e027a79c602fe03832c8291d3f9805 100644 (file)
@@ -8,10 +8,9 @@
 package org.opendaylight.protocol.pcep;
 
 import io.netty.util.concurrent.Future;
 package org.opendaylight.protocol.pcep;
 
 import io.netty.util.concurrent.Future;
-
 import java.net.InetAddress;
 import java.net.InetAddress;
-
 import org.opendaylight.protocol.framework.ProtocolSession;
 import org.opendaylight.protocol.framework.ProtocolSession;
+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.types.rev131005.Message;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.open.Tlvs;
 
 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;
 
@@ -21,7 +20,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.
  */
  * 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 ProtocolSession<Message> {
+public interface PCEPSession extends ProtocolSession<Message>, PcepSessionState {
 
     /**
      * Sends message from user to PCE/PCC. If the user sends an Open Message, the session returns an error (open message
 
     /**
      * Sends message from user to PCE/PCC. If the user sends an Open Message, the session returns an error (open message
@@ -38,4 +37,6 @@ public interface PCEPSession extends ProtocolSession<Message> {
     Tlvs getRemoteTlvs();
 
     InetAddress getRemoteAddress();
     Tlvs getRemoteTlvs();
 
     InetAddress getRemoteAddress();
+
+    void resetStats();
 }
 }
diff --git a/pcep/api/src/main/yang/pcep-session-stats.yang b/pcep/api/src/main/yang/pcep-session-stats.yang
new file mode 100644 (file)
index 0000000..035ebb3
--- /dev/null
@@ -0,0 +1,124 @@
+// 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";
+    prefix "pcep-stats";
+
+    organization "Cisco Systems, Inc.";
+
+    contact "Milos Fabian <milfabia@cisco.com>";
+
+    description
+        "This module contains the base YANG definitions for
+         PCEP session statistics.
+
+        Copyright (c)2014 Cisco Systems, 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 "2014-10-06" {
+        description
+            "Initial revision";
+    }
+
+    grouping error {
+        description "PCEP Error-type/value.";
+        leaf error-type {
+            type uint8;
+            default 0;
+        }
+        leaf error-value {
+            type uint8;
+            default 0;
+        }
+    }
+
+    grouping preferences {
+        leaf keepalive {
+            description "Advertised keep-alive value.";
+            type uint8;
+            default 0;
+        }
+
+        leaf deadtimer {
+            description "Advertised deadtimer value.";
+            type uint8;
+            default 0;
+        }
+
+        leaf ip-address {
+            description "Peer's IP address.";
+            type string;
+            default "";
+        }
+
+        leaf session-id {
+            description "Peer's session identifier.";
+            type uint16;
+            default 0;
+        }
+    }
+
+    grouping pcep-session-state {
+        description "PCEP session statistics.";
+
+        container messages {
+            description "The statistics of PCEP received/sent messages from the PCE point of view.";
+            leaf received-msg-count {
+                description "Total number of received PCEP messages.";
+                type uint32;
+            }
+
+            leaf sent-msg-count {
+                description "Total number of sent PCEP messages.";
+                type uint32;
+            }
+
+            leaf last-sent-msg-timestamp {
+                description "The timestamp of last sent message.";
+                type uint32;
+            }
+
+            leaf unknown-msg-received {
+                description "The number of received unknown messages.";
+                type uint16;
+            }
+
+            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;
+                }
+            }
+        }
+
+        container local-pref {
+            description "The local (PCE) preferences.";
+            uses preferences;
+        }
+
+        container peer-pref {
+            description "The remote peer (PCC) preferences.";
+            uses preferences;
+        }
+    }
+}
\ No newline at end of file
index 5739ad1767c4b3248b595179d03b5174b681b966..a4aed7154d38d55091af687b12f9617576424668 100644 (file)
@@ -28,6 +28,9 @@ import org.opendaylight.protocol.pcep.PCEPSession;
 import org.opendaylight.protocol.pcep.PCEPSessionListener;
 import org.opendaylight.protocol.pcep.TerminationReason;
 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
 import org.opendaylight.protocol.pcep.PCEPSessionListener;
 import org.opendaylight.protocol.pcep.TerminationReason;
 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.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;
@@ -35,11 +38,13 @@ 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.KeepaliveMessage;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.OpenMessage;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.KeepaliveMessage;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.OpenMessage;
+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.close.message.CCloseMessageBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.close.object.CCloseBuilder;
 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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.close.message.CCloseMessageBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.close.object.CCloseBuilder;
 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;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -47,7 +52,7 @@ import org.slf4j.LoggerFactory;
  * Implementation of PCEPSession. (Not final for testing.)
  */
 @VisibleForTesting
  * Implementation of PCEPSession. (Not final for testing.)
  */
 @VisibleForTesting
-public class PCEPSessionImpl extends AbstractProtocolSession<Message> implements PCEPSession, PCEPSessionRuntimeMXBean {
+public class PCEPSessionImpl extends AbstractProtocolSession<Message> implements PCEPSession {
     /**
      * System.nanoTime value about when was sent the last message Protected to be updated also in tests.
      */
     /**
      * System.nanoTime value about when was sent the last message Protected to be updated also in tests.
      */
@@ -75,10 +80,6 @@ public class PCEPSessionImpl extends AbstractProtocolSession<Message> implements
 
     private static final Logger LOG = LoggerFactory.getLogger(PCEPSessionImpl.class);
 
 
     private static final Logger LOG = LoggerFactory.getLogger(PCEPSessionImpl.class);
 
-    private int sentMsgCount = 0;
-
-    private int receivedMsgCount = 0;
-
     private int maxUnknownMessages;
 
     // True if the listener should not be notified about events
     private int maxUnknownMessages;
 
     // True if the listener should not be notified about events
@@ -88,6 +89,8 @@ public class PCEPSessionImpl extends AbstractProtocolSession<Message> implements
 
     private final Keepalive kaMessage = new KeepaliveBuilder().setKeepaliveMessage(new KeepaliveMessageBuilder().build()).build();
 
 
     private final Keepalive kaMessage = new KeepaliveBuilder().setKeepaliveMessage(new KeepaliveMessageBuilder().build()).build();
 
+    private final PCEPSessionState sessionState;
+
     PCEPSessionImpl(final PCEPSessionListener listener, final int maxUnknownMessages, final Channel channel,
         final Open localOpen, final Open remoteOpen) {
         this.listener = Preconditions.checkNotNull(listener);
     PCEPSessionImpl(final PCEPSessionListener listener, final int maxUnknownMessages, final Channel channel,
         final Open localOpen, final Open remoteOpen) {
         this.listener = Preconditions.checkNotNull(listener);
@@ -121,6 +124,15 @@ public class PCEPSessionImpl extends AbstractProtocolSession<Message> implements
 
         LOG.info("Session {}[{}] <-> {}[{}] started", channel.localAddress(), localOpen.getSessionId(), channel.remoteAddress(),
             remoteOpen.getSessionId());
 
         LOG.info("Session {}[{}] <-> {}[{}] started", channel.localAddress(), localOpen.getSessionId(), channel.remoteAddress(),
             remoteOpen.getSessionId());
+        this.sessionState = new PCEPSessionState(remoteOpen, localOpen, channel);
+    }
+
+    public Integer getKeepAliveTimerValue() {
+        return this.localOpen.getKeepalive().intValue();
+    }
+
+    public Integer getDeadTimerValue() {
+        return this.remoteOpen.getDeadTimer().intValue();
     }
 
     /**
     }
 
     /**
@@ -184,10 +196,13 @@ public class PCEPSessionImpl extends AbstractProtocolSession<Message> implements
     public Future<Void> sendMessage(final Message msg) {
         final ChannelFuture f = this.channel.writeAndFlush(msg);
         this.lastMessageSentAt = System.nanoTime();
     public Future<Void> sendMessage(final Message msg) {
         final ChannelFuture f = this.channel.writeAndFlush(msg);
         this.lastMessageSentAt = System.nanoTime();
+        this.sessionState.updateLastSentMsg();
         if (!(msg instanceof KeepaliveMessage)) {
             LOG.debug("PCEP Message enqueued: {}", msg);
         }
         if (!(msg instanceof KeepaliveMessage)) {
             LOG.debug("PCEP Message enqueued: {}", msg);
         }
-        this.sentMsgCount++;
+        if (msg instanceof PcerrMessage) {
+            this.sessionState.setLastSentError(msg);
+        }
 
         f.addListener(new ChannelFutureListener() {
             @Override
 
         f.addListener(new ChannelFutureListener() {
             @Override
@@ -223,7 +238,7 @@ public class PCEPSessionImpl extends AbstractProtocolSession<Message> implements
         this.closed = true;
         this.sendMessage(new CloseBuilder().setCCloseMessage(
             new CCloseMessageBuilder().setCClose(new CCloseBuilder().setReason(reason.getShortValue()).build()).build()).build());
         this.closed = true;
         this.sendMessage(new CloseBuilder().setCCloseMessage(
             new CCloseMessageBuilder().setCClose(new CCloseBuilder().setReason(reason.getShortValue()).build()).build()).build());
-        this.channel.close();
+        this.close();
     }
 
     @Override
     }
 
     @Override
@@ -300,7 +315,7 @@ public class PCEPSessionImpl extends AbstractProtocolSession<Message> implements
     public synchronized void handleMessage(final Message msg) {
         // Update last reception time
         this.lastMessageReceivedAt = System.nanoTime();
     public synchronized void handleMessage(final Message msg) {
         // Update last reception time
         this.lastMessageReceivedAt = System.nanoTime();
-        this.receivedMsgCount++;
+        this.sessionState.updateLastReceivedMsg();
         if (!(msg instanceof KeepaliveMessage)) {
             LOG.debug("PCEP message {} received.", msg);
         }
         if (!(msg instanceof KeepaliveMessage)) {
             LOG.debug("PCEP message {} received.", msg);
         }
@@ -318,74 +333,57 @@ public class PCEPSessionImpl extends AbstractProtocolSession<Message> implements
             this.close();
         } else {
             // This message needs to be handled by the user
             this.close();
         } else {
             // This message needs to be handled by the user
+            if (msg instanceof PcerrMessage) {
+                this.sessionState.setLastReceivedError(msg);
+            }
             this.listener.onMessage(this, msg);
         }
     }
 
             this.listener.onMessage(this, msg);
         }
     }
 
-    /**
-     * @return the sentMsgCount
-     */
-
     @Override
     @Override
-    public final Integer getSentMsgCount() {
-        return this.sentMsgCount;
+    public final String toString() {
+        return addToStringAttributes(Objects.toStringHelper(this)).toString();
     }
 
     }
 
-    /**
-     * @return the receivedMsgCount
-     */
-
-    @Override
-    public final Integer getReceivedMsgCount() {
-        return this.receivedMsgCount;
+    protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
+        toStringHelper.add("channel", this.channel);
+        toStringHelper.add("localOpen", this.localOpen);
+        toStringHelper.add("remoteOpen", this.remoteOpen);
+        return toStringHelper;
     }
 
     @Override
     }
 
     @Override
-    public final Integer getDeadTimerValue() {
-        return Integer.valueOf(this.remoteOpen.getDeadTimer());
+    @VisibleForTesting
+    public void sessionUp() {
+        this.listener.onSessionUp(this);
     }
 
     }
 
-    @Override
-    public final Integer getKeepAliveTimerValue() {
-        return Integer.valueOf(this.localOpen.getKeepalive());
+    @VisibleForTesting
+    protected final Queue<Long> getUnknownMessagesTimes() {
+        return this.unknownMessagesTimes;
     }
 
     @Override
     }
 
     @Override
-    public final String getPeerAddress() {
-        final InetSocketAddress a = (InetSocketAddress) this.channel.remoteAddress();
-        return a.getHostName();
+    public Messages getMessages() {
+        return this.sessionState.getMessages(this.unknownMessagesTimes.size());
     }
 
     @Override
     }
 
     @Override
-    public void tearDown() {
-        this.close();
+    public LocalPref getLocalPref() {
+        return this.sessionState.getLocalPref();
     }
 
     @Override
     }
 
     @Override
-    public final String toString() {
-        return addToStringAttributes(Objects.toStringHelper(this)).toString();
-    }
-
-    protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
-        toStringHelper.add("channel", this.channel);
-        toStringHelper.add("localOpen", this.localOpen);
-        toStringHelper.add("remoteOpen", this.remoteOpen);
-        return toStringHelper;
+    public PeerPref getPeerPref() {
+        return this.sessionState.getPeerPref();
     }
 
     @Override
     }
 
     @Override
-    @VisibleForTesting
-    public void sessionUp() {
-        this.listener.onSessionUp(this);
+    public Class<? extends DataContainer> getImplementedInterface() {
+        throw new UnsupportedOperationException();
     }
     }
-
     @Override
     @Override
-    public String getNodeIdentifier() {
-        return "";
-    }
-
-    @VisibleForTesting
-    protected final Queue<Long> getUnknownMessagesTimes() {
-        return this.unknownMessagesTimes;
+    public void resetStats() {
+        this.sessionState.reset();
     }
 }
     }
 }
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPSessionRuntimeMXBean.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPSessionRuntimeMXBean.java
deleted file mode 100644 (file)
index 6d951cf..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2013 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.protocol.pcep.impl;
-
-import java.io.IOException;
-
-public interface PCEPSessionRuntimeMXBean {
-    // FIXME: BUG-194: remove once operations are generated
-
-    Integer getDeadTimerValue();
-
-    Integer getKeepAliveTimerValue();
-
-    Integer getReceivedMsgCount();
-
-    Integer getSentMsgCount();
-
-    String getPeerAddress();
-
-    String getNodeIdentifier();
-
-    void tearDown() throws IOException;
-}
diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPSessionState.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPSessionState.java
new file mode 100644 (file)
index 0000000..be4e34b
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * 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.protocol.pcep.impl;
+
+import com.google.common.base.Preconditions;
+import io.netty.channel.Channel;
+import java.net.InetSocketAddress;
+import java.util.concurrent.TimeUnit;
+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.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;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.pcep.error.object.ErrorObject;
+
+final class PCEPSessionState {
+    private long sentMsgCount = 0;
+    private long receivedMsgCount = 0;
+    private long sentErrMsgCount = 0;
+    private long receivedErrMsgCount = 0;
+    private long lastSentMsgTimestamp = 0;
+    private final PeerPref peerPref;
+    private final LocalPref localPref;
+    private final LastReceivedErrorBuilder lastReceivedErrorBuilder;
+    private final LastSentErrorBuilder lastSentErrorBuilder;
+    private final ErrorMessagesBuilder errorsBuilder;
+    private final MessagesBuilder msgsBuilder;
+
+    public PCEPSessionState(final Open remoteOpen, final Open localOpen, final Channel channel) {
+        Preconditions.checkNotNull(remoteOpen);
+        Preconditions.checkNotNull(localOpen);
+        Preconditions.checkNotNull(channel);
+        this.peerPref = getRemotePref(remoteOpen, channel);
+        this.localPref = getLocalPref(localOpen, channel);
+        this.lastReceivedErrorBuilder = new LastReceivedErrorBuilder();
+        this.lastSentErrorBuilder = new LastSentErrorBuilder();
+        this.errorsBuilder = new ErrorMessagesBuilder();
+        this.msgsBuilder = new MessagesBuilder();
+    }
+
+    public Messages getMessages(final int unknownMessagesCount) {
+        this.errorsBuilder.setReceivedErrorMsgCount(this.receivedErrMsgCount);
+        this.errorsBuilder.setSentErrorMsgCount(this.sentErrMsgCount);
+        this.errorsBuilder.setLastReceivedError(this.lastReceivedErrorBuilder.build());
+        this.errorsBuilder.setLastSentError(this.lastSentErrorBuilder.build());
+        this.msgsBuilder.setLastSentMsgTimestamp(TimeUnit.MILLISECONDS.toSeconds(this.lastSentMsgTimestamp));
+        this.msgsBuilder.setReceivedMsgCount(this.receivedMsgCount);
+        this.msgsBuilder.setSentMsgCount(this.sentMsgCount);
+        this.msgsBuilder.setUnknownMsgReceived(unknownMessagesCount);
+        this.msgsBuilder.setErrorMessages(this.errorsBuilder.build());
+        return this.msgsBuilder.build();
+    }
+
+    public void reset() {
+        this.receivedMsgCount = 0;
+        this.sentMsgCount = 0;
+        this.receivedErrMsgCount = 0;
+        this.sentErrMsgCount = 0;
+        this.lastSentMsgTimestamp = 0;
+        this.lastReceivedErrorBuilder.setErrorType((short) 0);
+        this.lastReceivedErrorBuilder.setErrorValue((short) 0);
+        this.lastSentErrorBuilder.setErrorType((short) 0);
+        this.lastSentErrorBuilder.setErrorValue((short) 0);
+    }
+
+    public LocalPref getLocalPref() {
+        return this.localPref;
+    }
+
+    public PeerPref getPeerPref() {
+        return this.peerPref;
+    }
+
+    public 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) {
+        final ErrorObject errObj = getErrorObject(msg);
+        this.receivedErrMsgCount++;
+        this.lastReceivedErrorBuilder.setErrorType(errObj.getType());
+        this.lastReceivedErrorBuilder.setErrorValue(errObj.getValue());
+    }
+
+    public void updateLastReceivedMsg() {
+        this.receivedMsgCount++;
+    }
+
+    public void updateLastSentMsg() {
+        this.lastSentMsgTimestamp = System.currentTimeMillis();
+        this.sentMsgCount++;
+    }
+
+    private static ErrorObject getErrorObject(final Message msg) {
+        Preconditions.checkNotNull(msg);
+        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();
+    }
+
+    private static PeerPref getRemotePref(final Open open, final Channel channel) {
+        final PeerPrefBuilder peerBuilder = new PeerPrefBuilder();
+        peerBuilder.setDeadtimer(open.getDeadTimer());
+        peerBuilder.setKeepalive(open.getKeepalive());
+        peerBuilder.setIpAddress(((InetSocketAddress) channel.remoteAddress()).getAddress().getHostAddress());
+        peerBuilder.setSessionId(open.getSessionId().intValue());
+        return peerBuilder.build();
+    }
+
+    private static LocalPref getLocalPref(final Open open, final Channel channel) {
+        final LocalPrefBuilder peerBuilder = new LocalPrefBuilder();
+        peerBuilder.setDeadtimer(open.getDeadTimer());
+        peerBuilder.setKeepalive(open.getKeepalive());
+        peerBuilder.setIpAddress(((InetSocketAddress) channel.localAddress()).getAddress().getHostAddress());
+        peerBuilder.setSessionId(open.getSessionId().intValue());
+        return peerBuilder.build();
+    }
+}
index 4eb9f9d2d141fb37663e3a6c474049103ebaf5a7..bb491f59006eb8a132ea186a1123157f3a88e451 100644 (file)
@@ -40,6 +40,10 @@ import org.opendaylight.yangtools.yang.binding.Notification;
 
 public class AbstractPCEPSessionTest {
 
 
 public class AbstractPCEPSessionTest {
 
+    protected static final String IP_ADDRESS = "127.0.0.1";
+    protected static final short KEEP_ALIVE = 15;
+    protected static final short DEADTIMER = 40;
+
     @Mock
     protected Channel channel;
 
     @Mock
     protected Channel channel;
 
@@ -85,12 +89,12 @@ public class AbstractPCEPSessionTest {
         doReturn(this.pipeline).when(this.pipeline).replace(any(ChannelHandler.class), any(String.class), any(ChannelHandler.class));
         doReturn(true).when(this.channel).isActive();
         doReturn(mock(ChannelFuture.class)).when(this.channel).close();
         doReturn(this.pipeline).when(this.pipeline).replace(any(ChannelHandler.class), any(String.class), any(ChannelHandler.class));
         doReturn(true).when(this.channel).isActive();
         doReturn(mock(ChannelFuture.class)).when(this.channel).close();
-        doReturn(InetSocketAddress.createUnresolved("127.0.0.1", 4189)).when(this.channel).remoteAddress();
-        doReturn(InetSocketAddress.createUnresolved("127.0.0.1", 4189)).when(this.channel).localAddress();
+        doReturn(new InetSocketAddress(IP_ADDRESS, 4189)).when(this.channel).remoteAddress();
+        doReturn(new InetSocketAddress(IP_ADDRESS, 4189)).when(this.channel).localAddress();
         this.openMsg = new OpenBuilder().setOpenMessage(
                 new OpenMessageBuilder().setOpen(
                         new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.OpenBuilder().setDeadTimer(
         this.openMsg = new OpenBuilder().setOpenMessage(
                 new OpenMessageBuilder().setOpen(
                         new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.open.object.OpenBuilder().setDeadTimer(
-                                (short) 45).setKeepalive((short) 15).build()).build()).build();
+                                DEADTIMER).setKeepalive(KEEP_ALIVE).setSessionId((short) 0).build()).build()).build();
         this.kaMsg = new KeepaliveBuilder().setKeepaliveMessage(new KeepaliveMessageBuilder().build()).build();
 
         this.listener = new SimpleSessionListener();
         this.kaMsg = new KeepaliveBuilder().setKeepaliveMessage(new KeepaliveMessageBuilder().build()).build();
 
         this.listener = new SimpleSessionListener();
index fc52bcdee92d43381c077ab868a0a7b15d608427..f513a2a29818bdb3ce31c84378ac91a4f46d9667 100644 (file)
@@ -91,11 +91,11 @@ public class PCEPDispatcherImplTest {
                 }).get();
 
         Assert.assertTrue(futureChannel.channel().isActive());
                 }).get();
 
         Assert.assertTrue(futureChannel.channel().isActive());
-        Assert.assertEquals(CLIENT1_ADDRESS.getAddress().getHostAddress(), session1.getPeerAddress());
+        Assert.assertEquals(CLIENT1_ADDRESS.getAddress().getHostAddress(), session1.getPeerPref().getIpAddress());
         Assert.assertEquals(DEAD_TIMER, session1.getDeadTimerValue().shortValue());
         Assert.assertEquals(KEEP_ALIVE, session1.getKeepAliveTimerValue().shortValue());
 
         Assert.assertEquals(DEAD_TIMER, session1.getDeadTimerValue().shortValue());
         Assert.assertEquals(KEEP_ALIVE, session1.getKeepAliveTimerValue().shortValue());
 
-        Assert.assertEquals(CLIENT2_ADDRESS.getAddress().getHostAddress(), session2.getPeerAddress());
+        Assert.assertEquals(CLIENT2_ADDRESS.getAddress().getHostAddress(), session2.getPeerPref().getIpAddress());
         Assert.assertEquals(DEAD_TIMER, session2.getDeadTimerValue().shortValue());
         Assert.assertEquals(KEEP_ALIVE, session2.getKeepAliveTimerValue().shortValue());
 
         Assert.assertEquals(DEAD_TIMER, session2.getDeadTimerValue().shortValue());
         Assert.assertEquals(KEEP_ALIVE, session2.getKeepAliveTimerValue().shortValue());
 
index 4b653345f92ba3cf8aadea1831f1e9530cbc7720..46f632237dc594553d30fc50484c67164f1f709f 100644 (file)
@@ -15,6 +15,10 @@ import org.junit.Test;
 import org.mockito.Mockito;
 import org.opendaylight.protocol.pcep.TerminationReason;
 import org.opendaylight.protocol.pcep.spi.PCEPErrors;
 import org.mockito.Mockito;
 import org.opendaylight.protocol.pcep.TerminationReason;
 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.CloseBuilder;
 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.CloseBuilder;
 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;
@@ -34,34 +38,36 @@ public class PCEPSessionImplTest extends AbstractPCEPSessionTest {
 
     @After
     public void tearDown() {
 
     @After
     public void tearDown() {
-        this.session.tearDown();
+        this.session.close();
     }
 
     @Test
     public void testPcepSessionImpl() throws InterruptedException {
         Assert.assertTrue(this.listener.up);
 
     }
 
     @Test
     public void testPcepSessionImpl() throws InterruptedException {
         Assert.assertTrue(this.listener.up);
 
-        Assert.assertEquals(45, this.session.getDeadTimerValue().intValue());
-        Assert.assertEquals(15, this.session.getKeepAliveTimerValue().intValue());
         this.session.handleMessage(this.kaMsg);
         this.session.handleMessage(this.kaMsg);
-        Assert.assertEquals(1, this.session.getReceivedMsgCount().intValue());
+        Assert.assertEquals(1, this.session.getMessages().getReceivedMsgCount().intValue());
 
         this.session.handleMessage(new PcreqBuilder().build());
 
         this.session.handleMessage(new PcreqBuilder().build());
-        Assert.assertEquals(2, this.session.getReceivedMsgCount().intValue());
+        Assert.assertEquals(2, this.session.getMessages().getReceivedMsgCount().intValue());
         Assert.assertEquals(1, this.listener.messages.size());
         Assert.assertTrue(this.listener.messages.get(0) instanceof Pcreq);
         Assert.assertEquals(1, this.listener.messages.size());
         Assert.assertTrue(this.listener.messages.get(0) instanceof Pcreq);
+        Assert.assertEquals(2, this.session.getMessages().getReceivedMsgCount().intValue());
 
         this.session.handleMessage(new CloseBuilder().build());
 
         this.session.handleMessage(new CloseBuilder().build());
-        Assert.assertEquals(3, this.session.getReceivedMsgCount().intValue());
+        Assert.assertEquals(3, this.session.getMessages().getReceivedMsgCount().intValue());
         Assert.assertEquals(1, this.listener.messages.size());
         Assert.assertTrue(this.channel.isActive());
         Mockito.verify(this.channel, Mockito.times(1)).close();
         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
     public void testAttemptSecondSession() {
         this.session.handleMessage(this.openMsg);
     }
 
     @Test
     public void testAttemptSecondSession() {
         this.session.handleMessage(this.openMsg);
-        Assert.assertEquals(1, this.session.getReceivedMsgCount().intValue());
+        Assert.assertEquals(1, this.session.getMessages().getReceivedMsgCount().intValue());
         Assert.assertEquals(1, this.msgsSend.size());
         Assert.assertTrue(this.msgsSend.get(0) instanceof Pcerr);
         final Pcerr pcErr = (Pcerr) this.msgsSend.get(0);
         Assert.assertEquals(1, this.msgsSend.size());
         Assert.assertTrue(this.msgsSend.get(0) instanceof Pcerr);
         final Pcerr pcErr = (Pcerr) this.msgsSend.get(0);
@@ -77,7 +83,7 @@ public class PCEPSessionImplTest extends AbstractPCEPSessionTest {
         final Pcerr pcErr = (Pcerr) this.msgsSend.get(0);
         final ErrorObject errorObj = pcErr.getPcerrMessage().getErrors().get(0).getErrorObject();
         Assert.assertEquals(PCEPErrors.CAPABILITY_NOT_SUPPORTED, PCEPErrors.forValue(errorObj.getType(), errorObj.getValue()));
         final Pcerr pcErr = (Pcerr) this.msgsSend.get(0);
         final ErrorObject errorObj = pcErr.getPcerrMessage().getErrors().get(0).getErrorObject();
         Assert.assertEquals(PCEPErrors.CAPABILITY_NOT_SUPPORTED, PCEPErrors.forValue(errorObj.getType(), errorObj.getValue()));
-        Assert.assertEquals(1, this.session.getUnknownMessagesTimes().size());
+        Assert.assertEquals(1, this.session.getMessages().getUnknownMsgReceived().intValue());
         // exceeded max. unknown messages count - terminate session
         Assert.assertTrue(this.msgsSend.get(1) instanceof CloseMessage);
         final CloseMessage closeMsg = (CloseMessage) this.msgsSend.get(1);
         // exceeded max. unknown messages count - terminate session
         Assert.assertTrue(this.msgsSend.get(1) instanceof CloseMessage);
         final CloseMessage closeMsg = (CloseMessage) this.msgsSend.get(1);
@@ -93,7 +99,7 @@ public class PCEPSessionImplTest extends AbstractPCEPSessionTest {
     }
 
     @Test
     }
 
     @Test
-    public void voidTestCloseSessionWithReason() {
+    public void testCloseSessionWithReason() {
         this.session.close(TerminationReason.Unknown);
         Assert.assertEquals(1, this.msgsSend.size());
         Assert.assertTrue(this.msgsSend.get(0) instanceof CloseMessage);
         this.session.close(TerminationReason.Unknown);
         Assert.assertEquals(1, this.msgsSend.size());
         Assert.assertTrue(this.msgsSend.get(0) instanceof CloseMessage);
@@ -101,4 +107,40 @@ public class PCEPSessionImplTest extends AbstractPCEPSessionTest {
         Assert.assertEquals(TerminationReason.Unknown, TerminationReason.forValue(closeMsg.getCCloseMessage().getCClose().getReason()));
         Mockito.verify(this.channel, Mockito.times(1)).close();
     }
         Assert.assertEquals(TerminationReason.Unknown, TerminationReason.forValue(closeMsg.getCCloseMessage().getCClose().getReason()));
         Mockito.verify(this.channel, Mockito.times(1)).close();
     }
+
+    @Test
+    public void testSessionStatistics() {
+        this.session.handleMessage(Util.createErrorMessage(PCEPErrors.LSP_RSVP_ERROR, null));
+        Assert.assertEquals(IP_ADDRESS, this.session.getPeerPref().getIpAddress());
+        final PeerPref peerPref = this.session.getPeerPref();
+        Assert.assertEquals(IP_ADDRESS, peerPref.getIpAddress());
+        Assert.assertEquals(DEADTIMER, peerPref.getDeadtimer().shortValue());
+        Assert.assertEquals(KEEP_ALIVE, peerPref.getKeepalive().shortValue());
+        Assert.assertEquals(0, peerPref.getSessionId().intValue());
+        final LocalPref localPref = this.session.getLocalPref();
+        Assert.assertEquals(IP_ADDRESS, localPref.getIpAddress());
+        Assert.assertEquals(DEADTIMER, localPref.getDeadtimer().shortValue());
+        Assert.assertEquals(KEEP_ALIVE, localPref.getKeepalive().shortValue());
+        Assert.assertEquals(0, localPref.getSessionId().intValue());
+        final Messages msgs = this.session.getMessages();
+        Assert.assertEquals(1, msgs.getReceivedMsgCount().longValue());
+        Assert.assertEquals(0, msgs.getSentMsgCount().longValue());
+        Assert.assertEquals(0, msgs.getUnknownMsgReceived().longValue());
+        final ErrorMessages errMsgs = msgs.getErrorMessages();
+        Assert.assertEquals(1, errMsgs.getReceivedErrorMsgCount().intValue());
+        Assert.assertEquals(0, errMsgs.getSentErrorMsgCount().intValue());
+        Assert.assertEquals(PCEPErrors.LSP_RSVP_ERROR.getErrorType(), errMsgs.getLastReceivedError().getErrorType().shortValue());
+        Assert.assertEquals(PCEPErrors.LSP_RSVP_ERROR.getErrorValue(), errMsgs.getLastReceivedError().getErrorValue().shortValue());
+
+        this.session.sendMessage(Util.createErrorMessage(PCEPErrors.UNKNOWN_PLSP_ID, null));
+        final Messages msgs2 = this.session.getMessages();
+        Assert.assertEquals(1, msgs2.getReceivedMsgCount().longValue());
+        Assert.assertEquals(1, msgs2.getSentMsgCount().longValue());
+        Assert.assertEquals(0, msgs2.getUnknownMsgReceived().longValue());
+        final ErrorMessages errMsgs2 = msgs2.getErrorMessages();
+        Assert.assertEquals(1, errMsgs2.getReceivedErrorMsgCount().intValue());
+        Assert.assertEquals(1, errMsgs2.getSentErrorMsgCount().intValue());
+        Assert.assertEquals(PCEPErrors.UNKNOWN_PLSP_ID.getErrorType(), errMsgs2.getLastSentError().getErrorType().shortValue());
+        Assert.assertEquals(PCEPErrors.UNKNOWN_PLSP_ID.getErrorValue(), errMsgs2.getLastSentError().getErrorValue().shortValue());
+    }
 }
 }
index 2424fec4857e30ccef33bdf53dd9b789a5adb42f..1531ddc0d1720a572ff249e24c1ffddd03dc6b4d 100644 (file)
@@ -21,6 +21,12 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import javax.annotation.concurrent.GuardedBy;
 import java.util.Map;
 import java.util.Map.Entry;
 import javax.annotation.concurrent.GuardedBy;
+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.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.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;
 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;
@@ -59,7 +65,7 @@ import org.slf4j.LoggerFactory;
  * @param <S> identifier type of requests
  * @param <L> identifier type for LSPs
  */
  * @param <S> identifier type of requests
  * @param <L> identifier type for LSPs
  */
-public abstract class AbstractTopologySessionListener<S, L> implements PCEPSessionListener, TopologySessionListener {
+public abstract class AbstractTopologySessionListener<S, L> implements PCEPSessionListener, TopologySessionListener, ListenerStateRuntimeMXBean {
     protected static final class MessageContext {
         private final Collection<PCEPRequest> requests = new ArrayList<>();
         private final WriteTransaction trans;
     protected static final class MessageContext {
         private final Collection<PCEPRequest> requests = new ArrayList<>();
         private final WriteTransaction trans;
@@ -92,6 +98,7 @@ public abstract class AbstractTopologySessionListener<S, L> implements PCEPSessi
             return this.version;
         }
     };
             return this.version;
         }
     };
+
     private static final Logger LOG = LoggerFactory.getLogger(AbstractTopologySessionListener.class);
 
     protected static final String MISSING_XML_TAG = "Mandatory XML tags are missing.";
     private static final Logger LOG = LoggerFactory.getLogger(AbstractTopologySessionListener.class);
 
     protected static final String MISSING_XML_TAG = "Mandatory XML tags are missing.";
@@ -111,8 +118,12 @@ public abstract class AbstractTopologySessionListener<S, L> implements PCEPSessi
     private boolean synced = false;
     private PCEPSession session;
 
     private boolean synced = false;
     private PCEPSession session;
 
+    private ListenerStateRuntimeRegistration registration;
+    private final SessionListenerState listenerState;
+
     protected AbstractTopologySessionListener(final ServerSessionManager serverSessionManager) {
         this.serverSessionManager = Preconditions.checkNotNull(serverSessionManager);
     protected AbstractTopologySessionListener(final ServerSessionManager serverSessionManager) {
         this.serverSessionManager = Preconditions.checkNotNull(serverSessionManager);
+        this.listenerState = new SessionListenerState();
     }
 
     @Override
     }
 
     @Override
@@ -160,6 +171,10 @@ public abstract class AbstractTopologySessionListener<S, L> implements PCEPSessi
 
         this.session = session;
         this.nodeState = state;
 
         this.session = session;
         this.nodeState = state;
+        this.listenerState.init(session);
+        if (this.serverSessionManager.getRuntimeRootRegistration().isPresent()) {
+            this.registration = this.serverSessionManager.getRuntimeRootRegistration().get().register(this);
+        }
         LOG.info("Session with {} attached to topology node {}", session.getRemoteAddress(), state.getNodeId());
     }
 
         LOG.info("Session with {} attached to topology node {}", session.getRemoteAddress(), state.getNodeId());
     }
 
@@ -230,6 +245,9 @@ public abstract class AbstractTopologySessionListener<S, L> implements PCEPSessi
 
     @Override
     public void close() {
 
     @Override
     public void close() {
+        if (this.registration != null) {
+            this.registration.close();
+        }
         if (this.session != null) {
             this.session.close(TerminationReason.Unknown);
         }
         if (this.session != null) {
             this.session.close(TerminationReason.Unknown);
         }
@@ -237,6 +255,7 @@ public abstract class AbstractTopologySessionListener<S, L> implements PCEPSessi
 
     protected final synchronized PCEPRequest removeRequest(final S id) {
         final PCEPRequest ret = this.requests.remove(id);
 
     protected final synchronized PCEPRequest removeRequest(final S id) {
         final PCEPRequest ret = this.requests.remove(id);
+        this.listenerState.processRequestStats(ret.getElapsedMillis());
         LOG.trace("Removed request {} object {}", id, ret);
         return ret;
     }
         LOG.trace("Removed request {} object {}", id, ret);
         return ret;
     }
@@ -244,6 +263,7 @@ public abstract class AbstractTopologySessionListener<S, L> implements PCEPSessi
     protected 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);
     protected 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);
         final PCEPRequest req = new PCEPRequest(metadata);
         this.requests.put(requestId, req);
 
         final PCEPRequest req = new PCEPRequest(metadata);
         this.requests.put(requestId, req);
 
@@ -418,4 +438,53 @@ public abstract class AbstractTopologySessionListener<S, L> implements PCEPSessi
     }
 
     protected abstract Object validateReportedLsp(final Optional<ReportedLsp> rep, final LspId input);
     }
 
     protected abstract Object validateReportedLsp(final Optional<ReportedLsp> rep, final LspId input);
+
+    protected SessionListenerState getSessionListenerState() {
+        return this.listenerState;
+    }
+
+    @Override
+    public Integer getDelegatedLspsCount() {
+        return this.lsps.size();
+    }
+
+    @Override
+    public Boolean getSynchronized() {
+        return this.synced;
+    }
+
+    @Override
+    public StatefulMessages getStatefulMessages() {
+        return this.listenerState.getStatefulMessages();
+    }
+
+    @Override
+    public void resetStats() {
+        this.listenerState.resetStats(this.session);
+    }
+
+    @Override
+    public ReplyTime getReplyTime() {
+        return this.listenerState.getReplyTime();
+    }
+
+    @Override
+    public PeerCapabilities getPeerCapabilities() {
+        return this.listenerState.getPeerCapabilities();
+    }
+
+    @Override
+    public void tearDownSession() {
+        this.close();
+    }
+
+    @Override
+    public SessionState getSessionState() {
+        return this.listenerState.getSessionState(this.session);
+    }
+
+    @Override
+    public String getPeerId() {
+        return this.session.getPeerPref().getIpAddress();
+    }
 }
 }
index 95a3e082fa91ce176fb2f18b97665c539101edfc..5feea8267476392e97b6fba4eb6cb406084eacda 100644 (file)
@@ -7,9 +7,10 @@
  */
 package org.opendaylight.bgpcep.pcep.topology.provider;
 
  */
 package org.opendaylight.bgpcep.pcep.topology.provider;
 
+import com.google.common.base.Stopwatch;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.SettableFuture;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.SettableFuture;
-
+import java.util.concurrent.TimeUnit;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.OperationResult;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.lsp.metadata.Metadata;
 import org.slf4j.Logger;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.OperationResult;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.lsp.metadata.Metadata;
 import org.slf4j.Logger;
@@ -26,11 +27,13 @@ final class PCEPRequest {
     private final SettableFuture<OperationResult> future;
     private final Metadata metadata;
     private volatile State state;
     private final SettableFuture<OperationResult> future;
     private final Metadata metadata;
     private volatile State state;
+    private final Stopwatch stopwatch;
 
     PCEPRequest(final Metadata metadata) {
         this.future = SettableFuture.create();
         this.metadata = metadata;
         this.state = State.UNSENT;
 
     PCEPRequest(final Metadata metadata) {
         this.future = SettableFuture.create();
         this.metadata = metadata;
         this.state = State.UNSENT;
+        this.stopwatch = new Stopwatch().start();
     }
 
     protected ListenableFuture<OperationResult> getFuture() {
     }
 
     protected ListenableFuture<OperationResult> getFuture() {
@@ -59,4 +62,8 @@ final class PCEPRequest {
             state = State.UNACKED;
         }
     }
             state = State.UNACKED;
         }
     }
+
+    public long getElapsedMillis() {
+        return this.stopwatch.elapsed(TimeUnit.MILLISECONDS);
+    }
 }
\ No newline at end of file
 }
\ No newline at end of file
index 0b2699e443b47bb8a695900298a7c93c8a0987fd..e85737a86c9c60380ce883bd45184fbc7d32f63e 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.bgpcep.pcep.topology.provider;
 
  */
 package org.opendaylight.bgpcep.pcep.topology.provider;
 
+import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
 import com.google.common.base.Preconditions;
 import io.netty.channel.Channel;
 import io.netty.channel.ChannelFuture;
@@ -15,6 +16,7 @@ import java.net.InetSocketAddress;
 import java.util.concurrent.ExecutionException;
 import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
 import org.opendaylight.bgpcep.topology.DefaultTopologyReference;
 import java.util.concurrent.ExecutionException;
 import org.opendaylight.bgpcep.programming.spi.InstructionScheduler;
 import org.opendaylight.bgpcep.topology.DefaultTopologyReference;
+import org.opendaylight.controller.config.yang.pcep.topology.provider.PCEPTopologyProviderRuntimeRegistrator;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
@@ -50,10 +52,14 @@ public final class PCEPTopologyProvider extends DefaultTopologyReference impleme
 
     public static PCEPTopologyProvider create(final PCEPDispatcher dispatcher, final InetSocketAddress address, final KeyMapping keys,
             final InstructionScheduler scheduler, final DataBroker dataBroker, final RpcProviderRegistry rpcRegistry,
 
     public static PCEPTopologyProvider create(final PCEPDispatcher dispatcher, final InetSocketAddress address, final KeyMapping keys,
             final InstructionScheduler scheduler, final DataBroker dataBroker, final RpcProviderRegistry rpcRegistry,
-            final InstanceIdentifier<Topology> topology, final TopologySessionListenerFactory listenerFactory) throws InterruptedException,
+            final InstanceIdentifier<Topology> topology, final TopologySessionListenerFactory listenerFactory,
+            Optional<PCEPTopologyProviderRuntimeRegistrator> runtimeRootRegistrator) throws InterruptedException,
             ExecutionException, ReadFailedException, TransactionCommitFailedException {
 
         final ServerSessionManager manager = new ServerSessionManager(dataBroker, topology, listenerFactory);
             ExecutionException, ReadFailedException, TransactionCommitFailedException {
 
         final ServerSessionManager manager = new ServerSessionManager(dataBroker, topology, listenerFactory);
+        if (runtimeRootRegistrator.isPresent()) {
+            manager.registerRuntimeRootRegistartion(runtimeRootRegistrator.get());
+        }
         final ChannelFuture f = dispatcher.createServer(address, keys, manager);
         f.get();
 
         final ChannelFuture f = dispatcher.createServer(address, keys, manager);
         f.get();
 
index afc7172f89ee03f5af6a32431cdc4aec6eb8217a..f3afdfae8392a313d417838b71aee3a716575ee7 100644 (file)
@@ -15,6 +15,9 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.TimeUnit;
+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.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
@@ -47,7 +50,7 @@ import org.slf4j.LoggerFactory;
 /**
  *
  */
 /**
  *
  */
-final class ServerSessionManager implements SessionListenerFactory<PCEPSessionListener>, AutoCloseable, TopologySessionRPCs {
+final class ServerSessionManager implements SessionListenerFactory<PCEPSessionListener>, AutoCloseable, TopologySessionRPCs, PCEPTopologyProviderRuntimeMXBean {
     private static final Logger LOG = LoggerFactory.getLogger(ServerSessionManager.class);
     private static final long DEFAULT_HOLD_STATE_NANOS = TimeUnit.MINUTES.toNanos(5);
 
     private static final Logger LOG = LoggerFactory.getLogger(ServerSessionManager.class);
     private static final long DEFAULT_HOLD_STATE_NANOS = TimeUnit.MINUTES.toNanos(5);
 
@@ -56,6 +59,7 @@ final class ServerSessionManager implements SessionListenerFactory<PCEPSessionLi
     private final TopologySessionListenerFactory listenerFactory;
     private final InstanceIdentifier<Topology> topology;
     private final DataBroker broker;
     private final TopologySessionListenerFactory listenerFactory;
     private final InstanceIdentifier<Topology> topology;
     private final DataBroker broker;
+    private Optional<PCEPTopologyProviderRuntimeRegistration> runtimeRootRegistration = Optional.absent();
 
     public ServerSessionManager(final DataBroker broker, final InstanceIdentifier<Topology> topology,
             final TopologySessionListenerFactory listenerFactory) throws ReadFailedException, TransactionCommitFailedException {
 
     public ServerSessionManager(final DataBroker broker, final InstanceIdentifier<Topology> topology,
             final TopologySessionListenerFactory listenerFactory) throws ReadFailedException, TransactionCommitFailedException {
@@ -165,6 +169,9 @@ final class ServerSessionManager implements SessionListenerFactory<PCEPSessionLi
 
     @Override
     public void close() throws TransactionCommitFailedException {
 
     @Override
     public void close() throws TransactionCommitFailedException {
+        if (this.runtimeRootRegistration.isPresent()) {
+            this.runtimeRootRegistration.get().close();
+        }
         for (final TopologySessionListener sessionListener : this.nodes.values()) {
             sessionListener.close();
         }
         for (final TopologySessionListener sessionListener : this.nodes.values()) {
             sessionListener.close();
         }
@@ -175,4 +182,12 @@ final class ServerSessionManager implements SessionListenerFactory<PCEPSessionLi
         t.delete(LogicalDatastoreType.OPERATIONAL, this.topology);
         t.submit().checkedGet();
     }
         t.delete(LogicalDatastoreType.OPERATIONAL, this.topology);
         t.submit().checkedGet();
     }
+
+    public void registerRuntimeRootRegistartion(final PCEPTopologyProviderRuntimeRegistrator runtimeRootRegistrator) {
+        this.runtimeRootRegistration = Optional.of(runtimeRootRegistrator.register(this));
+    }
+
+    public Optional<PCEPTopologyProviderRuntimeRegistration> getRuntimeRootRegistration() {
+        return this.runtimeRootRegistration;
+    }
 }
 }
diff --git a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/SessionListenerState.java b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/SessionListenerState.java
new file mode 100644 (file)
index 0000000..65dc595
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * 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 com.google.common.base.Preconditions;
+import com.google.common.base.Stopwatch;
+import java.util.concurrent.TimeUnit;
+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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Pcinitiate;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.Pcupd;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.types.rev131005.Message;
+
+final class SessionListenerState {
+    private long lastReceivedRptMsgTimestamp = 0;
+    private long receivedRptMsgCount = 0;
+    private long sentUpdMsgCount = 0;
+    private long sentInitMsgCount = 0;
+    private PeerCapabilities capa;
+    private LocalPref localPref;
+    private PeerPref peerPref;
+    private final Stopwatch sessionUpDuration;
+
+    private long minReplyTime = 0;
+    private long maxReplyTime = 0;
+    private long totalTime = 0;
+    private long reqCount = 0;
+
+    public SessionListenerState() {
+        this.sessionUpDuration = new Stopwatch();
+        this.capa = new PeerCapabilities();
+    }
+
+    public void init(final PCEPSession session) {
+        Preconditions.checkNotNull(session);
+        this.localPref = getLocalPref(session.getLocalPref());
+        this.peerPref = getPeerPref(session.getPeerPref());
+        this.sessionUpDuration.start();
+    }
+
+    public void processRequestStats(final long duration) {
+        if (this.minReplyTime == 0) {
+            this.minReplyTime = duration;
+        } else {
+            if (duration < this.minReplyTime) {
+                this.minReplyTime = duration;
+            }
+        }
+        if (duration > this.maxReplyTime) {
+            this.maxReplyTime = duration;
+        }
+        this.totalTime += duration;
+        this.reqCount++;
+    }
+
+    public StatefulMessages getStatefulMessages() {
+        final StatefulMessages msgs = new StatefulMessages();
+        msgs.setLastReceivedRptMsgTimestamp(TimeUnit.MILLISECONDS.toSeconds(this.lastReceivedRptMsgTimestamp));
+        msgs.setReceivedRptMsgCount(this.receivedRptMsgCount);
+        msgs.setSentInitMsgCount(this.sentInitMsgCount);
+        msgs.setSentUpdMsgCount(this.sentUpdMsgCount);
+        return msgs;
+    }
+
+    public void resetStats(final PCEPSession session) {
+        Preconditions.checkNotNull(session);
+        this.receivedRptMsgCount = 0;
+        this.sentInitMsgCount = 0;
+        this.sentUpdMsgCount = 0;
+        this.lastReceivedRptMsgTimestamp = 0;
+        this.maxReplyTime = 0;
+        this.minReplyTime = 0;
+        this.totalTime = 0;
+        this.reqCount = 0;
+        session.resetStats();
+    }
+
+    public ReplyTime getReplyTime() {
+        final ReplyTime time = new ReplyTime();
+        long avg = 0;
+        if (this.reqCount != 0) {
+            avg = this.totalTime / this.reqCount;
+        }
+        time.setAverageTime(avg);
+        time.setMaxTime(this.maxReplyTime);
+        time.setMinTime(this.minReplyTime);
+        return time;
+    }
+
+    public PeerCapabilities getPeerCapabilities() {
+        return this.capa;
+    }
+
+    public SessionState getSessionState(final PCEPSession session) {
+        Preconditions.checkNotNull(session);
+        final SessionState state = new SessionState();
+        state.setLocalPref(this.localPref);
+        state.setPeerPref(this.peerPref);
+        state.setMessages(getMessageStats(session.getMessages()));
+        state.setSessionDuration(formatElapsedTime(this.sessionUpDuration.elapsed(TimeUnit.SECONDS)));
+        return state;
+    }
+
+    public void setPeerCapabilities(final PeerCapabilities capabilities) {
+        this.capa = Preconditions.checkNotNull(capabilities);
+    }
+
+    public void updateLastReceivedRptMsg() {
+        this.lastReceivedRptMsgTimestamp = System.currentTimeMillis();
+        this.receivedRptMsgCount++;
+    }
+
+    public void updateStatefulSentMsg(final Message msg) {
+        if (msg instanceof Pcinitiate || msg instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.Pcinitiate) {
+            this.sentInitMsgCount++;
+        } else if (msg instanceof Pcupd || msg instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.Pcupd) {
+            this.sentUpdMsgCount++;
+        }
+    }
+
+    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;
+    }
+
+    private static String formatElapsedTime(final long seconds) {
+        return String.format("%2d:%02d:%02d:%02d",
+                TimeUnit.SECONDS.toDays(seconds),
+                TimeUnit.SECONDS.toHours(seconds) - TimeUnit.DAYS.toHours(TimeUnit.SECONDS.toDays(seconds)),
+                TimeUnit.SECONDS.toMinutes(seconds) - TimeUnit.HOURS.toMinutes(TimeUnit.SECONDS.toHours(seconds)),
+                seconds - TimeUnit.MINUTES.toSeconds(TimeUnit.SECONDS.toMinutes(seconds)));
+    }
+}
index ecbd986a7aa8ccc785145900174fdfe1bf333558..fb9542ec1fe3e1787e4ebfb8ca97e345f8826498 100644 (file)
@@ -17,8 +17,10 @@ import com.google.common.util.concurrent.ListenableFuture;
 import java.net.InetAddress;
 import java.nio.ByteBuffer;
 import java.util.Collections;
 import java.net.InetAddress;
 import java.nio.ByteBuffer;
 import java.util.Collections;
+import org.opendaylight.controller.config.yang.pcep.topology.provider.PeerCapabilities;
 import org.opendaylight.protocol.pcep.PCEPSession;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.PcinitiateBuilder;
 import org.opendaylight.protocol.pcep.PCEPSession;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.PcinitiateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.Stateful1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.pcinitiate.message.PcinitiateMessageBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.pcinitiate.message.pcinitiate.message.RequestsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.Arguments1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.pcinitiate.message.PcinitiateMessageBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated._00.rev140113.pcinitiate.message.pcinitiate.message.RequestsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.Arguments1;
@@ -78,6 +80,7 @@ public class Stateful02TopologySessionListener extends AbstractTopologySessionLi
         if (tlv != null) {
             final Stateful stateful = tlv.getStateful();
             if (stateful != null) {
         if (tlv != null) {
             final Stateful stateful = tlv.getStateful();
             if (stateful != null) {
+                getSessionListenerState().setPeerCapabilities(getCapabilities(stateful));
                 pccBuilder.setReportedLsp(Collections.<ReportedLsp> emptyList());
                 pccBuilder.setStateSync(PccSyncState.InitialResync);
                 pccBuilder.setStatefulTlv(new StatefulTlvBuilder().addAugmentation(StatefulTlv1.class, new StatefulTlv1Builder(tlv).build()).build());
                 pccBuilder.setReportedLsp(Collections.<ReportedLsp> emptyList());
                 pccBuilder.setStateSync(PccSyncState.InitialResync);
                 pccBuilder.setStatefulTlv(new StatefulTlvBuilder().addAugmentation(StatefulTlv1.class, new StatefulTlv1Builder(tlv).build()).build());
@@ -95,6 +98,7 @@ public class Stateful02TopologySessionListener extends AbstractTopologySessionLi
             return true;
         }
 
             return true;
         }
 
+        getSessionListenerState().updateLastReceivedRptMsg();
         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcrpt.message.PcrptMessage rpt = ((PcrptMessage) message).getPcrptMessage();
         for (final Reports r : rpt.getReports()) {
             final Lsp lsp = r.getLsp();
         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.stateful._02.rev140110.pcrpt.message.PcrptMessage rpt = ((PcrptMessage) message).getPcrptMessage();
         for (final Reports r : rpt.getReports()) {
             final Lsp lsp = r.getLsp();
@@ -285,4 +289,17 @@ public class Stateful02TopologySessionListener extends AbstractTopologySessionLi
         Preconditions.checkState(reportedLsp != null, "Reported LSP does not contain LSP object.");
         return reportedLsp;
     }
         Preconditions.checkState(reportedLsp != null, "Reported LSP does not contain LSP object.");
         return reportedLsp;
     }
+
+    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;
+    }
 }
 }
index ba15a73366669d18d9daf0a6a0b66e0f4c19660f..64ada921bb1a631323b4b1701af42e07a6729b48 100644 (file)
@@ -20,10 +20,12 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicLong;
+import org.opendaylight.controller.config.yang.pcep.topology.provider.PeerCapabilities;
 import org.opendaylight.protocol.pcep.PCEPSession;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.PcinitiateBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Srp1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Srp1Builder;
 import org.opendaylight.protocol.pcep.PCEPSession;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.PcinitiateBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Srp1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Srp1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.Stateful1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.pcinitiate.message.PcinitiateMessageBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.pcinitiate.message.pcinitiate.message.Requests;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.pcinitiate.message.pcinitiate.message.RequestsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.pcinitiate.message.PcinitiateMessageBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.pcinitiate.message.pcinitiate.message.Requests;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.crabbe.initiated.rev131126.pcinitiate.message.pcinitiate.message.RequestsBuilder;
@@ -92,6 +94,7 @@ final class Stateful07TopologySessionListener extends AbstractTopologySessionLis
         if (tlvs != null && tlvs.getAugmentation(Tlvs1.class) != null) {
             final Stateful stateful = tlvs.getAugmentation(Tlvs1.class).getStateful();
             if (stateful != null) {
         if (tlvs != null && tlvs.getAugmentation(Tlvs1.class) != null) {
             final Stateful stateful = tlvs.getAugmentation(Tlvs1.class).getStateful();
             if (stateful != null) {
+                getSessionListenerState().setPeerCapabilities(getCapabilities(stateful));
                 pccBuilder.setReportedLsp(Collections.<ReportedLsp> emptyList());
                 pccBuilder.setStateSync(PccSyncState.InitialResync);
                 pccBuilder.setStatefulTlv(new StatefulTlvBuilder().addAugmentation(StatefulTlv1.class,
                 pccBuilder.setReportedLsp(Collections.<ReportedLsp> emptyList());
                 pccBuilder.setStateSync(PccSyncState.InitialResync);
                 pccBuilder.setStatefulTlv(new StatefulTlvBuilder().addAugmentation(StatefulTlv1.class,
@@ -134,6 +137,7 @@ final class Stateful07TopologySessionListener extends AbstractTopologySessionLis
         if (!(message instanceof PcrptMessage)) {
             return true;
         }
         if (!(message instanceof PcrptMessage)) {
             return true;
         }
+        getSessionListenerState().updateLastReceivedRptMsg();
         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.PcrptMessage rpt = ((PcrptMessage) message).getPcrptMessage();
         for (final Reports report : rpt.getReports()) {
             final Lsp lsp = report.getLsp();
         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.pcep.ietf.stateful.rev131222.pcrpt.message.PcrptMessage rpt = ((PcrptMessage) message).getPcrptMessage();
         for (final Reports report : rpt.getReports()) {
             final Lsp lsp = report.getLsp();
@@ -388,4 +392,17 @@ final class Stateful07TopologySessionListener extends AbstractTopologySessionLis
         Preconditions.checkState(reportedLsp != null, "Reported LSP does not contain LSP object.");
         return reportedLsp;
     }
         Preconditions.checkState(reportedLsp != null, "Reported LSP does not contain LSP object.");
         return reportedLsp;
     }
+
+    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;
+    }
 }
 }
index 433e975f5c5244f0c285b9615ab800deb18dfd05..e9e35eea1b6eef6fb8dd236d514b31b30c558f26 100644 (file)
 package org.opendaylight.controller.config.yang.pcep.topology.provider;
 
 import com.google.common.base.Charsets;
 package org.opendaylight.controller.config.yang.pcep.topology.provider;
 
 import com.google.common.base.Charsets;
+import com.google.common.base.Optional;
 import com.google.common.net.InetAddresses;
 import com.google.common.net.InetAddresses;
-
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.util.concurrent.ExecutionException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.util.concurrent.ExecutionException;
-
 import org.opendaylight.bgpcep.pcep.topology.provider.PCEPTopologyProvider;
 import org.opendaylight.controller.config.api.JmxAttributeValidationException;
 import org.opendaylight.controller.config.yang.pcep.impl.PCEPDispatcherImplModuleMXBean;
 import org.opendaylight.bgpcep.pcep.topology.provider.PCEPTopologyProvider;
 import org.opendaylight.controller.config.api.JmxAttributeValidationException;
 import org.opendaylight.controller.config.yang.pcep.impl.PCEPDispatcherImplModuleMXBean;
@@ -134,7 +133,8 @@ public final class PCEPTopologyProviderModule extends
 
         try {
             return PCEPTopologyProvider.create(getDispatcherDependency(), address, keys.isEmpty() ? null : keys, getSchedulerDependency(),
 
         try {
             return PCEPTopologyProvider.create(getDispatcherDependency(), address, keys.isEmpty() ? null : keys, getSchedulerDependency(),
-                    getDataProviderDependency(), getRpcRegistryDependency(), topology, getStatefulPluginDependency());
+                    getDataProviderDependency(), getRpcRegistryDependency(), topology, getStatefulPluginDependency(),
+                    Optional.of(getRootRuntimeBeanRegistratorWrapper()));
         } catch (InterruptedException | ExecutionException | TransactionCommitFailedException | ReadFailedException e) {
             LOG.error("Failed to instantiate topology provider at {}", address, e);
             throw new IllegalStateException("Failed to instantiate provider", e);
         } catch (InterruptedException | ExecutionException | TransactionCommitFailedException | ReadFailedException e) {
             LOG.error("Failed to instantiate topology provider at {}", address, e);
             throw new IllegalStateException("Failed to instantiate provider", e);
index 5390d8e3b72fde2282abd5a6534f467ca1fbbd80..f719de4abad90858613bedfa0b7afbbeff5951f2 100644 (file)
@@ -12,6 +12,8 @@ module odl-pcep-topology-provider-cfg {
     import odl-pcep-api-cfg { prefix pcep; revision-date 2013-04-09; }
     import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
     import odl-tcpmd5-cfg { prefix tcpmd5; revision-date 2014-04-27; }
     import odl-pcep-api-cfg { prefix pcep; revision-date 2013-04-09; }
     import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
     import odl-tcpmd5-cfg { prefix tcpmd5; revision-date 2014-04-27; }
+    import rpc-context { prefix rpcx; revision-date 2013-06-17; }
+    import pcep-session-stats { prefix pcep-stats; revision-date 2014-10-06; }
 
     organization "Cisco Systems, Inc.";
 
 
     organization "Cisco Systems, Inc.";
 
@@ -158,5 +160,131 @@ module odl-pcep-topology-provider-cfg {
             }
         }
     }
             }
         }
     }
+
+    identity session-rpc;
+
+    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 "/config:modules/config:module/config:state" {
+        case pcep-topology-provider {
+            when "/config:modules/config:module/config:type = 'pcep-topology-provider'";
+            list listener-state {
+                description "Statistics gained from session listener.";
+                config:inner-state-bean;
+                rpcx:rpc-context-instance "session-rpc";
+
+                key "peer-id";
+
+                leaf peer-id {
+                    type string;
+                }
+
+                container session-state {
+                    leaf session-duration {
+                        description "Elapsed time (in d:H:m:s) from session-up until now.";
+                        type string;
+                    }
+                    uses pcep-stats:pcep-session-state;
+                }
+
+                container peer-capabilities {
+                    description "Remote peer's (PCC) advertised stateful capabilities.";
+                    uses stateful-preferences;
+                }
+
+                leaf delegated-lsps-count {
+                    description "The number of delegated LSPs (tunnels) from PCC.";
+                    type uint16;
+                }
+
+                leaf synchronized {
+                    description "Represents synchronization status.";
+                    type boolean;
+                }
+
+                container stateful-messages {
+                    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;
+                    }
+
+                    leaf received-rpt-msg-count {
+                        description "The number of received PcRpt messages.";
+                        type uint32;
+                    }
+
+                    leaf sent-upd-msg-count {
+                        description "The number of sent PCUpd messages.";
+                        type uint32;
+                    }
+
+                    leaf sent-init-msg-count {
+                        description "The number of sent PCInitiate messages.";
+                        type uint32;
+                    }
+                }
+
+                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;
+                    }
+
+                    leaf min-time {
+                        description "Minimal measured time value (in milliseconds).";
+                        type uint32;
+                    }
+
+                    leaf max-time {
+                        description "Maximal measured time value (in milliseconds).";
+                        type uint32;
+                    }
+                }
+              }
+          }
+    }
+
+    rpc tear-down-session {
+        description "Closes the session between PCE and PCC.";
+        input {
+            uses rpcx:rpc-context-ref {
+                refine context-instance {
+                    rpcx:rpc-context-instance session-rpc;
+                }
+            }
+        }
+    }
+
+    rpc reset-stats {
+        description "Resets statistics like message counters and timestamps. (set to 0)";
+        input {
+            uses rpcx:rpc-context-ref {
+                refine context-instance {
+                    rpcx:rpc-context-instance session-rpc;
+                }
+            }
+        }
+    }
 }
 
 }
 
index 92090701f8ca3ab0f45f792d5fbfc6c6f9309756..956467b48c118447c7a5b0a6269c8df4b4804306 100644 (file)
@@ -73,6 +73,8 @@ public abstract class AbstractPCEPSessionTest<T extends TopologySessionListenerF
     protected static final String ERO_IP_PREFIX = TEST_ADDRESS + IPV4_MASK;
     protected static final String NEW_DESTINATION_ADDRESS = "127.0.1.0";
     protected static final String DST_IP_PREFIX = NEW_DESTINATION_ADDRESS + IPV4_MASK;
     protected static final String ERO_IP_PREFIX = TEST_ADDRESS + IPV4_MASK;
     protected static final String NEW_DESTINATION_ADDRESS = "127.0.1.0";
     protected static final String DST_IP_PREFIX = NEW_DESTINATION_ADDRESS + IPV4_MASK;
+    protected static final short DEAD_TIMER = 30;
+    protected static final short KEEP_ALIVE = 10;
 
     protected List<Notification> receivedMsgs;
 
 
     protected List<Notification> receivedMsgs;
 
@@ -92,7 +94,7 @@ public abstract class AbstractPCEPSessionTest<T extends TopologySessionListenerF
 
     private T listenerFactory;
 
 
     private T listenerFactory;
 
-    private final Open localPrefs = new OpenBuilder().setDeadTimer((short) 30).setKeepalive((short) 10).build();
+    private final Open localPrefs = new OpenBuilder().setDeadTimer((short) 30).setKeepalive((short) 10).setSessionId((short) 0).build();
 
     protected ServerSessionManager manager;
 
 
     protected ServerSessionManager manager;
 
index dbe62927e5f28d6ada3cfae4a8e46d53bf64bdcd..7dd9bb3e3dd3ab153bff579e4a33811817393b25 100644 (file)
@@ -23,9 +23,9 @@ import java.util.Collections;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.Before;
 import org.junit.Test;
+import org.opendaylight.controller.config.yang.pcep.topology.provider.SessionState;
 import org.opendaylight.protocol.pcep.PCEPCloseTermination;
 import org.opendaylight.protocol.pcep.TerminationReason;
 import org.opendaylight.protocol.pcep.pcc.mock.MsgBuilderUtil;
 import org.opendaylight.protocol.pcep.PCEPCloseTermination;
 import org.opendaylight.protocol.pcep.TerminationReason;
 import org.opendaylight.protocol.pcep.pcc.mock.MsgBuilderUtil;
@@ -104,6 +104,18 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
     public void testStateful07TopologySessionListener() throws Exception {
         this.listener.onSessionUp(this.session);
 
     public void testStateful07TopologySessionListener() throws Exception {
         this.listener.onSessionUp(this.session);
 
+        assertEquals(TEST_ADDRESS, this.listener.getPeerId());
+        final SessionState state = this.listener.getSessionState();
+        assertNotNull(state);
+        assertEquals(DEAD_TIMER, state.getLocalPref().getDeadtimer().shortValue());
+        assertEquals(KEEP_ALIVE, state.getLocalPref().getKeepalive().shortValue());
+        assertEquals(0, state.getLocalPref().getSessionId().intValue());
+        assertEquals(TEST_ADDRESS, state.getLocalPref().getIpAddress());
+        assertEquals(DEAD_TIMER, state.getPeerPref().getDeadtimer().shortValue());
+        assertEquals(KEEP_ALIVE, state.getPeerPref().getKeepalive().shortValue());
+        assertEquals(0, state.getPeerPref().getSessionId().intValue());
+        assertEquals(TEST_ADDRESS, state.getPeerPref().getIpAddress());
+
         // add-lsp
         this.topologyRpcs.addLsp(createAddLspInput());
         assertEquals(1, this.receivedMsgs.size());
         // add-lsp
         this.topologyRpcs.addLsp(createAddLspInput());
         assertEquals(1, this.receivedMsgs.size());
@@ -139,6 +151,14 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         Path path = reportedLsp.getPath().get(0);
         assertEquals(1, path.getEro().getSubobject().size());
         assertEquals(ERO_IP_PREFIX, getLastEroIpPrefix(path.getEro()));
         Path path = reportedLsp.getPath().get(0);
         assertEquals(1, path.getEro().getSubobject().size());
         assertEquals(ERO_IP_PREFIX, getLastEroIpPrefix(path.getEro()));
+        // check stats
+        assertEquals(1, this.listener.getDelegatedLspsCount().intValue());
+        assertTrue(this.listener.getSynchronized());
+        assertTrue(this.listener.getStatefulMessages().getLastReceivedRptMsgTimestamp() > 0);
+        assertEquals(2, this.listener.getStatefulMessages().getReceivedRptMsgCount().intValue());
+        assertEquals(1, this.listener.getStatefulMessages().getSentInitMsgCount().intValue());
+        assertEquals(0, this.listener.getStatefulMessages().getSentUpdMsgCount().intValue());
+        assertNotNull(this.listener.getSessionState());
 
         // update-lsp
         org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.update.lsp.args.ArgumentsBuilder updArgsBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.update.lsp.args.ArgumentsBuilder();
 
         // update-lsp
         org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.update.lsp.args.ArgumentsBuilder updArgsBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.update.lsp.args.ArgumentsBuilder();
@@ -165,6 +185,18 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         path = reportedLsp.getPath().get(0);
         assertEquals(2, path.getEro().getSubobject().size());
         assertEquals(DST_IP_PREFIX, getLastEroIpPrefix(path.getEro()));
         path = reportedLsp.getPath().get(0);
         assertEquals(2, path.getEro().getSubobject().size());
         assertEquals(DST_IP_PREFIX, getLastEroIpPrefix(path.getEro()));
+        // check stats
+        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());
+        assertFalse(this.listener.getPeerCapabilities().getInstantiation());
+        assertTrue(this.listener.getPeerCapabilities().getStateful());
 
         // ensure-operational
         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.ensure.lsp.operational.args.ArgumentsBuilder ensureArgs = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.ensure.lsp.operational.args.ArgumentsBuilder();
 
         // ensure-operational
         final org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.ensure.lsp.operational.args.ArgumentsBuilder ensureArgs = new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.topology.pcep.rev131024.ensure.lsp.operational.args.ArgumentsBuilder();
@@ -190,13 +222,28 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         topology = getTopology().get();
         pcc = topology.getNode().get(0).getAugmentation(Node1.class).getPathComputationClient();
         assertEquals(0, pcc.getReportedLsp().size());
         topology = getTopology().get();
         pcc = topology.getNode().get(0).getAugmentation(Node1.class).getPathComputationClient();
         assertEquals(0, pcc.getReportedLsp().size());
+        // check stats
+        assertEquals(0, this.listener.getDelegatedLspsCount().intValue());
+        assertTrue(this.listener.getSynchronized());
+        assertTrue(this.listener.getStatefulMessages().getLastReceivedRptMsgTimestamp() > 0);
+        assertEquals(4, this.listener.getStatefulMessages().getReceivedRptMsgCount().intValue());
+        assertEquals(2, this.listener.getStatefulMessages().getSentInitMsgCount().intValue());
+        assertEquals(1, this.listener.getStatefulMessages().getSentUpdMsgCount().intValue());
+        this.listener.resetStats();
+        assertEquals(0, this.listener.getStatefulMessages().getLastReceivedRptMsgTimestamp().longValue());
+        assertEquals(0, this.listener.getStatefulMessages().getReceivedRptMsgCount().intValue());
+        assertEquals(0, this.listener.getStatefulMessages().getSentInitMsgCount().intValue());
+        assertEquals(0, this.listener.getStatefulMessages().getSentUpdMsgCount().intValue());
+        assertEquals(0, this.listener.getReplyTime().getAverageTime().longValue());
+        assertEquals(0, this.listener.getReplyTime().getMaxTime().longValue());
+        assertEquals(0, this.listener.getReplyTime().getMinTime().longValue());
     }
 
     @Test
     public void testOnUnhandledErrorMessage() {
         final Message errorMsg = AbstractMessageParser.createErrorMsg(PCEPErrors.NON_ZERO_PLSPID, Optional.<Rp>absent());
         this.listener.onSessionUp(this.session);
     }
 
     @Test
     public void testOnUnhandledErrorMessage() {
         final Message errorMsg = AbstractMessageParser.createErrorMsg(PCEPErrors.NON_ZERO_PLSPID, Optional.<Rp>absent());
         this.listener.onSessionUp(this.session);
-        Assert.assertTrue(this.listener.onMessage(Optional.<AbstractTopologySessionListener.MessageContext>absent().orNull(), errorMsg));
+        assertTrue(this.listener.onMessage(Optional.<AbstractTopologySessionListener.MessageContext>absent().orNull(), errorMsg));
     }
 
     @Test
     }
 
     @Test
@@ -207,11 +254,11 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         this.listener.onMessage(this.session, errorMsg);
 
         final AddLspOutput output = futureOutput.get().getResult();
         this.listener.onMessage(this.session, errorMsg);
 
         final AddLspOutput output = futureOutput.get().getResult();
-        Assert.assertEquals(FailureType.Failed ,output.getFailure());
-        Assert.assertEquals(1, output.getError().size());
+        assertEquals(FailureType.Failed ,output.getFailure());
+        assertEquals(1, output.getError().size());
         final ErrorObject err = output.getError().get(0).getErrorObject();
         final ErrorObject err = output.getError().get(0).getErrorObject();
-        Assert.assertEquals(PCEPErrors.NON_ZERO_PLSPID.getErrorType(), err.getType().shortValue());
-        Assert.assertEquals(PCEPErrors.NON_ZERO_PLSPID.getErrorValue(), err.getValue().shortValue());
+        assertEquals(PCEPErrors.NON_ZERO_PLSPID.getErrorType(), err.getType().shortValue());
+        assertEquals(PCEPErrors.NON_ZERO_PLSPID.getErrorValue(), err.getValue().shortValue());
     }
 
     @Test
     }
 
     @Test
@@ -222,7 +269,7 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
         this.listener.onSessionDown(this.session, new IllegalArgumentException());
         final AddLspOutput output = futureOutput.get().getResult();
         // deal with unsent request after session down
         this.listener.onSessionDown(this.session, new IllegalArgumentException());
         final AddLspOutput output = futureOutput.get().getResult();
         // deal with unsent request after session down
-        Assert.assertEquals(FailureType.Unsent, output.getFailure());
+        assertEquals(FailureType.Unsent, output.getFailure());
     }
 
     @Test
     }
 
     @Test
@@ -239,11 +286,11 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe
                 inetAddress, inetAddress, inetAddress);
         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()));
         this.listener.onMessage(this.session, pcRpt);
                 inetAddress, inetAddress, inetAddress);
         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()));
         this.listener.onMessage(this.session, pcRpt);
-        Assert.assertEquals(1, getTopology().get().getNode().size());
+        assertEquals(1, getTopology().get().getNode().size());
 
         // node should be removed after termination
         this.listener.onSessionTerminated(this.session, new PCEPCloseTermination(TerminationReason.Unknown));
 
         // node should be removed after termination
         this.listener.onSessionTerminated(this.session, new PCEPCloseTermination(TerminationReason.Unknown));
-        Assert.assertEquals(0, getTopology().get().getNode().size());
+        assertEquals(0, getTopology().get().getNode().size());
     }
 
     @Test
     }
 
     @Test