Command implementations updated to recent karaf api.
Command artifacts renamed for consistency.
JIRA: OPNFLWPLUG-1113
Signed-off-by: Ruslan Kashapov <ruslan.kashapov@pantheon.tech>
Change-Id: I741542d706975e27b3850238367fc74ccbd0dfba
</dependency>
<dependency>
<groupId>org.apache.karaf.shell</groupId>
- <artifactId>org.apache.karaf.shell.console</artifactId>
+ <artifactId>org.apache.karaf.shell.core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
</dependency>
</dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.karaf.tooling</groupId>
+ <artifactId>karaf-services-maven-plugin</artifactId>
+ </plugin>
+ </plugins>
+ </build>
+
</project>
import org.slf4j.LoggerFactory;
@Singleton
-@Component(service = DpnTracker.class)
+@Component(service = DpnTracker.class, immediate = true)
public final class DefaultDpnTracker implements DpnTracker, DataTreeChangeListener<FlowCapableNode>, AutoCloseable {
private static final Logger LOG = LoggerFactory.getLogger(DefaultDpnTracker.class);
public static final String DEFAULT_DPN_NAME = "UNKNOWN";
*/
package org.opendaylight.openflowplugin.applications.southboundcli.cli;
-import static java.util.Objects.requireNonNull;
+import static org.opendaylight.openflowplugin.applications.southboundcli.util.ShellUtil.LINE_SEPARATOR;
import java.util.Formatter;
-import org.apache.felix.gogo.commands.Command;
-import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.Session;
import org.opendaylight.openflowplugin.applications.southboundcli.DpnTracker;
import org.opendaylight.openflowplugin.applications.southboundcli.util.OFNode;
+@Service
@Command(scope = "openflow", name = "getallnodes", description = "Print all nodes from the operational datastore")
-public class GetAllNodesCommandProvider extends OsgiCommandSupport {
- private final DpnTracker dpnTracker;
+public final class GetAllNodesCommand implements Action {
+ @Reference
+ Session session;
+ @Reference
+ DpnTracker dpnTracker;
- public GetAllNodesCommandProvider(final DpnTracker dpnTracker) {
- this.dpnTracker = requireNonNull(dpnTracker);
- }
-
- @SuppressWarnings("checkstyle:RegexpSinglelineJava")
@Override
- protected Object doExecute() throws Exception {
+ public Object execute() throws Exception {
+ if (dpnTracker == null) {
+ // not initialized
+ return null;
+ }
+
final var ofNodeList = dpnTracker.currentNodes();
if (ofNodeList.isEmpty()) {
- System.out.println("No node is connected yet");
+ session.getConsole().println("No node is connected yet");
return null;
}
final var stringBuilder = new StringBuilder();
try (var formatter = new Formatter(stringBuilder)) {
- System.out.println("Number of nodes: " + ofNodeList.size());
- System.out.println(getAllLocalNodesHeaderOutput());
- System.out.println("--------------------------------------------------------------------------");
+ session.getConsole().println("Number of nodes: " + ofNodeList.size());
+ session.getConsole().println(getAllLocalNodesHeaderOutput());
+ session.getConsole().println(LINE_SEPARATOR);
for (OFNode ofNode : ofNodeList) {
- System.out.println(formatter.format("%-15s %3s %-15s %n",
+ session.getConsole().println(formatter.format("%-15s %3s %-15s %n",
ofNode.getNodeId(), "", ofNode.getNodeName()).toString());
stringBuilder.setLength(0);
}
package org.opendaylight.openflowplugin.applications.southboundcli.cli;
import static org.opendaylight.openflowplugin.applications.frm.util.FrmUtil.OPENFLOW_PREFIX;
+import static org.opendaylight.openflowplugin.applications.southboundcli.util.ShellUtil.LINE_SEPARATOR;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Formatter;
import java.util.Map;
import java.util.Map.Entry;
-import org.apache.karaf.shell.commands.Command;
-import org.apache.karaf.shell.commands.Option;
-import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.Session;
import org.opendaylight.openflowplugin.api.openflow.FlowGroupInfo;
import org.opendaylight.openflowplugin.api.openflow.FlowGroupInfoHistories;
import org.opendaylight.openflowplugin.api.openflow.FlowGroupInfoHistory;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
+@Service
@Command(scope = "openflow", name = "getflownodecache", description = "Print all flow/group cache")
-public class GetFlowGroupCacheProvider extends OsgiCommandSupport {
- // FIXME: use String.repeat(), this does look arbitrary
- private static final String LINE_SEPARATOR =
- "--------------------------------------------------------------------------------------------------------------"
- + "------------------------------";
-
+public final class GetFlowGroupCacheCommand implements Action {
@Option(name = "-d", description = "Node Id")
String dpnId;
- private final FlowGroupInfoHistories histories;
-
- public GetFlowGroupCacheProvider(final FlowGroupInfoHistories histories) {
- this.histories = histories;
- }
+ @Reference
+ Session session;
+ @Reference
+ FlowGroupInfoHistories histories;
@Override
- @SuppressWarnings("checkstyle:RegexpSinglelineJava")
- protected Object doExecute() {
+ public Object execute() {
+ if (histories == null) {
+ // not initialized
+ return null;
+ }
if (dpnId == null) {
printAllNodes();
return null;
StringBuilder sb = new StringBuilder();
Formatter fmt = new Formatter(sb);
- System.out.println(String.format("Number of flows and groups in cache for node %s : %d", nodeId,
+ session.getConsole().println(String.format("Number of flows and groups in cache for node %s : %d", nodeId,
entries.size()));
- System.out.println(getLocalNodeHeaderOutput());
- System.out.println(LINE_SEPARATOR);
+ session.getConsole().println(getLocalNodeHeaderOutput());
+ session.getConsole().println(LINE_SEPARATOR);
for (FlowGroupInfo entry : entries) {
- System.out.println(fmt.format("%-10s %1s %-8s %1s %-23s %1s %-60s", entry.getDescription(), "",
- entry.getStatus(), "", getTime(entry), "", entry.getId()).toString());
+ session.getConsole().println(fmt.format("%-10s %1s %-8s %1s %-23s %1s %-60s", entry.getDescription(), "",
+ entry.getStatus(), "", getTime(entry), "", entry.getId()));
sb.setLength(0);
}
fmt.close();
StringBuilder sb = new StringBuilder();
Formatter fmt = new Formatter(sb);
- System.out.println(getAllLocalNodesHeaderOutput());
- System.out.println(LINE_SEPARATOR);
+ session.getConsole().println(getAllLocalNodesHeaderOutput());
+ session.getConsole().println(LINE_SEPARATOR);
for (Entry<NodeId, FlowGroupInfoHistory> entry : allHistories.entrySet()) {
// FIXME: just seek/substring
String[] temp = entry.getKey().getValue().split(":");
String node = temp[1];
for (FlowGroupInfo info : entry.getValue().readEntries()) {
- System.out.println(fmt.format("%-15s %1s %-10s %1s %-8s %1s %-21s %1s %-60s", node, "",
+ session.getConsole().println(fmt.format("%-15s %1s %-10s %1s %-8s %1s %-21s %1s %-60s", node, "",
info.getDescription(), "", info.getStatus(), "", getTime(info), "", info.getId()).toString());
sb.setLength(0);
}
*/
package org.opendaylight.openflowplugin.applications.southboundcli.cli;
+import static org.opendaylight.openflowplugin.applications.southboundcli.util.ShellUtil.LINE_SEPARATOR;
+
import java.util.ArrayList;
-import org.apache.karaf.shell.commands.Command;
-import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.Session;
import org.opendaylight.openflowplugin.applications.frm.ReconciliationJMXServiceMBean;
+@Service
@Command(scope = "openflow", name = "getreconciliationstate",
description = "Print reconciliation state for all devices")
-public class GetReconciliationStateProvider extends OsgiCommandSupport {
- private final ReconciliationJMXServiceMBean reconciliationJMXServiceMBean;
-
- public GetReconciliationStateProvider(final ReconciliationJMXServiceMBean reconciliationJMXServiceMBean) {
- this.reconciliationJMXServiceMBean = reconciliationJMXServiceMBean;
- }
+public final class GetReconciliationStateCommand implements Action {
+ @Reference
+ Session session;
+ @Reference
+ ReconciliationJMXServiceMBean reconciliationJMXServiceMBean;
@Override
- protected Object doExecute() {
+ public Object execute() {
+ if (reconciliationJMXServiceMBean == null) {
+ // not initialized
+ return null;
+ }
+
final var reconciliationStates = reconciliationJMXServiceMBean.acquireReconciliationStates();
if (!reconciliationStates.isEmpty()) {
final var result = new ArrayList<String>();
result.add(status);
});
session.getConsole().println(getHeaderOutput());
- session.getConsole().println(getLineSeparator());
+ session.getConsole().println(LINE_SEPARATOR);
result.stream().forEach(p -> session.getConsole().println(p));
} else {
session.getConsole().println("Reconciliation data not available");
private static String getHeaderOutput() {
return String.format("%-17s %-25s %-25s", "DatapathId", "Reconciliation Status", "Reconciliation Time");
}
-
- private static String getLineSeparator() {
- return "-------------------------------------------------------------------";
- }
}
\ No newline at end of file
*/
package org.opendaylight.openflowplugin.applications.southboundcli.cli;
+import static org.opendaylight.openflowplugin.applications.southboundcli.util.ShellUtil.LINE_SEPARATOR;
+
import java.util.Formatter;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
-import org.apache.karaf.shell.commands.Argument;
-import org.apache.karaf.shell.commands.Command;
-import org.apache.karaf.shell.commands.Option;
-import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Argument;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.Session;
import org.opendaylight.openflowplugin.applications.southboundcli.ReconcileService;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.app.reconciliation.service.rev180227.ReconcileOutput;
import org.opendaylight.yangtools.yang.common.Uint64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+@Service
@Command(scope = "openflow", name = "reconcile", description = "Launch reconciliation for openflow nodes")
-public class Reconciliation extends OsgiCommandSupport {
- private static final Logger LOG = LoggerFactory.getLogger(Reconciliation.class);
-
- private ReconcileService reconciliationService = null;
-
- public void setReconciliationService(final ReconcileService reconciliationService) {
- this.reconciliationService = reconciliationService;
- }
+public final class ReconcileCommand implements Action {
+ private static final Logger LOG = LoggerFactory.getLogger(ReconcileCommand.class);
+ @Reference
+ Session session;
+ @Reference
+ ReconcileService reconciliationService = null;
@Argument(name = "nodeId", description = "The NODE Id", multiValued = true)
List<Long> nodeIds;
@Option(name = "-all", description = "Reconcile all operative NODEs")
boolean reconcileAllNodes;
- @SuppressWarnings("checkstyle:RegexpSinglelineJava")
@Override
- protected Object doExecute() throws Exception {
+ public Object execute() throws Exception {
+ if (reconciliationService == null) {
+ // not initialized
+ return null;
+ }
+
final var nodes = nodeIds == null ? Set.<Uint64>of()
: nodeIds.stream().map(Uint64::valueOf).collect(Collectors.toSet());
final var rpcOutput = reconcileAllNodes ? reconciliationService.reconcileAll()
try {
final var rpcResult = rpcOutput.get();
if (rpcResult.isSuccessful()) {
- System.out.println("Reconciliation triggered for the node(s)");
+ session.getConsole().println("Reconciliation triggered for the node(s)");
printInProgressNodes(rpcResult.getResult());
} else {
- System.out.println(rpcResult.getErrors().stream().findFirst().orElseThrow().getMessage());
+ session.getConsole().println(rpcResult.getErrors().stream().findFirst().orElseThrow().getMessage());
}
} catch (ExecutionException e) {
LOG.error("Error occurred while invoking reconcile RPC for node {}", nodes, e);
return null;
}
- @SuppressWarnings("checkstyle:RegexpSinglelineJava")
- private static void printInProgressNodes(final ReconcileOutput reconcileOutput) {
+ private void printInProgressNodes(final ReconcileOutput reconcileOutput) {
final var inprogressNodes = reconcileOutput.getInprogressNodes();
if (inprogressNodes.size() > 0) {
final var stringBuilder = new StringBuilder();
try (var formatter = new Formatter(stringBuilder)) {
- System.out.println(getReconcileHeaderOutput());
- System.out.println("----------------------------------------------------");
+ session.getConsole().println(getReconcileHeaderOutput());
+ session.getConsole().println(LINE_SEPARATOR);
for (Uint64 node : inprogressNodes) {
- System.out.println(formatter.format("%-15s %n",node).toString());
+ session.getConsole().println(formatter.format("%-15s %n",node));
stringBuilder.setLength(0);
}
}
package org.opendaylight.openflowplugin.applications.southboundcli.cli;
-import java.util.Collection;
import java.util.Formatter;
-import org.apache.karaf.shell.commands.Command;
-import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.Session;
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.openflowplugin.applications.southboundcli.util.ShellUtil;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflowplugin.app.reconciliation.service.rev180227.reconciliation.counter.ReconcileCounter;
+@Service
@Command(scope = "openflow", name = "getReconciliationCount",
description = "Displays the number of reconciliation triggered for openflow nodes")
-public class ReconciliationCount extends OsgiCommandSupport {
+public final class ReconciliationCountCommand implements Action {
+ @Reference
+ Session session;
+ @Reference
+ DataBroker dataBroker;
- private DataBroker dataBroker;
-
- public void setDataBroker(final DataBroker dataBroker) {
- this.dataBroker = dataBroker;
- }
-
- @SuppressWarnings("checkstyle:RegexpSinglelineJava")
@Override
- protected Object doExecute() {
- Collection<ReconcileCounter> result = ShellUtil.getReconcileCount(dataBroker);
+ public Object execute() {
+ if (dataBroker == null) {
+ // not initialized
+ return null;
+ }
+ final var result = ShellUtil.getReconcileCount(dataBroker);
if (result.isEmpty()) {
- System.out.println("Reconciliation count not yet available for openflow nodes.");
+ session.getConsole().println("Reconciliation count not yet available for openflow nodes.");
} else {
StringBuilder stringBuilder = new StringBuilder();
final Formatter formatter = new Formatter(stringBuilder);
- System.out.println(getReconcileCountHeaderOutput());
- System.out.println("--------------------------------------------------------------------------"
- + "---------------------------");
+ session.getConsole().println(getReconcileCountHeaderOutput());
+ session.getConsole().println("-".repeat(100));
for (ReconcileCounter reconcile : result) {
- System.out.println(formatter.format("%-15s %3s %-15s %9s %-20s %4s %-20s %n",
+ session.getConsole().println(formatter.format("%-15s %3s %-15s %9s %-20s %4s %-20s %n",
reconcile.getNodeId(), "", reconcile.getSuccessCount(), "", reconcile.getFailureCount(), "",
- reconcile.getLastRequestTime().getValue()).toString());
+ reconcile.getLastRequestTime().getValue()));
stringBuilder.setLength(0);
}
formatter.close();
*/
package org.opendaylight.openflowplugin.applications.southboundcli.cli;
+import static org.opendaylight.openflowplugin.applications.southboundcli.util.ShellUtil.LINE_SEPARATOR;
+
import java.util.Formatter;
-import org.apache.karaf.shell.commands.Command;
-import org.apache.karaf.shell.commands.Option;
-import org.apache.karaf.shell.console.OsgiCommandSupport;
+import org.apache.karaf.shell.api.action.Action;
+import org.apache.karaf.shell.api.action.Command;
+import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.action.lifecycle.Reference;
+import org.apache.karaf.shell.api.action.lifecycle.Service;
+import org.apache.karaf.shell.api.console.Session;
import org.opendaylight.mdsal.binding.api.DataBroker;
import org.opendaylight.openflowplugin.applications.southboundcli.util.OFNode;
import org.opendaylight.openflowplugin.applications.southboundcli.util.ShellUtil;
+@Service
@Command(scope = "openflow", name = "shownode", description = "shownode -d <NodeID>")
-public class ShowNodeCommandProvider extends OsgiCommandSupport {
+@Deprecated
+public class ShowNodeCommand implements Action {
public static final String OUTPUT_FORMAT = "%-24s %-20s %-15s";
public static final String NEW_LINE = "%-24s %-20s %-15s %n";
- public static final String HEADER_SEPARATOR = "---------------------------------------------"
- + "---------------------------------------";
- @Option(name = "-d", description = "Node Id", required = true, multiValued = false)
+ @Option(name = "-d", description = "Node Id", required = true)
String nodeId;
+ @Reference
+ Session session;
+ @Reference
+ DataBroker dataBroker;
- private DataBroker dataBroker;
-
- public void setDataBroker(final DataBroker dataBroker) {
- this.dataBroker = dataBroker;
- }
-
- @SuppressWarnings("checkstyle:RegexpSinglelineJava")
- @Deprecated
@Override
- protected Object doExecute() {
+ public Object execute() {
if (nodeId == null) {
- System.out.println("NodeID not specified");
+ session.getConsole().println("NodeID not specified");
return null;
}
OFNode node = ShellUtil.getNode(Long.parseLong(nodeId), dataBroker);
if (node != null) {
printNodeHeaderOutput();
- printHeaderSeparator();
+ session.getConsole().println(LINE_SEPARATOR);
printNodeOutput(node);
} else {
- System.out.println("No node available for this NodeID");
+ session.getConsole().println("No node available for this NodeID");
}
return null;
}
- @SuppressWarnings("checkstyle:RegexpSinglelineJava")
- private static void printNodeHeaderOutput() {
+ private void printNodeHeaderOutput() {
Formatter formatter = new Formatter();
String header = formatter.format(OUTPUT_FORMAT, "NodeId", "Name", "Ports").toString();
formatter.close();
- System.out.println(header);
- }
-
- @SuppressWarnings("checkstyle:RegexpSinglelineJava")
- private static void printHeaderSeparator() {
- System.out.println(HEADER_SEPARATOR);
+ session.getConsole().println(header);
}
- @SuppressWarnings("checkstyle:RegexpSinglelineJava")
- private static void printNodeOutput(final OFNode ofNode) {
+ private void printNodeOutput(final OFNode ofNode) {
String ofNodeId = ofNode.getNodeId().toString();
String ofNodeName = ofNode.getNodeName();
- System.out.print(new Formatter().format(NEW_LINE, ofNodeId, ofNodeName, ofNode.getPorts()).toString());
+ session.getConsole().print(new Formatter().format(NEW_LINE, ofNodeId, ofNodeName, ofNode.getPorts()));
}
}
\ No newline at end of file
public final class ShellUtil {
private static final Logger LOG = LoggerFactory.getLogger(ShellUtil.class);
+ public static final String LINE_SEPARATOR = "-".repeat(100);
public static final String NODE_PREFIX = "openflow:";
private ShellUtil() {
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
- xmlns:cm="http://aries.apache.org/blueprint/xmlns/blueprint-cm/v1.2.0">
- <reference id="dataBroker"
- interface="org.opendaylight.mdsal.binding.api.DataBroker"/>
- <reference id="reconciliationJMXServiceMBean"
- interface="org.opendaylight.openflowplugin.applications.frm.ReconciliationJMXServiceMBean"
- availability="optional"/>
- <reference id="clusterMemberInfoProvider"
- interface="org.opendaylight.infrautils.diagstatus.ClusterMemberInfo"
- availability="optional"/>
- <reference id="flowGroupHistories"
- interface="org.opendaylight.openflowplugin.api.openflow.FlowGroupInfoHistories"/>
- <reference id="reconciliationService"
- interface="org.opendaylight.openflowplugin.applications.southboundcli.ReconcileService"/>
- <reference id="dpnTracker"
- interface="org.opendaylight.openflowplugin.applications.southboundcli.DpnTracker"/>
-
- <cm:property-placeholder persistent-id="org.ops4j.pax.web" update-strategy="none">
- <cm:default-properties>
- <cm:property name="org.osgi.service.http.port" value="8181"/>
- </cm:default-properties>
- </cm:property-placeholder>
-
- <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.0.0">
- <command name="openflow/getallnodes">
- <action class="org.opendaylight.openflowplugin.applications.southboundcli.cli.GetAllNodesCommandProvider">
- <argument ref="dpnTracker"/>
- </action>
- </command>
- <command name="openflow/shownode">
- <action class="org.opendaylight.openflowplugin.applications.southboundcli.cli.ShowNodeCommandProvider">
- <property name="dataBroker" ref="dataBroker" />
- </action>
- </command>
- <command name="openflow/reconcile">
- <action class="org.opendaylight.openflowplugin.applications.southboundcli.cli.Reconciliation">
- <property name="reconciliationService" ref="reconciliationService"/>
- </action>
- </command>
- <command name="openflow/getreconciliationcount">
- <action class="org.opendaylight.openflowplugin.applications.southboundcli.cli.ReconciliationCount">
- <property name="dataBroker" ref="dataBroker"/>
- </action>
- </command>
- <command name="openflow/getreconciliationstate">
- <action class="org.opendaylight.openflowplugin.applications.southboundcli.cli.GetReconciliationStateProvider">
- <argument ref ="reconciliationJMXServiceMBean"/>
- </action>
- </command>
- <command name="openflow/getflownodecache">
- <action class="org.opendaylight.openflowplugin.applications.southboundcli.cli.GetFlowGroupCacheProvider">
- <argument ref="flowGroupHistories"/>
- </action>
- </command>
- </command-bundle>
-</blueprint>