From 66b5c49f10c9354119742c6806fc62a5fffea215 Mon Sep 17 00:00:00 2001 From: Milos Fabian Date: Mon, 6 Oct 2014 09:19:01 +0200 Subject: [PATCH] Bug-2081: PCEP statistics -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 --- .../protocol/pcep/PCEPSession.java | 7 +- .../api/src/main/yang/pcep-session-stats.yang | 124 ++++++++++++ .../protocol/pcep/impl/PCEPSessionImpl.java | 100 +++++----- .../pcep/impl/PCEPSessionRuntimeMXBean.java | 28 --- .../protocol/pcep/impl/PCEPSessionState.java | 134 +++++++++++++ .../pcep/impl/AbstractPCEPSessionTest.java | 10 +- .../pcep/impl/PCEPDispatcherImplTest.java | 4 +- .../pcep/impl/PCEPSessionImplTest.java | 60 +++++- .../AbstractTopologySessionListener.java | 71 ++++++- .../pcep/topology/provider/PCEPRequest.java | 9 +- .../provider/PCEPTopologyProvider.java | 8 +- .../provider/ServerSessionManager.java | 17 +- .../provider/SessionListenerState.java | 182 ++++++++++++++++++ .../Stateful02TopologySessionListener.java | 17 ++ .../Stateful07TopologySessionListener.java | 17 ++ .../provider/PCEPTopologyProviderModule.java | 6 +- .../yang/odl-pcep-topology-provider-cfg.yang | 128 ++++++++++++ .../provider/AbstractPCEPSessionTest.java | 4 +- ...Stateful07TopologySessionListenerTest.java | 65 ++++++- 19 files changed, 878 insertions(+), 113 deletions(-) create mode 100644 pcep/api/src/main/yang/pcep-session-stats.yang delete mode 100644 pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPSessionRuntimeMXBean.java create mode 100644 pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPSessionState.java create mode 100644 pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/SessionListenerState.java diff --git a/pcep/api/src/main/java/org/opendaylight/protocol/pcep/PCEPSession.java b/pcep/api/src/main/java/org/opendaylight/protocol/pcep/PCEPSession.java index bb15c92b02..1d5efe2548 100644 --- a/pcep/api/src/main/java/org/opendaylight/protocol/pcep/PCEPSession.java +++ b/pcep/api/src/main/java/org/opendaylight/protocol/pcep/PCEPSession.java @@ -8,10 +8,9 @@ package org.opendaylight.protocol.pcep; import io.netty.util.concurrent.Future; - import java.net.InetAddress; - 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; @@ -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. */ -public interface PCEPSession extends ProtocolSession { +public interface PCEPSession extends ProtocolSession, PcepSessionState { /** * 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 { 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 index 0000000000..035ebb3a3f --- /dev/null +++ b/pcep/api/src/main/yang/pcep-session-stats.yang @@ -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 "; + + 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 diff --git a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPSessionImpl.java b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPSessionImpl.java index 5739ad1767..a4aed7154d 100644 --- a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPSessionImpl.java +++ b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPSessionImpl.java @@ -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.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; @@ -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.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.yangtools.yang.binding.DataContainer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -47,7 +52,7 @@ import org.slf4j.LoggerFactory; * Implementation of PCEPSession. (Not final for testing.) */ @VisibleForTesting -public class PCEPSessionImpl extends AbstractProtocolSession implements PCEPSession, PCEPSessionRuntimeMXBean { +public class PCEPSessionImpl extends AbstractProtocolSession implements PCEPSession { /** * 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 implements 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 @@ -88,6 +89,8 @@ public class PCEPSessionImpl extends AbstractProtocolSession implements 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); @@ -121,6 +124,15 @@ public class PCEPSessionImpl extends AbstractProtocolSession implements 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 implements public Future 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); } - this.sentMsgCount++; + if (msg instanceof PcerrMessage) { + this.sessionState.setLastSentError(msg); + } f.addListener(new ChannelFutureListener() { @Override @@ -223,7 +238,7 @@ public class PCEPSessionImpl extends AbstractProtocolSession implements 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 @@ -300,7 +315,7 @@ public class PCEPSessionImpl extends AbstractProtocolSession implements 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); } @@ -318,74 +333,57 @@ public class PCEPSessionImpl extends AbstractProtocolSession implements 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); } } - /** - * @return the sentMsgCount - */ - @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 - 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 getUnknownMessagesTimes() { + return this.unknownMessagesTimes; } @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 - public void tearDown() { - this.close(); + public LocalPref getLocalPref() { + return this.sessionState.getLocalPref(); } @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 - @VisibleForTesting - public void sessionUp() { - this.listener.onSessionUp(this); + public Class getImplementedInterface() { + throw new UnsupportedOperationException(); } - @Override - public String getNodeIdentifier() { - return ""; - } - - @VisibleForTesting - protected final Queue 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 index 6d951cf7c1..0000000000 --- a/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPSessionRuntimeMXBean.java +++ /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 index 0000000000..be4e34baef --- /dev/null +++ b/pcep/impl/src/main/java/org/opendaylight/protocol/pcep/impl/PCEPSessionState.java @@ -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(); + } +} diff --git a/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/AbstractPCEPSessionTest.java b/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/AbstractPCEPSessionTest.java index 4eb9f9d2d1..bb491f5900 100644 --- a/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/AbstractPCEPSessionTest.java +++ b/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/AbstractPCEPSessionTest.java @@ -40,6 +40,10 @@ import org.opendaylight.yangtools.yang.binding.Notification; 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; @@ -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(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( - (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(); diff --git a/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPDispatcherImplTest.java b/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPDispatcherImplTest.java index fc52bcdee9..f513a2a298 100644 --- a/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPDispatcherImplTest.java +++ b/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPDispatcherImplTest.java @@ -91,11 +91,11 @@ public class PCEPDispatcherImplTest { }).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(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()); diff --git a/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPSessionImplTest.java b/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPSessionImplTest.java index 4b653345f9..46f632237d 100644 --- a/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPSessionImplTest.java +++ b/pcep/impl/src/test/java/org/opendaylight/protocol/pcep/impl/PCEPSessionImplTest.java @@ -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.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; @@ -34,34 +38,36 @@ public class PCEPSessionImplTest extends AbstractPCEPSessionTest { @After public void tearDown() { - this.session.tearDown(); + this.session.close(); } @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); - Assert.assertEquals(1, this.session.getReceivedMsgCount().intValue()); + Assert.assertEquals(1, this.session.getMessages().getReceivedMsgCount().intValue()); 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(2, this.session.getMessages().getReceivedMsgCount().intValue()); 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(); + + this.session.resetStats(); + Assert.assertEquals(0, this.session.getMessages().getReceivedMsgCount().longValue()); } @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); @@ -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())); - 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); @@ -93,7 +99,7 @@ public class PCEPSessionImplTest extends AbstractPCEPSessionTest { } @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); @@ -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(); } + + @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()); + } } diff --git a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractTopologySessionListener.java b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractTopologySessionListener.java index 2424fec485..1531ddc0d1 100644 --- a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractTopologySessionListener.java +++ b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractTopologySessionListener.java @@ -21,6 +21,12 @@ import java.util.List; 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; @@ -59,7 +65,7 @@ import org.slf4j.LoggerFactory; * @param identifier type of requests * @param identifier type for LSPs */ -public abstract class AbstractTopologySessionListener implements PCEPSessionListener, TopologySessionListener { +public abstract class AbstractTopologySessionListener implements PCEPSessionListener, TopologySessionListener, ListenerStateRuntimeMXBean { protected static final class MessageContext { private final Collection requests = new ArrayList<>(); private final WriteTransaction trans; @@ -92,6 +98,7 @@ public abstract class AbstractTopologySessionListener implements PCEPSessi return this.version; } }; + 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 implements PCEPSessi private boolean synced = false; private PCEPSession session; + private ListenerStateRuntimeRegistration registration; + private final SessionListenerState listenerState; + protected AbstractTopologySessionListener(final ServerSessionManager serverSessionManager) { this.serverSessionManager = Preconditions.checkNotNull(serverSessionManager); + this.listenerState = new SessionListenerState(); } @Override @@ -160,6 +171,10 @@ public abstract class AbstractTopologySessionListener implements PCEPSessi 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()); } @@ -230,6 +245,9 @@ public abstract class AbstractTopologySessionListener implements PCEPSessi @Override public void close() { + if (this.registration != null) { + this.registration.close(); + } if (this.session != null) { this.session.close(TerminationReason.Unknown); } @@ -237,6 +255,7 @@ public abstract class AbstractTopologySessionListener implements PCEPSessi 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; } @@ -244,6 +263,7 @@ public abstract class AbstractTopologySessionListener implements PCEPSessi protected final synchronized ListenableFuture sendMessage(final Message message, final S requestId, final Metadata metadata) { final io.netty.util.concurrent.Future f = this.session.sendMessage(message); + this.listenerState.updateStatefulSentMsg(message); final PCEPRequest req = new PCEPRequest(metadata); this.requests.put(requestId, req); @@ -418,4 +438,53 @@ public abstract class AbstractTopologySessionListener implements PCEPSessi } protected abstract Object validateReportedLsp(final Optional 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(); + } } diff --git a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPRequest.java b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPRequest.java index 95a3e082fa..5feea82674 100644 --- a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPRequest.java +++ b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPRequest.java @@ -7,9 +7,10 @@ */ 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 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; @@ -26,11 +27,13 @@ final class PCEPRequest { private final SettableFuture 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; + this.stopwatch = new Stopwatch().start(); } protected ListenableFuture getFuture() { @@ -59,4 +62,8 @@ final class PCEPRequest { state = State.UNACKED; } } + + public long getElapsedMillis() { + return this.stopwatch.elapsed(TimeUnit.MILLISECONDS); + } } \ No newline at end of file diff --git a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPTopologyProvider.java b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPTopologyProvider.java index 0b2699e443..e85737a86c 100644 --- a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPTopologyProvider.java +++ b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/PCEPTopologyProvider.java @@ -7,6 +7,7 @@ */ 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; @@ -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 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; @@ -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, - final InstanceIdentifier topology, final TopologySessionListenerFactory listenerFactory) throws InterruptedException, + final InstanceIdentifier topology, final TopologySessionListenerFactory listenerFactory, + Optional runtimeRootRegistrator) throws InterruptedException, 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(); diff --git a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/ServerSessionManager.java b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/ServerSessionManager.java index afc7172f89..f3afdfae83 100644 --- a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/ServerSessionManager.java +++ b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/ServerSessionManager.java @@ -15,6 +15,9 @@ import java.util.ArrayList; 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; @@ -47,7 +50,7 @@ import org.slf4j.LoggerFactory; /** * */ -final class ServerSessionManager implements SessionListenerFactory, AutoCloseable, TopologySessionRPCs { +final class ServerSessionManager implements SessionListenerFactory, AutoCloseable, TopologySessionRPCs, PCEPTopologyProviderRuntimeMXBean { 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 topology; private final DataBroker broker; + private Optional runtimeRootRegistration = Optional.absent(); public ServerSessionManager(final DataBroker broker, final InstanceIdentifier topology, final TopologySessionListenerFactory listenerFactory) throws ReadFailedException, TransactionCommitFailedException { @@ -165,6 +169,9 @@ final class ServerSessionManager implements SessionListenerFactory 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 index 0000000000..65dc595f63 --- /dev/null +++ b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/SessionListenerState.java @@ -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))); + } +} diff --git a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful02TopologySessionListener.java b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful02TopologySessionListener.java index ecbd986a7a..fb9542ec1f 100644 --- a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful02TopologySessionListener.java +++ b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful02TopologySessionListener.java @@ -17,8 +17,10 @@ import com.google.common.util.concurrent.ListenableFuture; 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.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; @@ -78,6 +80,7 @@ public class Stateful02TopologySessionListener extends AbstractTopologySessionLi if (tlv != null) { final Stateful stateful = tlv.getStateful(); if (stateful != null) { + getSessionListenerState().setPeerCapabilities(getCapabilities(stateful)); pccBuilder.setReportedLsp(Collections. 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; } + 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(); @@ -285,4 +289,17 @@ public class Stateful02TopologySessionListener extends AbstractTopologySessionLi 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; + } } diff --git a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful07TopologySessionListener.java b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful07TopologySessionListener.java index ba15a73366..64ada921bb 100644 --- a/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful07TopologySessionListener.java +++ b/pcep/topology-provider/src/main/java/org/opendaylight/bgpcep/pcep/topology/provider/Stateful07TopologySessionListener.java @@ -20,10 +20,12 @@ import java.util.ArrayList; 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.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; @@ -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) { + getSessionListenerState().setPeerCapabilities(getCapabilities(stateful)); pccBuilder.setReportedLsp(Collections. 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; } + 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(); @@ -388,4 +392,17 @@ final class Stateful07TopologySessionListener extends AbstractTopologySessionLis 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; + } } diff --git a/pcep/topology-provider/src/main/java/org/opendaylight/controller/config/yang/pcep/topology/provider/PCEPTopologyProviderModule.java b/pcep/topology-provider/src/main/java/org/opendaylight/controller/config/yang/pcep/topology/provider/PCEPTopologyProviderModule.java index 433e975f5c..e9e35eea1b 100644 --- a/pcep/topology-provider/src/main/java/org/opendaylight/controller/config/yang/pcep/topology/provider/PCEPTopologyProviderModule.java +++ b/pcep/topology-provider/src/main/java/org/opendaylight/controller/config/yang/pcep/topology/provider/PCEPTopologyProviderModule.java @@ -17,12 +17,11 @@ 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 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; @@ -134,7 +133,8 @@ public final class PCEPTopologyProviderModule extends 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); diff --git a/pcep/topology-provider/src/main/yang/odl-pcep-topology-provider-cfg.yang b/pcep/topology-provider/src/main/yang/odl-pcep-topology-provider-cfg.yang index 5390d8e3b7..f719de4aba 100644 --- a/pcep/topology-provider/src/main/yang/odl-pcep-topology-provider-cfg.yang +++ b/pcep/topology-provider/src/main/yang/odl-pcep-topology-provider-cfg.yang @@ -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 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."; @@ -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; + } + } + } + } } diff --git a/pcep/topology-provider/src/test/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractPCEPSessionTest.java b/pcep/topology-provider/src/test/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractPCEPSessionTest.java index 92090701f8..956467b48c 100644 --- a/pcep/topology-provider/src/test/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractPCEPSessionTest.java +++ b/pcep/topology-provider/src/test/java/org/opendaylight/bgpcep/pcep/topology/provider/AbstractPCEPSessionTest.java @@ -73,6 +73,8 @@ public abstract class AbstractPCEPSessionTest receivedMsgs; @@ -92,7 +94,7 @@ public abstract class AbstractPCEPSessionTest 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(); @@ -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())); + // 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(); @@ -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()); + // 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.absent()); this.listener.onSessionUp(this.session); - Assert.assertTrue(this.listener.onMessage(Optional.absent().orNull(), errorMsg)); + assertTrue(this.listener.onMessage(Optional.absent().orNull(), errorMsg)); } @Test @@ -207,11 +254,11 @@ public class Stateful07TopologySessionListenerTest extends AbstractPCEPSessionTe 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(); - 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 @@ -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 - Assert.assertEquals(FailureType.Unsent, output.getFailure()); + assertEquals(FailureType.Unsent, output.getFailure()); } @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); - 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)); - Assert.assertEquals(0, getTopology().get().getNode().size()); + assertEquals(0, getTopology().get().getNode().size()); } @Test -- 2.36.6