<artifactId>bgp-inet</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>bgp-cli</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bgp-parser-api</artifactId>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2016 Inocybe Technologies. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <scm>
+ <connection>scm:git:ssh://git.opendaylight.org:29418/bgpcep.git</connection>
+ <developerConnection>scm:git:ssh://git.opendaylight.org:29418/bgpcep.git</developerConnection>
+ <url>https://wiki.opendaylight.org/view/BGP_LS_PCEP:Main</url>
+ <tag>HEAD</tag>
+ </scm>
+ <parent>
+ <groupId>org.opendaylight.bgpcep</groupId>
+ <artifactId>bgp-parent</artifactId>
+ <version>0.6.0-SNAPSHOT</version>
+ </parent>
+
+ <artifactId>bgp-cli</artifactId>
+ <description>BGP CLI</description>
+ <packaging>bundle</packaging>
+ <name>${project.artifactId}</name>
+ <prerequisites>
+ <maven>3.0.4</maven>
+ </prerequisites>
+
+ <dependencies>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>bgp-parser-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>bgp-rib-impl</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>bgp-concepts</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>concepts</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>yang-binding</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-common</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>concepts</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.mdsal.model</groupId>
+ <artifactId>ietf-inet-types</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.google.guava</groupId>
+ <artifactId>guava</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.console</artifactId>
+ <version>${karaf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.table</artifactId>
+ <version>${karaf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.commands</artifactId>
+ <version>${karaf.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.karaf.shell</groupId>
+ <artifactId>org.apache.karaf.shell.table</artifactId>
+ <version>${karaf.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Name>${project.groupId}.${project.artifactId}</Bundle-Name>
+ </instructions>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
+ <!--
+ Maven Site Configuration
+
+ The following configuration is necessary for maven-site-plugin to
+ correctly identify the correct deployment path for OpenDaylight Maven
+ sites.
+ -->
+ <url>${odl.site.url}/${project.groupId}/${stream}/${project.artifactId}/</url>
+
+ <distributionManagement>
+ <site>
+ <id>opendaylight-site</id>
+ <url>${nexus.site.url}/${project.artifactId}/</url>
+ </site>
+ </distributionManagement>
+</project>
--- /dev/null
+/*
+ * Copyright © 2016 Inocybe Technologies 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.bgp.cli;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.lang.management.ManagementFactory;
+import java.util.Set;
+import javax.annotation.Nonnull;
+import javax.management.JMX;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.config.yang.bgp.rib.impl.BGPPeerModuleFactory;
+import org.opendaylight.controller.config.yang.bgp.rib.impl.BGPPeerRuntimeMXBean;
+
+public abstract class AbstractStatsCommandProvider extends OsgiCommandSupport {
+ private static final ObjectName BGP_PEER_MODULE_PATTERN = ObjectNameUtil.createRuntimeBeanPattern(BGPPeerModuleFactory.NAME, null);
+
+ private static final MBeanServer MBEAN_SERVER = ManagementFactory.getPlatformMBeanServer();
+
+ @Override
+ protected final Object doExecute() throws Exception {
+ final PrintStream out = this.session.getConsole();
+ getObjectNames().forEach(objectName -> {
+ onExecution(out, getRuntimeMXBean(objectName), objectName);
+ });
+ return null;
+ }
+
+ protected abstract void onExecution(@Nonnull PrintStream out, @Nonnull BGPPeerRuntimeMXBean peerRuntimeMXBean, @Nonnull ObjectName objectName);
+
+ private static Set<ObjectName> getObjectNames() throws IOException {
+ return MBEAN_SERVER.queryNames(BGP_PEER_MODULE_PATTERN, null);
+ }
+
+ private static final BGPPeerRuntimeMXBean getRuntimeMXBean(final ObjectName objectName) {
+ return JMX.newMXBeanProxy(MBEAN_SERVER, objectName, BGPPeerRuntimeMXBean.class);
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2016 Inocybe Technologies 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.bgp.cli;
+
+import java.io.PrintStream;
+import javax.annotation.Nonnull;
+import javax.management.ObjectName;
+import org.apache.karaf.shell.commands.Command;
+import org.opendaylight.controller.config.yang.bgp.rib.impl.BGPPeerRuntimeMXBean;
+
+@Command(scope = "bgp", name = "reset-stats", description = "Reset BGP stats.")
+public class ResetBGPStatsCommandProvider extends AbstractStatsCommandProvider {
+
+ @Override
+ protected void onExecution(@Nonnull PrintStream out, @Nonnull BGPPeerRuntimeMXBean peerRuntimeMXBean,
+ @Nonnull ObjectName objectName) {
+ peerRuntimeMXBean.resetSession();
+ out.println(String.format("BGP Statistics reset for [%s]!", objectName));
+ }
+}
+
--- /dev/null
+/*
+ * Copyright © 2016 Inocybe Technologies 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.bgp.cli;
+
+import java.io.PrintStream;
+import javax.annotation.Nonnull;
+import javax.management.ObjectName;
+import org.apache.felix.gogo.commands.Command;
+import org.opendaylight.controller.config.yang.bgp.rib.impl.BGPPeerRuntimeMXBean;
+import org.opendaylight.controller.config.yang.bgp.rib.impl.BgpSessionState;
+import org.opendaylight.protocol.bgp.cli.utils.BgpCliUtils;
+
+@Command(scope = "bgp", name = "show-stats", description = "Shows BGP stats.")
+public class ShowBGPStatsCommandProvider extends AbstractStatsCommandProvider {
+
+ @Override
+ protected void onExecution(@Nonnull PrintStream out, @Nonnull BGPPeerRuntimeMXBean peerRuntimeMXBean,
+ @Nonnull ObjectName objectName) {
+ final BgpSessionState state = peerRuntimeMXBean.getBgpSessionState();
+ BgpCliUtils.displayAll(objectName, state, out);
+ }
+}
--- /dev/null
+/*
+ * Copyright © 2016 Inocybe Technologies 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.bgp.cli.utils;
+
+import java.io.PrintStream;
+import javax.management.ObjectName;
+import org.apache.karaf.shell.table.ShellTable;
+import org.opendaylight.controller.config.yang.bgp.rib.impl.BgpSessionState;
+import org.opendaylight.controller.config.yang.bgp.rib.impl.LocalPeerPreferences;
+import org.opendaylight.controller.config.yang.bgp.rib.impl.MessagesStats;
+import org.opendaylight.controller.config.yang.bgp.rib.impl.RemotePeerPreferences;
+
+public final class BgpCliUtils{
+ private static final String MESSAGE_STATS_LABEL = "MessagesStats.";
+ private static final String PEER_PREFERENCES_LABEL = "PeerPreferences.";
+ private static final String SPEAKER_PREFERENCES_LABEL = "SpeakerPreferences.";
+
+ public static void displayAll(final ObjectName objectName, final BgpSessionState bgpSessionState, final PrintStream printStream) {
+ if (bgpSessionState == null) {
+ printStream.println(String.format("No BgpSessionState found for [%s]", objectName));
+ return;
+ }
+ final ShellTable table = new ShellTable();
+ table.column("Attribute").alignLeft();
+ table.column("Value").alignLeft();
+ table.addRow().addContent("Object Name", objectName.getCanonicalName());
+ table.addRow().addContent("HoldtimeCurrent", bgpSessionState.getHoldtimeCurrent());
+ table.addRow().addContent("KeepaliveCurrent", bgpSessionState.getKeepaliveCurrent());
+ table.addRow().addContent("SessionDuration", bgpSessionState.getSessionDuration());
+ table.addRow().addContent("SessionState", bgpSessionState.getSessionState());
+
+ //Messages Stats
+ final MessagesStats messageStats = bgpSessionState.getMessagesStats();
+ table.addRow().addContent(MESSAGE_STATS_LABEL + "ErrorMsgsSent", messageStats.getErrorMsgs().getErrorSent().size());
+ table.addRow().addContent(MESSAGE_STATS_LABEL + "ErrorMsgsReceived", messageStats.getErrorMsgs().getErrorReceived().size());
+ table.addRow().addContent(MESSAGE_STATS_LABEL + "KeepAliveMsgsSent", messageStats.getKeepAliveMsgs().getSent().getCount());
+ table.addRow().addContent(MESSAGE_STATS_LABEL + "KeepAliveMsgsReceived", messageStats.getKeepAliveMsgs().getReceived().getCount());
+ table.addRow().addContent(MESSAGE_STATS_LABEL + "TotalMsgsSent", messageStats.getTotalMsgs().getSent().getCount());
+ table.addRow().addContent(MESSAGE_STATS_LABEL + "TotalMsgsReceived", messageStats.getTotalMsgs().getReceived().getCount());
+ table.addRow().addContent(MESSAGE_STATS_LABEL + "UpdateMsgsSent", messageStats.getUpdateMsgs().getSent().getCount());
+ table.addRow().addContent(MESSAGE_STATS_LABEL + "UpdateMsgsReceived", messageStats.getUpdateMsgs().getReceived().getCount());
+
+ //Peer Preferences
+ final LocalPeerPreferences peerPreferences = bgpSessionState.getLocalPeerPreferences();
+ table.addRow().addContent(PEER_PREFERENCES_LABEL + "AddPathCapability", peerPreferences.getAddPathCapability());
+ table.addRow().addContent(PEER_PREFERENCES_LABEL + "AS", peerPreferences.getAs());
+ table.addRow().addContent(PEER_PREFERENCES_LABEL + "BgpExtendedMessageCapability", peerPreferences.getBgpExtendedMessageCapability());
+ table.addRow().addContent(PEER_PREFERENCES_LABEL + "BgpId", peerPreferences.getBgpId());
+ table.addRow().addContent(PEER_PREFERENCES_LABEL + "FourOctetAsCapability", peerPreferences.getFourOctetAsCapability());
+ table.addRow().addContent(PEER_PREFERENCES_LABEL + "GrCapability", peerPreferences.getGrCapability());
+ table.addRow().addContent(PEER_PREFERENCES_LABEL + "Port", peerPreferences.getPort());
+ table.addRow().addContent(PEER_PREFERENCES_LABEL + "RouteRefreshCapability", peerPreferences.getRouteRefreshCapability());
+
+ //Speaker Preferences
+ final RemotePeerPreferences speakerPreferences = bgpSessionState.getRemotePeerPreferences();
+ table.addRow().addContent(SPEAKER_PREFERENCES_LABEL + "AddPathCapability", speakerPreferences.getAddPathCapability());
+ table.addRow().addContent(SPEAKER_PREFERENCES_LABEL + "AS", speakerPreferences.getAs());
+ table.addRow().addContent(SPEAKER_PREFERENCES_LABEL + "BgpExtendedMessageCapability", speakerPreferences.getBgpExtendedMessageCapability());
+ table.addRow().addContent(SPEAKER_PREFERENCES_LABEL + "BgpId", speakerPreferences.getBgpId());
+ table.addRow().addContent(SPEAKER_PREFERENCES_LABEL + "FourOctetAsCapability", speakerPreferences.getFourOctetAsCapability());
+ table.addRow().addContent(SPEAKER_PREFERENCES_LABEL + "GrCapability", speakerPreferences.getGrCapability());
+ table.addRow().addContent(SPEAKER_PREFERENCES_LABEL + "Port", speakerPreferences.getPort());
+ table.addRow().addContent(SPEAKER_PREFERENCES_LABEL + "RouteRefreshCapability", speakerPreferences.getRouteRefreshCapability());
+
+ table.print(printStream);
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+ * Copyright © 2016 Inocybe Technologies 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
+ */
+ -->
+
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+ <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.0.0">
+ <command name="bgp/show-stats">
+ <action class="org.opendaylight.protocol.bgp.cli.ShowBGPStatsCommandProvider"/>
+ </command>
+ <command name="bgp/reset-stats">
+ <action class="org.opendaylight.protocol.bgp.cli.ResetBGPStatsCommandProvider"/>
+ </command>
+ </command-bundle>
+</blueprint>
--- /dev/null
+/*
+ * Copyright © 2016 Inocybe Technologies 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.bgp.cli.utils;
+
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+import javax.management.JMException;
+import javax.management.ObjectName;
+import org.junit.Test;
+import org.opendaylight.controller.config.yang.bgp.rib.impl.BgpSessionState;
+import org.opendaylight.controller.config.yang.bgp.rib.impl.ErrorMsgs;
+import org.opendaylight.controller.config.yang.bgp.rib.impl.ErrorReceived;
+import org.opendaylight.controller.config.yang.bgp.rib.impl.LocalPeerPreferences;
+import org.opendaylight.controller.config.yang.bgp.rib.impl.MessagesStats;
+import org.opendaylight.controller.config.yang.bgp.rib.impl.RemotePeerPreferences;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.ZeroBasedCounter32;
+
+public final class BgpCliUtilsTests{
+
+ @Test
+ public void testDisplayAll() throws IOException, JMException {
+ //Arrange
+ ObjectName objectName = mock(ObjectName.class);
+ BgpSessionState bgpSessionState = mock(BgpSessionState.class);
+ PrintStream printStream = mock(PrintStream.class);
+ MessagesStats msgStats = mock(MessagesStats.class);
+ RemotePeerPreferences speakerPref = mock(RemotePeerPreferences.class);
+ LocalPeerPreferences peerPref = mock(LocalPeerPreferences.class);
+ ErrorMsgs errorMsgs = mock(ErrorMsgs.class);
+ ErrorReceived errorReceived = mock(ErrorReceived.class);
+ List<ErrorReceived> newlist = new ArrayList<>();
+ newlist.add(errorReceived);
+
+ when(bgpSessionState.getMessagesStats()).thenReturn(msgStats);
+ when(speakerPref.getAddPathCapability()).thenReturn(true);
+ when(peerPref.getAddPathCapability()).thenReturn(true);
+ when(errorReceived.getCount()).thenReturn(new ZeroBasedCounter32(5l));
+
+ when(errorMsgs.getErrorReceived()).thenReturn(newlist);
+ when(msgStats.getErrorMsgs()).thenReturn(errorMsgs);
+ when(bgpSessionState.getRemotePeerPreferences()).thenReturn(speakerPref);
+ when(bgpSessionState.getLocalPeerPreferences()).thenReturn(peerPref);
+
+ //Act
+ BgpCliUtils.displayAll(objectName, bgpSessionState, printStream);
+
+ //Assert
+ verify(objectName, atLeastOnce()).getCanonicalName();
+ verify(bgpSessionState, atLeastOnce()).getMessagesStats().getErrorMsgs();
+ verify(bgpSessionState, atLeastOnce()).getMessagesStats().getKeepAliveMsgs();
+ verify(bgpSessionState, atLeastOnce()).getMessagesStats().getRouteRefreshMsgs();
+ verify(bgpSessionState, atLeastOnce()).getMessagesStats().getTotalMsgs();
+ verify(bgpSessionState, atLeastOnce()).getMessagesStats().getUpdateMsgs();
+ verify(bgpSessionState, atLeastOnce()).getLocalPeerPreferences();
+ verify(bgpSessionState, atLeastOnce()).getRemotePeerPreferences();
+ }
+}
<module>path-selection-mode</module>
<module>benchmark-app</module>
<module>evpn</module>
+ <module>cli</module>
</modules>
<!--
<groupId>${project.groupId}</groupId>
<artifactId>bgp-inet</artifactId>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>bgp-cli</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>bgp-parser-api</artifactId>
<feature version='${project.version}'>odl-bgpcep-bgp-path-selection-mode</feature>
<feature version='${project.version}'>odl-bgpcep-bgp-topology</feature>
<feature version='${project.version}'>odl-bgpcep-bgp-openconfig</feature>
+ <feature version='${project.version}'>odl-bgpcep-bgp-cli</feature>
<configfile finalname="etc/opendaylight/karaf/31-bgp.xml">mvn:org.opendaylight.bgpcep/bgp-controller-config/{{VERSION}}/xml/config</configfile>
<configfile finalname="etc/opendaylight/karaf/40-bgp-openconfig.xml">mvn:org.opendaylight.bgpcep/bgp-controller-config/{{VERSION}}/xml/openconfig-config</configfile>
<configfile finalname="etc/opendaylight/karaf/41-bgp-example.xml">mvn:org.opendaylight.bgpcep/bgp-controller-config/{{VERSION}}/xml/config-example</configfile>
<bundle>mvn:org.opendaylight.bgpcep/bgp-benchmark-app/{{VERSION}}</bundle>
<configfile finalname="etc/opendaylight/karaf/bgp-app-peer-benchmark.xml">mvn:org.opendaylight.bgpcep/bgp-benchmark-app/{{VERSION}}/xml/app-peer-benchmark-config</configfile>
</feature>
+ <feature name='odl-bgpcep-bgp-cli' version='${project.version}'>
+ <feature version='${project.version}'>odl-bgpcep-bgp-rib-impl</feature>
+ <bundle>mvn:org.opendaylight.bgpcep/bgp-cli/{{VERSION}}</bundle>
+ </feature>
</features>