From: Robert Varga Date: Thu, 23 May 2024 11:57:03 +0000 (+0200) Subject: Change getIsOnlineFuture() return type X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=HEAD;hp=e620857d93ebd1c42ae5d8a2d4cb4bc886814d6b;p=openflowplugin.git Change getIsOnlineFuture() return type Provising a Boolean is superfluous -- we are just reporting success/failure. Clean this up by using Void as the return type. Change-Id: I7e292941a59f255d27df25828f6848bfc6b8059e Signed-off-by: Robert Varga (cherry picked from commit 5a64f2402b8af587dec4c692c57b44563368b463) --- diff --git a/applications/bulk-o-matic/src/main/java/org/opendaylight/openflowplugin/applications/bulk/o/matic/FlowWriterTxChain.java b/applications/bulk-o-matic/src/main/java/org/opendaylight/openflowplugin/applications/bulk/o/matic/FlowWriterTxChain.java index 067b6d3439..b66d3477e0 100644 --- a/applications/bulk-o-matic/src/main/java/org/opendaylight/openflowplugin/applications/bulk/o/matic/FlowWriterTxChain.java +++ b/applications/bulk-o-matic/src/main/java/org/opendaylight/openflowplugin/applications/bulk/o/matic/FlowWriterTxChain.java @@ -109,16 +109,16 @@ public class FlowWriterTxChain implements FlowCounterMBean { @Override public void run() { writeOpStatus.set(FlowCounter.OperationStatus.IN_PROGRESS.status()); - short tableId = startTableId; - int numSubmits = flowsPerDpn / batchSize; - int sourceIp = 1; - int newBatchSize = batchSize; + final int numSubmits = flowsPerDpn / batchSize; LOG.info("Number of Txn for dpId: {} is: {}", dpId, numSubmits); txChain = dataBroker.createMergingTransactionChain(); txChain.addCallback(this); LOG.info("Creating new txChain: {} for dpid: {}", txChain, dpId); + short tableId = startTableId; + int sourceIp = 1; + int newBatchSize = batchSize; for (int i = 1; i <= numSubmits; i++) { WriteTransaction writeTransaction = txChain.newWriteOnlyTransaction(); short calculatedTableId = tableId; diff --git a/applications/southbound-cli/pom.xml b/applications/southbound-cli/pom.xml index e3a5e59d1e..88f48eaa7a 100644 --- a/applications/southbound-cli/pom.xml +++ b/applications/southbound-cli/pom.xml @@ -25,7 +25,7 @@ org.apache.karaf.shell - org.apache.karaf.shell.console + org.apache.karaf.shell.core provided @@ -63,4 +63,13 @@ + + + + org.apache.karaf.tooling + karaf-services-maven-plugin + + + + diff --git a/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/DefaultDpnTracker.java b/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/DefaultDpnTracker.java index f0a37a076a..d126a6803e 100644 --- a/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/DefaultDpnTracker.java +++ b/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/DefaultDpnTracker.java @@ -33,7 +33,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Singleton -@Component(service = DpnTracker.class) +@Component(service = DpnTracker.class, immediate = true) public final class DefaultDpnTracker implements DpnTracker, DataTreeChangeListener, AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(DefaultDpnTracker.class); public static final String DEFAULT_DPN_NAME = "UNKNOWN"; diff --git a/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetAllNodesCommandProvider.java b/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetAllNodesCommand.java similarity index 57% rename from applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetAllNodesCommandProvider.java rename to applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetAllNodesCommand.java index 65c643a220..e2015dfced 100644 --- a/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetAllNodesCommandProvider.java +++ b/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetAllNodesCommand.java @@ -7,38 +7,45 @@ */ 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); } diff --git a/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetFlowGroupCacheProvider.java b/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetFlowGroupCacheCommand.java similarity index 57% rename from applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetFlowGroupCacheProvider.java rename to applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetFlowGroupCacheCommand.java index 6f443ef14a..699bcadd05 100644 --- a/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetFlowGroupCacheProvider.java +++ b/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetFlowGroupCacheCommand.java @@ -8,6 +8,7 @@ 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; @@ -15,33 +16,34 @@ import java.util.Collection; 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; @@ -59,16 +61,16 @@ public class GetFlowGroupCacheProvider extends OsgiCommandSupport { 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); + StringBuilder sb = new StringBuilder(); + Formatter fmt = new Formatter(sb); 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(); @@ -87,36 +89,34 @@ public class GetFlowGroupCacheProvider extends OsgiCommandSupport { return; } + session.getConsole().println(getAllLocalNodesHeaderOutput()); + session.getConsole().println(LINE_SEPARATOR); StringBuilder sb = new StringBuilder(); - Formatter fmt = new Formatter(sb); - System.out.println(getAllLocalNodesHeaderOutput()); - System.out.println(LINE_SEPARATOR); - for (Entry 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, "", - info.getDescription(), "", info.getStatus(), "", getTime(info), "", info.getId()).toString()); - sb.setLength(0); + try (var fmt = new Formatter(sb)) { + for (Entry entry : allHistories.entrySet()) { + // FIXME: just seek/substring + String[] temp = entry.getKey().getValue().split(":"); + String node = temp[1]; + for (FlowGroupInfo info : entry.getValue().readEntries()) { + 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); + } } } - fmt.close(); } private static String getLocalNodeHeaderOutput() { - Formatter formatter = new Formatter(); - String header = formatter.format("%-10s %1s %-8s %1s %-23s %1s %-60s", + try (var formatter = new Formatter()) { + return formatter.format("%-10s %1s %-8s %1s %-23s %1s %-60s", "TableId", "", "Status", "", "Time", "", "Flow/Group Id").toString(); - formatter.close(); - return header; + } } private static String getAllLocalNodesHeaderOutput() { - Formatter formatter = new Formatter(); - String header = formatter.format("%-15s %1s %-10s %1s %-8s %1s %-23s %1s %-60s", + try (var formatter = new Formatter()) { + return formatter.format("%-15s %1s %-10s %1s %-8s %1s %-23s %1s %-60s", "DpnId", "", "TableId", "", "Status", "", "Time", "", "Flow/Group Id").toString(); - formatter.close(); - return header; + } } } diff --git a/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetReconciliationStateProvider.java b/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetReconciliationStateCommand.java similarity index 66% rename from applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetReconciliationStateProvider.java rename to applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetReconciliationStateCommand.java index 6edce23129..c140a502df 100644 --- a/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetReconciliationStateProvider.java +++ b/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/GetReconciliationStateCommand.java @@ -7,22 +7,32 @@ */ 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(); @@ -31,7 +41,7 @@ public class GetReconciliationStateProvider extends OsgiCommandSupport { 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"); @@ -42,8 +52,4 @@ public class GetReconciliationStateProvider extends OsgiCommandSupport { 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 diff --git a/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/Reconciliation.java b/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/ReconcileCommand.java similarity index 66% rename from applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/Reconciliation.java rename to applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/ReconcileCommand.java index 7d4adbeae1..cf4a9f77f5 100644 --- a/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/Reconciliation.java +++ b/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/ReconcileCommand.java @@ -7,30 +7,34 @@ */ 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 nodeIds; @@ -38,9 +42,13 @@ public class Reconciliation extends OsgiCommandSupport { @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.of() : nodeIds.stream().map(Uint64::valueOf).collect(Collectors.toSet()); final var rpcOutput = reconcileAllNodes ? reconciliationService.reconcileAll() @@ -49,10 +57,10 @@ public class Reconciliation extends OsgiCommandSupport { 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); @@ -60,16 +68,15 @@ public class Reconciliation extends OsgiCommandSupport { 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); } } diff --git a/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/ReconciliationCount.java b/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/ReconciliationCountCommand.java similarity index 65% rename from applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/ReconciliationCount.java rename to applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/ReconciliationCountCommand.java index 16c9b95329..cc7c14d3b0 100644 --- a/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/ReconciliationCount.java +++ b/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/ReconciliationCountCommand.java @@ -8,40 +8,43 @@ 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 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(); diff --git a/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/ShowNodeCommandProvider.java b/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/ShowNodeCommand.java similarity index 53% rename from applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/ShowNodeCommandProvider.java rename to applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/ShowNodeCommand.java index d75ced1e69..4f4a41a22b 100644 --- a/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/ShowNodeCommandProvider.java +++ b/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/cli/ShowNodeCommand.java @@ -7,66 +7,60 @@ */ 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 ") -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 diff --git a/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/util/ShellUtil.java b/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/util/ShellUtil.java index 9a91a4fe6b..d0be9bc924 100644 --- a/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/util/ShellUtil.java +++ b/applications/southbound-cli/src/main/java/org/opendaylight/openflowplugin/applications/southboundcli/util/ShellUtil.java @@ -32,6 +32,7 @@ import org.slf4j.LoggerFactory; 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() { diff --git a/applications/southbound-cli/src/main/resources/OSGI-INF/blueprint/commands.xml b/applications/southbound-cli/src/main/resources/OSGI-INF/blueprint/commands.xml deleted file mode 100644 index 6c68e0924a..0000000000 --- a/applications/southbound-cli/src/main/resources/OSGI-INF/blueprint/commands.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libraries/liblldp/src/main/java/org/opendaylight/openflowplugin/libraries/liblldp/BitBufferHelper.java b/libraries/liblldp/src/main/java/org/opendaylight/openflowplugin/libraries/liblldp/BitBufferHelper.java index 90cfdaaf0f..8c187243a5 100644 --- a/libraries/liblldp/src/main/java/org/opendaylight/openflowplugin/libraries/liblldp/BitBufferHelper.java +++ b/libraries/liblldp/src/main/java/org/opendaylight/openflowplugin/libraries/liblldp/BitBufferHelper.java @@ -166,7 +166,6 @@ public abstract class BitBufferHelper { public static byte @NonNull [] getBits(final byte[] data, final int startOffset, final int numBits) throws BufferException { int startByteOffset; - int extranumBits = numBits % NetUtils.NUM_BITS_IN_A_BYTE; final int extraOffsetBits = startOffset % NetUtils.NUM_BITS_IN_A_BYTE; int numBytes = numBits % NetUtils.NUM_BITS_IN_A_BYTE != 0 ? 1 + numBits / NetUtils.NUM_BITS_IN_A_BYTE : numBits / NetUtils.NUM_BITS_IN_A_BYTE; @@ -178,6 +177,7 @@ public abstract class BitBufferHelper { checkExceptions(data, startOffset, numBits); + final int extranumBits = numBits % NetUtils.NUM_BITS_IN_A_BYTE; if (extraOffsetBits == 0) { if (extranumBits == 0) { System.arraycopy(data, startByteOffset, bytes, 0, numBytes); @@ -539,9 +539,8 @@ public abstract class BitBufferHelper { public static byte[] shiftBitsToMSB(final byte[] inputBytes, final int numBits) { int numBitstoShiftBy; int leadZeroesMSB = 8; - int numEndRestBits; int size = inputBytes.length; - byte[] shiftedBytes = new byte[size]; + final byte[] shiftedBytes = new byte[size]; for (int i = 0; i < Byte.SIZE; i++) { if ((byte) (inputBytes[0] & getMSBMask(i + 1)) != 0) { @@ -565,7 +564,7 @@ public abstract class BitBufferHelper { shiftedBytes[0] = (byte) ((inputBytes[0] & getLSBMask(numBits)) << numBitstoShiftBy); } else { // # of bits to read from last byte - numEndRestBits = NetUtils.NUM_BITS_IN_A_BYTE + final int numEndRestBits = NetUtils.NUM_BITS_IN_A_BYTE - (inputBytes.length * NetUtils.NUM_BITS_IN_A_BYTE - numBits - numBitstoShiftBy); for (int i = 0; i < size - 1; i++) { diff --git a/openflowjava/openflow-protocol-api/pom.xml b/openflowjava/openflow-protocol-api/pom.xml index c70fc90052..daea5ce148 100644 --- a/openflowjava/openflow-protocol-api/pom.xml +++ b/openflowjava/openflow-protocol-api/pom.xml @@ -21,12 +21,12 @@ - org.opendaylight.mdsal - yang-binding + io.netty + netty-buffer - org.opendaylight.yangtools - yang-common + org.opendaylight.mdsal + yang-binding org.opendaylight.mdsal.binding.model.ietf @@ -41,8 +41,12 @@ yang-ext - io.netty - netty-buffer + org.opendaylight.yangtools + concepts + + + org.opendaylight.yangtools + yang-common diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ConnectionConfigurationImpl.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ConnectionConfigurationImpl.java new file mode 100644 index 0000000000..45a9136187 --- /dev/null +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ConnectionConfigurationImpl.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2024 PANTHEON.tech, s.r.o. 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.openflowjava.protocol.impl.core; + +import static java.util.Objects.requireNonNull; + +import java.net.InetAddress; +import java.util.List; +import org.opendaylight.openflowjava.protocol.api.connection.ConnectionConfiguration; +import org.opendaylight.openflowjava.protocol.api.connection.ThreadConfiguration; +import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.TransportProtocol; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.config.rev160506.SwitchConnectionConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.config.rev160506._switch.connection.config.Threads; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.config.rev160506._switch.connection.config.Tls; + +final class ConnectionConfigurationImpl implements ConnectionConfiguration { + private final SwitchConnectionConfig config; + private final InetAddress address; + + ConnectionConfigurationImpl(final SwitchConnectionConfig config) { + this.config = requireNonNull(config); + final var addr = config.getAddress(); + address = addr != null ? IetfInetUtil.inetAddressFor(addr) : null; + } + + @Override + public InetAddress getAddress() { + return address; + } + + @Override + public int getPort() { + return config.getPort().toJava(); + } + + @Override + public Object getTransferProtocol() { + return config.getTransportProtocol(); + } + + @Override + public int getChannelOutboundQueueSize() { + return config.getChannelOutboundQueueSize().toJava(); + } + + @Override + public TlsConfiguration getTlsConfiguration() { + final Tls tlsConfig = config.getTls(); + if (tlsConfig == null || !TransportProtocol.TLS.equals(getTransferProtocol())) { + return null; + } + + return new TlsConfiguration() { + @Override + public KeystoreType getTlsTruststoreType() { + return requireNonNull(tlsConfig.getTruststoreType()); + } + + @Override + public String getTlsTruststore() { + return requireNonNull(tlsConfig.getTruststore()); + } + + @Override + public KeystoreType getTlsKeystoreType() { + return requireNonNull(tlsConfig.getKeystoreType()); + } + + @Override + public String getTlsKeystore() { + return requireNonNull(tlsConfig.getKeystore()); + } + + @Override + public org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType + getTlsKeystorePathType() { + return requireNonNull(tlsConfig.getKeystorePathType()); + } + + @Override + public org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType + getTlsTruststorePathType() { + return requireNonNull(tlsConfig.getTruststorePathType()); + } + + @Override + public String getKeystorePassword() { + return requireNonNull(tlsConfig.getKeystorePassword()); + } + + @Override + public String getCertificatePassword() { + return requireNonNull(tlsConfig.getCertificatePassword()); + } + + @Override + public String getTruststorePassword() { + return requireNonNull(tlsConfig.getTruststorePassword()); + } + + @Override + public List getCipherSuites() { + return tlsConfig.getCipherSuites(); + } + }; + } + + @Override + public long getSwitchIdleTimeout() { + return config.getSwitchIdleTimeout().toJava(); + } + + @Override + public Object getSslContext() { + return null; + } + + @Override + public ThreadConfiguration getThreadConfiguration() { + final Threads threads = config.getThreads(); + if (threads == null) { + return null; + } + + return new ThreadConfiguration() { + @Override + public int getWorkerThreadCount() { + return threads.getWorkerThreads().toJava(); + } + + @Override + public int getBossThreadCount() { + return threads.getBossThreads().toJava(); + } + }; + } + + @Override + public boolean useBarrier() { + return config.getUseBarrier(); + } + + @Override + public boolean isGroupAddModEnabled() { + return config.getGroupAddModEnabled(); + } +} \ No newline at end of file diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OnlineProvider.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OnlineProvider.java index c167dfb7f4..370ea160a9 100644 --- a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OnlineProvider.java +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/OnlineProvider.java @@ -5,8 +5,6 @@ * 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.openflowjava.protocol.impl.core; import com.google.common.util.concurrent.ListenableFuture; @@ -18,5 +16,5 @@ import com.google.common.util.concurrent.ListenableFuture; */ public interface OnlineProvider { - ListenableFuture getIsOnlineFuture(); + ListenableFuture getIsOnlineFuture(); } diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ServerFacade.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ServerFacade.java index 67bb0a3d32..6a0fa1ab6c 100644 --- a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ServerFacade.java +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/ServerFacade.java @@ -7,19 +7,11 @@ */ package org.opendaylight.openflowjava.protocol.impl.core; -import org.opendaylight.openflowjava.protocol.api.connection.ThreadConfiguration; - /** * Server facade interface. * * @author mirehak */ public interface ServerFacade extends ShutdownProvider, OnlineProvider, Runnable { - /** - * Sets thread configuration. - * - * @param threadConfig desired thread configuration - */ - @Deprecated(since = "0.17.2", forRemoval = true) - void setThreadConfig(ThreadConfiguration threadConfig); + } diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderFactoryImpl.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderFactoryImpl.java index 7ee78a13ff..cb8a963d5a 100644 --- a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderFactoryImpl.java +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderFactoryImpl.java @@ -9,23 +9,12 @@ package org.opendaylight.openflowjava.protocol.impl.core; import static java.util.Objects.requireNonNull; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.List; import javax.inject.Inject; import javax.inject.Singleton; import org.opendaylight.infrautils.diagstatus.DiagStatusService; -import org.opendaylight.openflowjava.protocol.api.connection.ConnectionConfiguration; -import org.opendaylight.openflowjava.protocol.api.connection.ThreadConfiguration; -import org.opendaylight.openflowjava.protocol.api.connection.TlsConfiguration; import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider; import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProviderFactory; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.TransportProtocol; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.config.rev160506.SwitchConnectionConfig; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.config.rev160506._switch.connection.config.Threads; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.config.rev160506._switch.connection.config.Tls; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; @@ -48,152 +37,4 @@ public class SwitchConnectionProviderFactoryImpl implements SwitchConnectionProv public SwitchConnectionProvider newInstance(final SwitchConnectionConfig config) { return new SwitchConnectionProviderImpl(diagStatus, new ConnectionConfigurationImpl(config)); } - - private static class ConnectionConfigurationImpl implements ConnectionConfiguration { - private final SwitchConnectionConfig config; - private InetAddress address; - - ConnectionConfigurationImpl(final SwitchConnectionConfig config) { - this.config = config; - - try { - address = getInetAddress(config.getAddress()); - } catch (UnknownHostException e) { - throw new IllegalStateException(e); - } - } - - @Override - public InetAddress getAddress() { - return address; - } - - @Override - public int getPort() { - return config.getPort().toJava(); - } - - @Override - public Object getTransferProtocol() { - return config.getTransportProtocol(); - } - - @Override - public int getChannelOutboundQueueSize() { - return config.getChannelOutboundQueueSize().toJava(); - } - - @Override - public TlsConfiguration getTlsConfiguration() { - final Tls tlsConfig = config.getTls(); - if (tlsConfig == null || !TransportProtocol.TLS.equals(getTransferProtocol())) { - return null; - } - - return new TlsConfiguration() { - @Override - public KeystoreType getTlsTruststoreType() { - return requireNonNull(tlsConfig.getTruststoreType()); - } - - @Override - public String getTlsTruststore() { - return requireNonNull(tlsConfig.getTruststore()); - } - - @Override - public KeystoreType getTlsKeystoreType() { - return requireNonNull(tlsConfig.getKeystoreType()); - } - - @Override - public String getTlsKeystore() { - return requireNonNull(tlsConfig.getKeystore()); - } - - @Override - public org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType - getTlsKeystorePathType() { - return requireNonNull(tlsConfig.getKeystorePathType()); - } - - @Override - public org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType - getTlsTruststorePathType() { - return requireNonNull(tlsConfig.getTruststorePathType()); - } - - @Override - public String getKeystorePassword() { - return requireNonNull(tlsConfig.getKeystorePassword()); - } - - @Override - public String getCertificatePassword() { - return requireNonNull(tlsConfig.getCertificatePassword()); - } - - @Override - public String getTruststorePassword() { - return requireNonNull(tlsConfig.getTruststorePassword()); - } - - @Override - public List getCipherSuites() { - return tlsConfig.getCipherSuites(); - } - }; - } - - @Override - public long getSwitchIdleTimeout() { - return config.getSwitchIdleTimeout().toJava(); - } - - @Override - public Object getSslContext() { - return null; - } - - @Override - public ThreadConfiguration getThreadConfiguration() { - final Threads threads = config.getThreads(); - if (threads == null) { - return null; - } - - return new ThreadConfiguration() { - @Override - public int getWorkerThreadCount() { - return threads.getWorkerThreads().toJava(); - } - - @Override - public int getBossThreadCount() { - return threads.getBossThreads().toJava(); - } - }; - } - - @Override - public boolean useBarrier() { - return config.getUseBarrier(); - } - - @Override - public boolean isGroupAddModEnabled() { - return config.getGroupAddModEnabled(); - } - - private static InetAddress getInetAddress(final IpAddress address) throws UnknownHostException { - if (address != null) { - if (address.getIpv4Address() != null) { - return InetAddress.getByName(address.getIpv4Address().getValue()); - } else if (address.getIpv6Address() != null) { - return InetAddress.getByName(address.getIpv6Address().getValue()); - } - } - return null; - } - } } diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderImpl.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderImpl.java index 923a9e8842..abd3af6eb8 100755 --- a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderImpl.java +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/SwitchConnectionProviderImpl.java @@ -7,15 +7,13 @@ */ package org.opendaylight.openflowjava.protocol.impl.core; -import static com.google.common.base.Preconditions.checkState; - import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; import com.google.common.util.concurrent.MoreExecutors; -import io.netty.channel.EventLoopGroup; import io.netty.channel.epoll.Epoll; +import java.util.Map; import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.infrautils.diagstatus.DiagStatusService; import org.opendaylight.infrautils.diagstatus.ServiceDescriptor; @@ -57,6 +55,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.meter.band.header.meter.band.MeterBandExperimenterCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.queue.property.header.QueueProperty; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.table.features.properties.grouping.TableFeatureProperties; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.config.rev160506.SwitchConnectionConfig; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,11 +70,18 @@ import org.slf4j.LoggerFactory; * @author mirehak * @author michal.polkorab */ +@Component(service = SwitchConnectionProvider.class, factory = SwitchConnectionProviderImpl.FACTORY_NAME) public class SwitchConnectionProviderImpl implements SwitchConnectionProvider, ConnectionInitializer { private static final Logger LOG = LoggerFactory.getLogger(SwitchConnectionProviderImpl.class); + private static final String THREAD_NAME_PREFIX = "OFP-SwitchConnectionProvider-Udp/TcpHandler"; private static final String OPENFLOW_JAVA_SERVICE_NAME_PREFIX = "OPENFLOW_SERVER"; + // OSGi DS Component Factory name + public static final String FACTORY_NAME = + "org.opendaylight.openflowjava.protocol.impl.core.SwitchConnectionProviderImpl"; + public static final String PROP_CONFIG = ".config"; + private SwitchConnectionHandler switchConnectionHandler; private ServerFacade serverFacade; private final ConnectionConfiguration connConfig; @@ -107,6 +117,17 @@ public class SwitchConnectionProviderImpl implements SwitchConnectionProvider, C deserializationFactory = new DeserializationFactory(deserializerRegistry); } + @Activate + public SwitchConnectionProviderImpl(@Reference final DiagStatusService diagStatus, + final Map props) { + this(diagStatus, new ConnectionConfigurationImpl((SwitchConnectionConfig) props.get(PROP_CONFIG))); + } + + @Deactivate + void deactivate() { + diagReg.close(); + } + // ID based, on configuration, used for diagstatus serviceIdentifier (ServiceDescriptor moduleServiceName) private static String createConnectionSuffix(final @Nullable ConnectionConfiguration config) { return config == null ? "-null-config" : "_" + config.getPort(); @@ -132,7 +153,7 @@ public class SwitchConnectionProviderImpl implements SwitchConnectionProvider, C @Override @SuppressWarnings("checkstyle:IllegalCatch") - public ListenableFuture startup() { + public ListenableFuture startup() { LOG.debug("Startup summoned"); try { serverFacade = createAndConfigureServer(); @@ -159,11 +180,16 @@ public class SwitchConnectionProviderImpl implements SwitchConnectionProvider, C private ServerFacade createAndConfigureServer() { LOG.debug("Configuring .."); - ServerFacade server; - checkState(connConfig != null, "Connection not configured"); + if (connConfig == null) { + throw new IllegalStateException("Connection not configured"); + } + final var transportProtocol = (TransportProtocol) connConfig.getTransferProtocol(); + if (transportProtocol == null) { + throw new IllegalStateException("No transport protocol received in " + connConfig); + } - final ChannelInitializerFactory factory = new ChannelInitializerFactory(); + final var factory = new ChannelInitializerFactory(); factory.setSwitchConnectionHandler(switchConnectionHandler); factory.setSwitchIdleTimeout(connConfig.getSwitchIdleTimeout()); factory.setTlsConfig(connConfig.getTlsConfiguration()); @@ -171,31 +197,31 @@ public class SwitchConnectionProviderImpl implements SwitchConnectionProvider, C factory.setDeserializationFactory(deserializationFactory); factory.setUseBarrier(connConfig.useBarrier()); factory.setChannelOutboundQueueSize(connConfig.getChannelOutboundQueueSize()); - final TransportProtocol transportProtocol = (TransportProtocol) connConfig.getTransferProtocol(); // Check if Epoll native transport is available. // TODO : Add option to disable Epoll. boolean isEpollEnabled = Epoll.isAvailable(); - if (TransportProtocol.TCP.equals(transportProtocol) || TransportProtocol.TLS.equals(transportProtocol)) { - server = new TcpHandler(connConfig.getAddress(), connConfig.getPort(), - () -> diagReg.report(new ServiceDescriptor(diagStatusIdentifier, ServiceState.OPERATIONAL))); - final TcpChannelInitializer channelInitializer = factory.createPublishingChannelInitializer(); - ((TcpHandler) server).setChannelInitializer(channelInitializer); - ((TcpHandler) server).initiateEventLoopGroups(connConfig.getThreadConfiguration(), isEpollEnabled); - final EventLoopGroup workerGroupFromTcpHandler = ((TcpHandler) server).getWorkerGroup(); - connectionInitializer = new TcpConnectionInitializer(workerGroupFromTcpHandler, isEpollEnabled); - connectionInitializer.setChannelInitializer(channelInitializer); - connectionInitializer.run(); - } else if (TransportProtocol.UDP.equals(transportProtocol)) { - server = new UdpHandler(connConfig.getAddress(), connConfig.getPort(), - () -> diagReg.report(new ServiceDescriptor(diagStatusIdentifier, ServiceState.OPERATIONAL))); - ((UdpHandler) server).initiateEventLoopGroups(connConfig.getThreadConfiguration(), isEpollEnabled); - ((UdpHandler) server).setChannelInitializer(factory.createUdpChannelInitializer()); - } else { - throw new IllegalStateException("Unknown transport protocol received: " + transportProtocol); - } - server.setThreadConfig(connConfig.getThreadConfiguration()); - return server; + return switch (transportProtocol) { + case TCP, TLS -> { + final var tcpHandler = new TcpHandler(connConfig.getAddress(), connConfig.getPort(), + () -> diagReg.report(new ServiceDescriptor(diagStatusIdentifier, ServiceState.OPERATIONAL))); + final var channelInitializer = factory.createPublishingChannelInitializer(); + tcpHandler.setChannelInitializer(channelInitializer); + tcpHandler.initiateEventLoopGroups(connConfig.getThreadConfiguration(), isEpollEnabled); + final var workerGroupFromTcpHandler = tcpHandler.getWorkerGroup(); + connectionInitializer = new TcpConnectionInitializer(workerGroupFromTcpHandler, isEpollEnabled); + connectionInitializer.setChannelInitializer(channelInitializer); + connectionInitializer.run(); + yield tcpHandler; + } + case UDP -> { + final var udpHandler = new UdpHandler(connConfig.getAddress(), connConfig.getPort(), + () -> diagReg.report(new ServiceDescriptor(diagStatusIdentifier, ServiceState.OPERATIONAL))); + udpHandler.initiateEventLoopGroups(connConfig.getThreadConfiguration(), isEpollEnabled); + udpHandler.setChannelInitializer(factory.createUdpChannelInitializer()); + yield udpHandler; + } + }; } public ServerFacade getServerFacade() { diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpConnectionInitializer.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpConnectionInitializer.java index 9e8d1fa9be..3549540889 100644 --- a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpConnectionInitializer.java +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpConnectionInitializer.java @@ -15,7 +15,6 @@ import io.netty.bootstrap.Bootstrap; import io.netty.channel.EventLoopGroup; import io.netty.channel.epoll.EpollSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; -import org.opendaylight.openflowjava.protocol.api.connection.ThreadConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,12 +24,11 @@ import org.slf4j.LoggerFactory; * @author martin.uhlir */ public class TcpConnectionInitializer implements ServerFacade, ConnectionInitializer { - private static final Logger LOG = LoggerFactory.getLogger(TcpConnectionInitializer.class); + private final SettableFuture hasRun = SettableFuture.create(); private final EventLoopGroup workerGroup; private final boolean isEpollEnabled; - private final SettableFuture hasRun = SettableFuture.create(); private TcpChannelInitializer channelInitializer; private Bootstrap bootstrap; @@ -53,27 +51,21 @@ public class TcpConnectionInitializer implements ServerFacade, ConnectionInitial } else { bootstrap.group(workerGroup).channel(NioSocketChannel.class).handler(channelInitializer); } - hasRun.set(true); + hasRun.set(null); } @Override public ListenableFuture shutdown() { - final SettableFuture result = SettableFuture.create(); + final var result = SettableFuture.create(); workerGroup.shutdownGracefully(); return result; } @Override - public ListenableFuture getIsOnlineFuture() { + public ListenableFuture getIsOnlineFuture() { return hasRun; } - @Override - @Deprecated(since = "0.17.2", forRemoval = true) - public void setThreadConfig(final ThreadConfiguration threadConfig) { - // IGNORE - } - @Override public void initiateConnection(final String host, final int port) { try { diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandler.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandler.java index 25789dcc1d..ca797a4d12 100644 --- a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandler.java +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandler.java @@ -48,13 +48,14 @@ public class TcpHandler implements ServerFacade { private static final Logger LOG = LoggerFactory.getLogger(TcpHandler.class); - private int port; - private String address; + private final SettableFuture isOnlineFuture = SettableFuture.create(); private final InetAddress startupAddress; private final Runnable readyRunnable; + + private int port; + private String address; private EventLoopGroup workerGroup; private EventLoopGroup bossGroup; - private final SettableFuture isOnlineFuture = SettableFuture.create(); private TcpChannelInitializer channelInitializer; @@ -136,7 +137,7 @@ public class TcpHandler implements ServerFacade { LOG.debug("address from tcphandler: {}", address); LOG.info("Switch listener started and ready to accept incoming tcp/tls connections on port: {}", port); readyRunnable.run(); - isOnlineFuture.set(true); + isOnlineFuture.set(null); // This waits until this channel is closed, and rethrows the cause of the failure if this future failed. f.channel().closeFuture().sync(); @@ -174,7 +175,7 @@ public class TcpHandler implements ServerFacade { } @Override - public ListenableFuture getIsOnlineFuture() { + public ListenableFuture getIsOnlineFuture() { return isOnlineFuture; } @@ -190,12 +191,6 @@ public class TcpHandler implements ServerFacade { this.channelInitializer = channelInitializer; } - @Override - @Deprecated(since = "0.17.2", forRemoval = true) - public void setThreadConfig(final ThreadConfiguration threadConfig) { - // No-op - } - /** * Initiate event loop groups. * diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpHandler.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpHandler.java index f4ad4b2e4a..1c59efd7cd 100644 --- a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpHandler.java +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/core/UdpHandler.java @@ -31,15 +31,14 @@ import org.slf4j.LoggerFactory; * @author michal.polkorab */ public final class UdpHandler implements ServerFacade { - private static final Logger LOG = LoggerFactory.getLogger(UdpHandler.class); - private int port; - private EventLoopGroup group; + private final SettableFuture isOnlineFuture = SettableFuture.create(); private final InetAddress startupAddress; private final Runnable readyRunnable; - private final SettableFuture isOnlineFuture = SettableFuture.create(); + private int port; + private EventLoopGroup group; private UdpChannelInitializer channelInitializer; private Class datagramChannelClass; @@ -96,7 +95,7 @@ public final class UdpHandler implements ServerFacade { LOG.debug("Address from udpHandler: {}", address); LOG.info("Switch listener started and ready to accept incoming udp connections on port: {}", port); readyRunnable.run(); - isOnlineFuture.set(true); + isOnlineFuture.set(null); // This waits until this channel is closed, and rethrows the cause of the failure if this future failed. f.channel().closeFuture().sync(); @@ -120,7 +119,7 @@ public final class UdpHandler implements ServerFacade { } @Override - public ListenableFuture getIsOnlineFuture() { + public ListenableFuture getIsOnlineFuture() { return isOnlineFuture; } @@ -132,12 +131,6 @@ public final class UdpHandler implements ServerFacade { this.channelInitializer = channelInitializer; } - @Override - @Deprecated(since = "0.17.2", forRemoval = true) - public void setThreadConfig(final ThreadConfiguration threadConfig) { - // No-op - } - /** * Initiate event loop groups. * diff --git a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/QueueGetConfigReplyMessageFactory.java b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/QueueGetConfigReplyMessageFactory.java index b0f15f0472..372a02ff2d 100644 --- a/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/QueueGetConfigReplyMessageFactory.java +++ b/openflowjava/openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories/QueueGetConfigReplyMessageFactory.java @@ -80,7 +80,7 @@ public class QueueGetConfigReplyMessageFactory implements OFDeserializer propertiesList = new ArrayList<>(); while (propertiesLength > 0) { - int propertyStartIndex = input.readerIndex(); + final int propertyStartIndex = input.readerIndex(); QueuePropertyBuilder propertiesBuilder = new QueuePropertyBuilder(); QueueProperties property = QueueProperties.forValue(input.readUnsignedShort()); propertiesBuilder.setProperty(property); diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandlerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandlerTest.java index a767bfa8c0..700b376f20 100644 --- a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandlerTest.java +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/TcpHandlerTest.java @@ -146,14 +146,12 @@ public class TcpHandlerTest { int serverPort = 28001; Socket firstBinder = new Socket(); - try { + try (firstBinder) { firstBinder.bind(new InetSocketAddress(serverAddress, serverPort)); tcpHandler = new TcpHandler(serverAddress, serverPort, () -> { }); tcpHandler.setChannelInitializer(mockChannelInitializer); tcpHandler.initiateEventLoopGroups(null, false); tcpHandler.run(); - } finally { - firstBinder.close(); } } @@ -165,7 +163,7 @@ public class TcpHandlerTest { int serverPort = 28001; Socket firstBinder = new Socket(); - try { + try (firstBinder) { firstBinder.bind(new InetSocketAddress(serverAddress, serverPort)); tcpHandler = new TcpHandler(serverAddress, serverPort, () -> { }); @@ -176,8 +174,6 @@ public class TcpHandlerTest { fail("Expected BindException or Errors.NativeIoException"); } catch (BindException | Errors.NativeIoException e) { // expected - } finally { - firstBinder.close(); } } @@ -192,8 +188,8 @@ public class TcpHandlerTest { assertEquals("shutdown failed", true, shutdownRet.get()); } - private Boolean startupServer(boolean isEpollEnabled) throws InterruptedException { - ListenableFuture online = tcpHandler.getIsOnlineFuture(); + private Boolean startupServer(final boolean isEpollEnabled) throws InterruptedException { + final var online = tcpHandler.getIsOnlineFuture(); /** * Test EPoll based native transport if isEpollEnabled is true. * Else use Nio based transport. @@ -204,10 +200,10 @@ public class TcpHandlerTest { while (online.isDone() != true && retry++ < 20) { Thread.sleep(100); } - return online.isDone() ; + return online.isDone(); } - private static Boolean clientConnection(int port) throws IOException { + private static Boolean clientConnection(final int port) throws IOException { // Connect, and disconnect Socket socket = new Socket(InetAddress.getLoopbackAddress(), port); Boolean result = socket.isConnected(); diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImpl02Test.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImpl02Test.java index 035efd39ab..a2b0daa166 100755 --- a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImpl02Test.java +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImpl02Test.java @@ -7,7 +7,9 @@ */ package org.opendaylight.openflowjava.protocol.impl.core.connection; -import com.google.common.util.concurrent.ListenableFuture; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + import java.net.InetAddress; import java.net.UnknownHostException; import java.util.List; @@ -36,7 +38,6 @@ import org.opendaylight.openflowjava.protocol.api.keys.MatchEntrySerializerKey; import org.opendaylight.openflowjava.protocol.api.keys.MessageCodeKey; import org.opendaylight.openflowjava.protocol.api.keys.MessageTypeKey; import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants; -import org.opendaylight.openflowjava.protocol.impl.core.ServerFacade; import org.opendaylight.openflowjava.protocol.impl.core.SwitchConnectionProviderImpl; import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.ExperimenterActionSubType; @@ -115,9 +116,9 @@ public class SwitchConnectionProviderImpl02Test { @Test public void testServerFacade() throws UnknownHostException { startUp(TransportProtocol.TCP); - final ListenableFuture future = provider.startup(); - final ServerFacade serverFacade = provider.getServerFacade(); - Assert.assertNotNull("Wrong -- getServerFacade return null",serverFacade); + final var future = provider.startup(); + final var serverFacade = provider.getServerFacade(); + assertNotNull("Wrong -- getServerFacade return null", serverFacade); } /** @@ -135,12 +136,10 @@ public class SwitchConnectionProviderImpl02Test { @Test public void testUnregisterWrongKeys() throws UnknownHostException { startUp(TransportProtocol.TCP); - final ExperimenterInstructionSerializerKey testSerKey - = new ExperimenterInstructionSerializerKey(EncodeConstants.OF_VERSION_1_0, 42L); - Assert.assertFalse("Wrong -- unregisterSerializer",provider.unregisterSerializer(testSerKey)); - final ExperimenterInstructionDeserializerKey tesDeserKey - = new ExperimenterInstructionDeserializerKey(EncodeConstants.OF_VERSION_1_0, 24L); - Assert.assertFalse("Wrong -- unregisterDeserializer",provider.unregisterDeserializer(tesDeserKey)); + final var testSerKey = new ExperimenterInstructionSerializerKey(EncodeConstants.OF_VERSION_1_0, 42L); + assertFalse("Wrong -- unregisterSerializer",provider.unregisterSerializer(testSerKey)); + final var tesDeserKey = new ExperimenterInstructionDeserializerKey(EncodeConstants.OF_VERSION_1_0, 24L); + assertFalse("Wrong -- unregisterDeserializer",provider.unregisterDeserializer(tesDeserKey)); } /** diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImplTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImplTest.java index 972970603a..f5fbe8bf36 100644 --- a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImplTest.java +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/SwitchConnectionProviderImplTest.java @@ -16,7 +16,6 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; -import com.google.common.util.concurrent.ListenableFuture; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.List; @@ -94,7 +93,7 @@ public class SwitchConnectionProviderImplTest { @Test public void testStartup1() throws UnknownHostException { startUp(null); - final ListenableFuture future = provider.startup(); + final var future = provider.startup(); final var cause = assertThrows(ExecutionException.class, () -> future.get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) .getCause(); @@ -109,7 +108,7 @@ public class SwitchConnectionProviderImplTest { public void testStartup2() throws UnknownHostException { startUp(null); provider.setSwitchConnectionHandler(handler); - final ListenableFuture future = provider.startup(); + final var future = provider.startup(); final var cause = assertThrows(ExecutionException.class, () -> future.get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) .getCause(); @@ -123,7 +122,7 @@ public class SwitchConnectionProviderImplTest { @Test public void testStartup3() throws UnknownHostException { startUp(TransportProtocol.TCP); - final ListenableFuture future = provider.startup(); + final var future = provider.startup(); final var cause = assertThrows(ExecutionException.class, () -> future.get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)) .getCause(); @@ -139,7 +138,7 @@ public class SwitchConnectionProviderImplTest { startUp(TransportProtocol.TCP); provider.setSwitchConnectionHandler(handler); - assertTrue("Failed to start", provider.startup().get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)); + provider.startup().get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS); } /** @@ -150,7 +149,7 @@ public class SwitchConnectionProviderImplTest { startUp(TransportProtocol.TLS); provider.setSwitchConnectionHandler(handler); - assertTrue("Failed to start", provider.startup().get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)); + provider.startup().get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS); } /** @@ -161,7 +160,7 @@ public class SwitchConnectionProviderImplTest { startUp(TransportProtocol.UDP); provider.setSwitchConnectionHandler(handler); - assertTrue("Failed to start", provider.startup().get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)); + provider.startup().get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS); } /** @@ -172,7 +171,7 @@ public class SwitchConnectionProviderImplTest { startUp(TransportProtocol.TCP); provider.setSwitchConnectionHandler(handler); - assertTrue("Failed to start", provider.startup().get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS)); + provider.startup().get(WAIT_TIMEOUT, TimeUnit.MILLISECONDS); assertTrue("Failed to stop", provider.shutdown().get(5 * WAIT_TIMEOUT, TimeUnit.MILLISECONDS)); } } diff --git a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpHandlerTest.java b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpHandlerTest.java index 871e2adf6a..cb2e53fb8c 100644 --- a/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpHandlerTest.java +++ b/openflowjava/openflow-protocol-impl/src/test/java/org/opendaylight/openflowjava/protocol/impl/core/connection/UdpHandlerTest.java @@ -7,12 +7,14 @@ */ package org.opendaylight.openflowjava.protocol.impl.core.connection; -import com.google.common.util.concurrent.ListenableFuture; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + import java.net.InetAddress; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -43,13 +45,9 @@ public class UdpHandlerTest { public void testWithEmptyAddress() throws Exception { udpHandler = new UdpHandler(null, 0, () -> { }); udpHandler.setChannelInitializer(udpChannelInitializerMock); - Assert.assertTrue("Wrong - start server", startupServer(false)); - try { - Assert.assertTrue(udpHandler.getIsOnlineFuture().get(1500, TimeUnit.MILLISECONDS)); - } catch (TimeoutException e) { - Assert.fail("Wrong - getIsOnlineFuture timed out"); - } - Assert.assertFalse("Wrong - port has been set to zero", udpHandler.getPort() == 0); + assertTrue("Wrong - start server", startupServer(false)); + udpHandler.getIsOnlineFuture().get(1500, TimeUnit.MILLISECONDS); + assertFalse("Wrong - port has been set to zero", udpHandler.getPort() == 0); shutdownServer(); } @@ -60,13 +58,9 @@ public class UdpHandlerTest { public void testWithEmptyAddressOnEpoll() throws Exception { udpHandler = new UdpHandler(null, 0, () -> { }); udpHandler.setChannelInitializer(udpChannelInitializerMock); - Assert.assertTrue("Wrong - start server", startupServer(true)); - try { - Assert.assertTrue(udpHandler.getIsOnlineFuture().get(1500,TimeUnit.MILLISECONDS)); - } catch (TimeoutException e) { - Assert.fail("Wrong - getIsOnlineFuture timed out"); - } - Assert.assertFalse("Wrong - port has been set to zero", udpHandler.getPort() == 0); + assertTrue("Wrong - start server", startupServer(true)); + udpHandler.getIsOnlineFuture().get(1500,TimeUnit.MILLISECONDS); + assertFalse("Wrong - port has been set to zero", udpHandler.getPort() == 0); shutdownServer(); } @@ -78,13 +72,9 @@ public class UdpHandlerTest { int port = 9874; udpHandler = new UdpHandler(InetAddress.getLocalHost(), port, () -> { }); udpHandler.setChannelInitializer(udpChannelInitializerMock); - Assert.assertTrue("Wrong - start server", startupServer(false)); - try { - Assert.assertTrue(udpHandler.getIsOnlineFuture().get(1500,TimeUnit.MILLISECONDS)); - } catch (TimeoutException e) { - Assert.fail("Wrong - getIsOnlineFuture timed out"); - } - Assert.assertEquals("Wrong - bad port number has been set", port, udpHandler.getPort()); + assertTrue("Wrong - start server", startupServer(false)); + udpHandler.getIsOnlineFuture().get(1500,TimeUnit.MILLISECONDS); + assertEquals("Wrong - bad port number has been set", port, udpHandler.getPort()); shutdownServer(); } @@ -96,19 +86,15 @@ public class UdpHandlerTest { int port = 9874; udpHandler = new UdpHandler(InetAddress.getLocalHost(), port, () -> { }); udpHandler.setChannelInitializer(udpChannelInitializerMock); - Assert.assertTrue("Wrong - start server", startupServer(true)); - try { - Assert.assertTrue(udpHandler.getIsOnlineFuture().get(1500,TimeUnit.MILLISECONDS)); - } catch (TimeoutException e) { - Assert.fail("Wrong - getIsOnlineFuture timed out"); - } - Assert.assertEquals("Wrong - bad port number has been set", port, udpHandler.getPort()); + assertTrue("Wrong - start server", startupServer(true)); + udpHandler.getIsOnlineFuture().get(1500,TimeUnit.MILLISECONDS); + assertEquals("Wrong - bad port number has been set", port, udpHandler.getPort()); shutdownServer(); } private Boolean startupServer(final boolean isEpollEnabled) throws InterruptedException, ExecutionException { - ListenableFuture online = udpHandler.getIsOnlineFuture(); + final var online = udpHandler.getIsOnlineFuture(); /** * Test EPoll based native transport if isEpollEnabled is true. * Else use Nio based transport. @@ -126,8 +112,7 @@ public class UdpHandlerTest { } private void shutdownServer() throws InterruptedException, ExecutionException, TimeoutException { - ListenableFuture shutdownRet = udpHandler.shutdown() ; - final Boolean shutdownSucceeded = shutdownRet.get(10, TimeUnit.SECONDS); - Assert.assertTrue("Wrong - shutdown failed", shutdownSucceeded); + final var shutdownRet = udpHandler.shutdown() ; + assertTrue("Wrong - shutdown failed", shutdownRet.get(10, TimeUnit.SECONDS)); } } diff --git a/openflowjava/openflow-protocol-spi/pom.xml b/openflowjava/openflow-protocol-spi/pom.xml index 0581548ed6..160b5ad59c 100644 --- a/openflowjava/openflow-protocol-spi/pom.xml +++ b/openflowjava/openflow-protocol-spi/pom.xml @@ -15,28 +15,32 @@ ODL :: openflowjava :: ${project.artifactId} https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main - HEAD - - - - - - org.apache.felix - maven-bundle-plugin - true - - - org.opendaylight.openflowjava.protocol.api.keys,* - - - - - + HEAD + ${project.groupId} openflow-protocol-api + + org.opendaylight.mdsal.binding.model.ietf + rfc6991-ietf-inet-types + + + + + + org.apache.felix + maven-bundle-plugin + true + + + org.opendaylight.openflowjava.protocol.api.keys,* + + + + + diff --git a/openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProvider.java b/openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProvider.java index f63e21c9e8..cab8051c16 100644 --- a/openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProvider.java +++ b/openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProvider.java @@ -33,9 +33,9 @@ public interface SwitchConnectionProvider extends AutoCloseable, * Start listening to switches, but please don't forget to do * {@link #setSwitchConnectionHandler(SwitchConnectionHandler)} first. * - * @return future, triggered to true, when listening channel is up and running + * @return future completing when the channel has been resolved */ - ListenableFuture startup(); + ListenableFuture startup(); /** * Stop listening to switches. diff --git a/openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProviderList.java b/openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProviderList.java deleted file mode 100644 index da8bf0c21a..0000000000 --- a/openflowjava/openflow-protocol-spi/src/main/java/org/opendaylight/openflowjava/protocol/spi/connection/SwitchConnectionProviderList.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2018 Red Hat, 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.openflowjava.protocol.spi.connection; - -import com.google.common.collect.ForwardingList; -import java.util.List; - -/** - * {@link List} of {@link SwitchConnectionProvider}. - * This is useful for strongly typed dependency injection, - * and makes it simpler to have a common single source of truth - * between Blueprint and other DI frameworks in a standalone environment. - * - * @author Michael Vorburger.ch - */ -public class SwitchConnectionProviderList extends ForwardingList { - - private final List switchConnectionProviders; - - public SwitchConnectionProviderList(List switchConnectionProviders) { - this.switchConnectionProviders = switchConnectionProviders; - } - - @Override - protected List delegate() { - return switchConnectionProviders; - } -} diff --git a/openflowjava/openflowjava-blueprint-config/pom.xml b/openflowjava/openflowjava-blueprint-config/pom.xml index 7ac8fe153a..cf18698419 100644 --- a/openflowjava/openflowjava-blueprint-config/pom.xml +++ b/openflowjava/openflowjava-blueprint-config/pom.xml @@ -23,18 +23,64 @@ https://wiki.opendaylight.org/view/Openflow_Protocol_Library:Main HEAD + + + + com.google.guava + guava + + + org.eclipse.jdt + org.eclipse.jdt.annotation + + + org.opendaylight.mdsal + mdsal-binding-api + + + org.opendaylight.mdsal + mdsal-common-api + + + org.opendaylight.mdsal + yang-binding + + + org.opendaylight.openflowplugin.openflowjava + openflow-protocol-api + + + org.opendaylight.openflowplugin.openflowjava + openflow-protocol-impl + + + org.opendaylight.openflowplugin.openflowjava + openflow-protocol-spi + + + org.opendaylight.yangtools + concepts + + + org.opendaylight.yangtools + yang-common + + + org.osgi + org.osgi.framework + + + org.osgi + org.osgi.service.component + + + org.osgi + org.osgi.service.component.annotations + + + - - org.apache.felix - maven-bundle-plugin - true - - - * - - - org.codehaus.mojo build-helper-maven-plugin diff --git a/openflowjava/openflowjava-blueprint-config/src/main/java/org/opendaylight/openflowjava/mdsal/OSGiFactorySwitchConnectionConfiguration.java b/openflowjava/openflowjava-blueprint-config/src/main/java/org/opendaylight/openflowjava/mdsal/OSGiFactorySwitchConnectionConfiguration.java new file mode 100644 index 0000000000..e567365096 --- /dev/null +++ b/openflowjava/openflowjava-blueprint-config/src/main/java/org/opendaylight/openflowjava/mdsal/OSGiFactorySwitchConnectionConfiguration.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2024 PANTHEON.tech, s.r.o. 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.openflowjava.mdsal; + +import com.google.common.base.Stopwatch; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.MoreExecutors; +import java.util.List; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.common.api.CommitInfo; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.KeystoreType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.PathType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.config.rev140630.TransportProtocol; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.config.rev160506.SwitchConnectionConfig; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.config.rev160506.SwitchConnectionConfigBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.config.rev160506._switch.connection.config.TlsBuilder; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.Uint16; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A component responsible for populating default (factory) configuration. + */ +@Component(service = { }) +public final class OSGiFactorySwitchConnectionConfiguration { + private static final Logger LOG = LoggerFactory.getLogger(OSGiFactorySwitchConnectionConfiguration.class); + + @Activate + public OSGiFactorySwitchConnectionConfiguration(@Reference final DataBroker dataBroker) { + // Common for both cases + final var builder = new SwitchConnectionConfigBuilder() + .setTransportProtocol(TransportProtocol.TCP) + .setGroupAddModEnabled(Boolean.FALSE) + .setChannelOutboundQueueSize(Uint16.valueOf(1024)) + .setTls(new TlsBuilder() + .setKeystore("configuration/ssl/ctl.jks") + .setKeystoreType(KeystoreType.JKS) + .setKeystorePathType(PathType.PATH) + .setKeystorePassword("opendaylight") + .setTruststore("configuration/ssl/truststore.jks") + .setTruststoreType(KeystoreType.JKS) + .setTruststorePathType(PathType.PATH) + .setTruststorePassword("opendaylight") + .setCertificatePassword("opendaylight") + .setCipherSuites(List.of()) + .build()); + + // Create OF switch connection provider on port 6653 (default) + writeIfNotPresent(dataBroker, builder + .setInstanceName("openflow-switch-connection-provider-default-impl") + .setPort(Uint16.valueOf(6653)) + .build()); + // Create OF switch connection provider on port 6633 (legacy) + writeIfNotPresent(dataBroker, builder + .setInstanceName("openflow-switch-connection-provider-legacy-impl") + .setPort(Uint16.valueOf(6633)) + .build()); + } + + private static void writeIfNotPresent(final DataBroker dataBroker, final SwitchConnectionConfig config) { + final var instanceName = config.getInstanceName(); + LOG.info("Checking presence of configuration for {}", instanceName); + + final var sw = Stopwatch.createStarted(); + final var iid = InstanceIdentifier.builder(SwitchConnectionConfig.class, config.key()).build(); + final var tx = dataBroker.newReadWriteTransaction(); + tx.exists(LogicalDatastoreType.CONFIGURATION, iid).addCallback(new FutureCallback() { + @Override + public void onSuccess(final Boolean result) { + LOG.debug("Presence of configuration for {} ascertained in {}", instanceName, sw); + if (result) { + LOG.info("Configuration for {} already present", instanceName); + tx.cancel(); + return; + } + + tx.put(LogicalDatastoreType.CONFIGURATION, iid, config); + tx.commit().addCallback(new FutureCallback() { + @Override + public void onSuccess(final CommitInfo result) { + LOG.info("Configuration for {} set to factory-default", instanceName); + } + + @Override + public void onFailure(final Throwable cause) { + LOG.warn("Failed to set configuration for {} set to factory-default", instanceName, cause); + } + }, MoreExecutors.directExecutor()); + } + + @Override + public void onFailure(final Throwable cause) { + LOG.warn("Failed to ascertain presence of configuration for {} after {}", instanceName, sw, cause); + tx.cancel(); + } + }, MoreExecutors.directExecutor()); + } +} diff --git a/openflowjava/openflowjava-blueprint-config/src/main/java/org/opendaylight/openflowjava/mdsal/OSGiSwitchConnectionProviders.java b/openflowjava/openflowjava-blueprint-config/src/main/java/org/opendaylight/openflowjava/mdsal/OSGiSwitchConnectionProviders.java new file mode 100644 index 0000000000..4d77533923 --- /dev/null +++ b/openflowjava/openflowjava-blueprint-config/src/main/java/org/opendaylight/openflowjava/mdsal/OSGiSwitchConnectionProviders.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2024 PANTHEON.tech, s.r.o. 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.openflowjava.mdsal; + +import static java.util.Objects.requireNonNull; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.binding.api.DataTreeChangeListener; +import org.opendaylight.mdsal.binding.api.DataTreeIdentifier; +import org.opendaylight.mdsal.binding.api.DataTreeModification; +import org.opendaylight.mdsal.common.api.LogicalDatastoreType; +import org.opendaylight.openflowjava.protocol.impl.core.SwitchConnectionProviderImpl; +import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow._switch.connection.config.rev160506.SwitchConnectionConfig; +import org.opendaylight.yangtools.concepts.Registration; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.osgi.framework.FrameworkUtil; +import org.osgi.service.component.ComponentFactory; +import org.osgi.service.component.ComponentInstance; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A component exposing {@link SwitchConnectionProvider} into OSGi service registry based on MD-SAL's configuration + * data store contents of {@link SwitchConnectionConfig}. + */ +@Component(service = { }) +public final class OSGiSwitchConnectionProviders implements DataTreeChangeListener { + private static final Logger LOG = LoggerFactory.getLogger(OSGiSwitchConnectionProviders.class); + + private final Map> instances = new HashMap<>(); + private final ComponentFactory providerFactory; + private final Registration reg; + + @Activate + public OSGiSwitchConnectionProviders(@Reference final DataBroker dataBroker, + @Reference(target = "(component.factory=" + SwitchConnectionProviderImpl.FACTORY_NAME + ")") + final ComponentFactory providerFactory) { + this.providerFactory = requireNonNull(providerFactory); + reg = dataBroker.registerTreeChangeListener(DataTreeIdentifier.of(LogicalDatastoreType.CONFIGURATION, + InstanceIdentifier.create(SwitchConnectionConfig.class)), this); + LOG.info("MD-SAL configuration-based SwitchConnectionProviders started"); + } + + @Deactivate + synchronized void deactivate() { + LOG.info("MD-SAL configuration-based SwitchConnectionProviders stopping"); + reg.close(); + instances.forEach((key, instance) -> instance.dispose()); + instances.clear(); + LOG.info("MD-SAL configuration-based SwitchConnectionProviders stopped"); + } + + @Override + public synchronized void onDataTreeChanged(final List> changes) { + final var apply = new HashMap(); + + for (var change : changes) { + final var root = change.getRootNode(); + switch (root.modificationType()) { + case DELETE -> apply.put(root.dataBefore().getInstanceName(), null); + case SUBTREE_MODIFIED, WRITE -> { + final var after = root.dataAfter(); + apply.put(after.getInstanceName(), after); + } + default -> LOG.warn("Ignoring unhandled root {}", root); + } + } + + LOG.debug("Applying {} changes", apply.size()); + apply.entrySet().stream() + .sorted(Comparator.comparing(Entry::getKey)) + .forEach(entry -> { + final var type = entry.getKey(); + final var prev = instances.remove(type); + if (prev != null) { + LOG.info("Stopping instance of type '{}'", type); + prev.dispose(); + } + + final var config = entry.getValue(); + if (config != null) { + LOG.info("Starting instance of type '{}'", type); + instances.put(type, providerFactory.newInstance(FrameworkUtil.asDictionary(props(type, config)))); + } + }); + } + + @Override + public void onInitialData() { + LOG.debug("No configuration is present"); + } + + private static Map props(final String type, final @Nullable SwitchConnectionConfig config) { + return config != null ? Map.of("type", type, SwitchConnectionProviderImpl.PROP_CONFIG, config) + : Map.of("type", type); + } +} diff --git a/openflowjava/openflowjava-blueprint-config/src/main/resources/OSGI-INF/blueprint/openflowjava.xml b/openflowjava/openflowjava-blueprint-config/src/main/resources/OSGI-INF/blueprint/openflowjava.xml deleted file mode 100644 index 146faabec6..0000000000 --- a/openflowjava/openflowjava-blueprint-config/src/main/resources/OSGI-INF/blueprint/openflowjava.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/openflowjava/openflowjava-util/pom.xml b/openflowjava/openflowjava-util/pom.xml index 2e3e6423da..0d54aaee9e 100644 --- a/openflowjava/openflowjava-util/pom.xml +++ b/openflowjava/openflowjava-util/pom.xml @@ -15,14 +15,29 @@ ODL :: openflowjava :: ${project.artifactId} - - junit - junit - test - ${project.groupId} openflow-protocol-api + + com.google.guava + guava + + + io.netty + netty-buffer + + + org.opendaylight.mdsal.binding.model.ietf + rfc6991-ietf-inet-types + + + org.opendaylight.mdsal.binding.model.ietf + rfc6991-ietf-yang-types + + + org.opendaylight.yangtools + yang-common + diff --git a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginProvider.java b/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginProvider.java deleted file mode 100644 index 94519348f9..0000000000 --- a/openflowplugin-api/src/main/java/org/opendaylight/openflowplugin/api/openflow/OpenFlowPluginProvider.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2015, 2017 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.openflowplugin.api.openflow; - -import org.opendaylight.mdsal.binding.api.BindingService; - -/** - * Plugin services provider. - */ -public interface OpenFlowPluginProvider extends AutoCloseable, BindingService { - - /** - * Method initializes all DeviceManager, RpcManager and related contexts. - */ - void initialize(); - -} diff --git a/openflowplugin-impl/pom.xml b/openflowplugin-impl/pom.xml index 15ff57784e..5055d89438 100644 --- a/openflowplugin-impl/pom.xml +++ b/openflowplugin-impl/pom.xml @@ -13,12 +13,32 @@ - org.osgi - org.osgi.framework + com.github.spotbugs + spotbugs-annotations + true - org.osgi - org.osgi.service.cm + com.google.guava + guava + + + com.guicedee.services + javax.inject + true + + + jakarta.annotation + jakarta.annotation-api + true + + + org.apache.commons + commons-lang3 + + + org.apache.karaf.shell + org.apache.karaf.shell.core + provided org.opendaylight.openflowplugin @@ -32,6 +52,10 @@ org.opendaylight.openflowplugin openflowplugin-extension-api + + org.opendaylight.openflowplugin + openflowplugin-common + org.opendaylight.openflowplugin.model model-flow-base @@ -73,54 +97,25 @@ openflow-protocol-spi - org.apache.karaf.shell - org.apache.karaf.shell.console - provided - - - com.google.guava - guava - - - org.apache.commons - commons-lang3 + ${project.groupId}.openflowjava + openflowjava-util - jakarta.annotation - jakarta.annotation-api - true + ${project.groupId}.openflowjava + openflow-protocol-impl - com.github.spotbugs - spotbugs-annotations - true + org.osgi + org.osgi.framework - com.guicedee.services - javax.inject - true + org.osgi + org.osgi.service.cm org.osgi org.osgi.service.component.annotations - - org.slf4j - slf4j-simple - test - - - ${project.groupId}.openflowjava - openflowjava-util - - - ${project.groupId}.openflowjava - openflow-protocol-impl - - - org.opendaylight.openflowplugin - openflowplugin-common - @@ -129,6 +124,22 @@ org.apache.felix maven-bundle-plugin true + + + org.opendaylight.openflowplugin.impl.karaf + + + osgi.service;objectClass:List<String>="org.opendaylight.openflowplugin.api.openflow.FlowGroupCacheManager";uses:="org.opendaylight.openflowplugin.api.openflow", + osgi.service;objectClass:List<String>="org.opendaylight.openflowplugin.api.openflow.FlowGroupInfoHistories,org.opendaylight.openflowplugin.extension.api.OpenFlowPluginExtensionRegistratorProvider";uses:="org.opendaylight.openflowplugin.api.openflow,org.opendaylight.openflowplugin.extension.api", + osgi.service;objectClass:List<String>="org.opendaylight.openflowplugin.api.openflow.configuration.ConfigurationServiceFactory";uses:="org.opendaylight.openflowplugin.api.openflow.configuration", + osgi.service;objectClass:List<String>="org.opendaylight.openflowplugin.api.openflow.mastership.MastershipChangeServiceManager";uses:="org.opendaylight.openflowplugin.api.openflow.mastership", + osgi.service;objectClass:List<String>="org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency";uses:="org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific", + osgi.service;objectClass:List<String>="org.opendaylight.openflowplugin.impl.DiagStatusProvider";uses:="org.opendaylight.openflowplugin.impl", + + osgi.service;objectClass:List<String>="org.opendaylight.openflowplugin.api.openflow.configuration.ConfigurationService";uses:="org.opendaylight.openflowplugin.api.openflow.configuration" + + + diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/ForwardingPingPongDataBroker.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/ForwardingPingPongDataBroker.java deleted file mode 100644 index e6e30a0bc3..0000000000 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/ForwardingPingPongDataBroker.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2018 Red Hat, 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.openflowplugin.impl; - -import static java.util.Objects.requireNonNull; - -import org.eclipse.jdt.annotation.NonNull; -import org.opendaylight.mdsal.binding.api.DataBroker; -import org.opendaylight.mdsal.binding.api.TransactionChain; -import org.opendaylight.mdsal.binding.spi.ForwardingDataBroker; - -/** - * Delegating {@link PingPongDataBroker} implementation. - * This is useful for simple strongly typed dependency injection. - * - * @author Michael Vorburger.ch - */ -// FIXME: this should not be necessary -public class ForwardingPingPongDataBroker extends ForwardingDataBroker implements PingPongDataBroker { - private final @NonNull DataBroker delegate; - - public ForwardingPingPongDataBroker(final DataBroker delegate) { - this.delegate = requireNonNull(delegate); - } - - @Override - protected DataBroker delegate() { - return delegate; - } - - @Override - public TransactionChain createTransactionChain() { - return delegate().createMergingTransactionChain(); - } -} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java index f5b4afd14b..b841e72c82 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImpl.java @@ -7,6 +7,8 @@ */ package org.opendaylight.openflowplugin.impl; +import static java.util.Objects.requireNonNull; + import com.google.common.annotations.VisibleForTesting; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; @@ -15,8 +17,6 @@ import com.google.common.util.concurrent.MoreExecutors; import com.google.common.util.concurrent.SettableFuture; import io.netty.util.HashedWheelTimer; import io.netty.util.Timer; -import java.lang.management.ManagementFactory; -import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutionException; @@ -26,17 +26,9 @@ import java.util.concurrent.SynchronousQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; -import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.inject.Inject; import javax.inject.Singleton; -import javax.management.InstanceAlreadyExistsException; -import javax.management.InstanceNotFoundException; -import javax.management.MBeanRegistrationException; -import javax.management.MBeanServer; -import javax.management.MalformedObjectNameException; -import javax.management.NotCompliantMBeanException; -import javax.management.ObjectName; import org.opendaylight.infrautils.diagstatus.ServiceState; import org.opendaylight.infrautils.ready.SystemReadyListener; import org.opendaylight.infrautils.ready.SystemReadyMonitor; @@ -46,10 +38,8 @@ import org.opendaylight.mdsal.binding.api.RpcProviderService; import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService; import org.opendaylight.mdsal.singleton.api.ClusterSingletonServiceProvider; import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider; -import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProviderList; import org.opendaylight.openflowplugin.api.openflow.FlowGroupInfoHistories; import org.opendaylight.openflowplugin.api.openflow.FlowGroupInfoHistory; -import org.opendaylight.openflowplugin.api.openflow.OpenFlowPluginProvider; import org.opendaylight.openflowplugin.api.openflow.configuration.ConfigurationService; import org.opendaylight.openflowplugin.api.openflow.connection.ConnectionManager; import org.opendaylight.openflowplugin.api.openflow.device.DeviceManager; @@ -58,7 +48,6 @@ import org.opendaylight.openflowplugin.api.openflow.role.RoleManager; import org.opendaylight.openflowplugin.api.openflow.rpc.RpcManager; import org.opendaylight.openflowplugin.api.openflow.statistics.StatisticsManager; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency; -import org.opendaylight.openflowplugin.extension.api.ExtensionConverterProviderKeeper; import org.opendaylight.openflowplugin.extension.api.ExtensionConverterRegistrator; import org.opendaylight.openflowplugin.extension.api.OpenFlowPluginExtensionRegistratorProvider; import org.opendaylight.openflowplugin.extension.api.core.extension.ExtensionConverterManager; @@ -73,8 +62,6 @@ import org.opendaylight.openflowplugin.impl.protocol.serialization.SerializerInj import org.opendaylight.openflowplugin.impl.role.RoleManagerImpl; import org.opendaylight.openflowplugin.impl.rpc.RpcManagerImpl; import org.opendaylight.openflowplugin.impl.statistics.StatisticsManagerImpl; -import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.MessageIntelligenceAgencyImpl; -import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.MessageIntelligenceAgencyMXBean; import org.opendaylight.openflowplugin.impl.util.ThreadPoolLoggingExecutor; import org.opendaylight.openflowplugin.impl.util.TranslatorLibraryUtil; import org.opendaylight.openflowplugin.openflow.md.core.extension.ExtensionConverterManagerImpl; @@ -83,81 +70,133 @@ import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorM import org.opendaylight.openflowplugin.openflow.md.core.session.OFSessionUtil; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow.provider.config.rev160510.OpenflowProviderConfig; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicyOption; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Singleton -public class OpenFlowPluginProviderImpl implements - OpenFlowPluginProvider, - OpenFlowPluginExtensionRegistratorProvider, - FlowGroupInfoHistories, - SystemReadyListener { - +@Component(immediate = true, service = { + OpenFlowPluginExtensionRegistratorProvider.class, + FlowGroupInfoHistories.class +}) +public final class OpenFlowPluginProviderImpl + implements OpenFlowPluginExtensionRegistratorProvider, FlowGroupInfoHistories, SystemReadyListener, + AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(OpenFlowPluginProviderImpl.class); private static final int TICKS_PER_WHEEL = 500; // 0.5 sec. private static final long TICK_DURATION = 10; private static final String POOL_NAME = "ofppool"; - private static final MessageIntelligenceAgency MESSAGE_INTELLIGENCE_AGENCY = new MessageIntelligenceAgencyImpl(); - private static final String MESSAGE_INTELLIGENCE_AGENCY_MX_BEAN_NAME = String - .format("%s:type=%s", - MessageIntelligenceAgencyMXBean.class.getPackage().getName(), - MessageIntelligenceAgencyMXBean.class.getSimpleName()); - + // TODO: Split this out into a separate component, which requires proper timer cancellation from all users. But is + // that worth the complications? private final HashedWheelTimer hashedWheelTimer = new HashedWheelTimer(TICK_DURATION, TimeUnit.MILLISECONDS, TICKS_PER_WHEEL); - private final NotificationPublishService notificationPublishService; private final ExtensionConverterManager extensionConverterManager; - private final DataBroker dataBroker; - private final Collection switchConnectionProviders; + private final List switchConnectionProviders; private final DeviceInitializerProvider deviceInitializerProvider; private final ConvertorManager convertorManager; - private final RpcProviderService rpcProviderRegistry; - private final ClusterSingletonServiceProvider singletonServicesProvider; private final OpenflowProviderConfig config; - private final EntityOwnershipService entityOwnershipService; - private final MastershipChangeServiceManager mastershipChangeServiceManager; - private DeviceManager deviceManager; - private RpcManager rpcManager; - private StatisticsManager statisticsManager; - private RoleManager roleManager; - private ConnectionManager connectionManager; - private ExecutorService executorService; - private ContextChainHolderImpl contextChainHolder; + private final DeviceManager deviceManager; + private final RpcManager rpcManager; + private final StatisticsManager statisticsManager; + private final RoleManager roleManager; + private final ExecutorService executorService; + private final ContextChainHolderImpl contextChainHolder; private final DiagStatusProvider diagStatusProvider; - private final SystemReadyMonitor systemReadyMonitor; private final SettableFuture fullyStarted = SettableFuture.create(); - private static final String OPENFLOW_SERVICE_NAME = "OPENFLOW"; - public static MessageIntelligenceAgency getMessageIntelligenceAgency() { - return MESSAGE_INTELLIGENCE_AGENCY; - } + private ConnectionManager connectionManager; @Inject - public OpenFlowPluginProviderImpl(final ConfigurationService configurationService, - final SwitchConnectionProviderList switchConnectionProviders, - final PingPongDataBroker pingPongDataBroker, - final RpcProviderService rpcProviderRegistry, - final NotificationPublishService notificationPublishService, - final ClusterSingletonServiceProvider singletonServiceProvider, - final EntityOwnershipService entityOwnershipService, - final MastershipChangeServiceManager mastershipChangeServiceManager, - final DiagStatusProvider diagStatusProvider, - final SystemReadyMonitor systemReadyMonitor) { - this.switchConnectionProviders = switchConnectionProviders; - dataBroker = pingPongDataBroker; - this.rpcProviderRegistry = rpcProviderRegistry; - this.notificationPublishService = notificationPublishService; - singletonServicesProvider = singletonServiceProvider; - this.entityOwnershipService = entityOwnershipService; + @Activate + public OpenFlowPluginProviderImpl(@Reference final ConfigurationService configurationService, + @Reference(cardinality = ReferenceCardinality.AT_LEAST_ONE, policyOption = ReferencePolicyOption.GREEDY) + final List switchConnectionProviders, + @Reference final DataBroker dataBroker, @Reference final RpcProviderService rpcProviderRegistry, + @Reference final NotificationPublishService notificationPublishService, + @Reference final ClusterSingletonServiceProvider singletonServiceProvider, + @Reference final EntityOwnershipService entityOwnershipService, + @Reference final MastershipChangeServiceManager mastershipChangeServiceManager, + @Reference final MessageIntelligenceAgency messageIntelligenceAgency, + @Reference final DiagStatusProvider diagStatusProvider, + @Reference final SystemReadyMonitor systemReadyMonitor) { + config = new OpenFlowProviderConfigImpl(configurationService); + this.switchConnectionProviders = List.copyOf(switchConnectionProviders); + final var ppdb = new PingPongDataBroker(dataBroker); + this.diagStatusProvider = requireNonNull(diagStatusProvider); + convertorManager = ConvertorManagerFactory.createDefaultManager(); extensionConverterManager = new ExtensionConverterManagerImpl(); deviceInitializerProvider = DeviceInitializerProviderFactory.createDefaultProvider(); - config = new OpenFlowProviderConfigImpl(configurationService); - this.mastershipChangeServiceManager = mastershipChangeServiceManager; - this.diagStatusProvider = diagStatusProvider; - this.systemReadyMonitor = systemReadyMonitor; + + // TODO: copied from OpenFlowPluginProvider (Helium) misusesing the old way of distributing extension converters + // TODO: rewrite later! + OFSessionUtil.getSessionManager().setExtensionConverterProvider(extensionConverterManager); + + // Creates a thread pool that creates new threads as needed, but will reuse previously + // constructed threads when they are available. + // Threads that have not been used for x seconds are terminated and removed from the cache. + executorService = new ThreadPoolLoggingExecutor( + config.getThreadPoolMinThreads().toJava(), + config.getThreadPoolMaxThreads().getValue().toJava(), + config.getThreadPoolTimeout().toJava(), + TimeUnit.SECONDS, new SynchronousQueue<>(), POOL_NAME); + + final var devMgr = new DeviceManagerImpl( + config, + ppdb, + messageIntelligenceAgency, + notificationPublishService, + hashedWheelTimer, + convertorManager, + deviceInitializerProvider, + executorService); + deviceManager = devMgr; + + TranslatorLibraryUtil.injectBasicTranslatorLibrary(deviceManager, convertorManager); + devMgr.setExtensionConverterProvider(extensionConverterManager); + + rpcManager = new RpcManagerImpl( + config, + rpcProviderRegistry, + extensionConverterManager, + convertorManager, + notificationPublishService); + + statisticsManager = new StatisticsManagerImpl( + config, + rpcProviderRegistry, + convertorManager, + executorService); + + roleManager = new RoleManagerImpl(hashedWheelTimer, config, executorService); + + contextChainHolder = new ContextChainHolderImpl( + executorService, + singletonServiceProvider, + entityOwnershipService, + mastershipChangeServiceManager, + config); + + contextChainHolder.addManager(deviceManager); + contextChainHolder.addManager(statisticsManager); + contextChainHolder.addManager(rpcManager); + contextChainHolder.addManager(roleManager); + + connectionManager = new ConnectionManagerImpl(config, executorService, ppdb, notificationPublishService); + connectionManager.setDeviceConnectedHandler(contextChainHolder); + connectionManager.setDeviceDisconnectedHandler(contextChainHolder); + + deviceManager.setContextChainHolder(contextChainHolder); + deviceManager.initialize(); + systemReadyMonitor.registerListener(this); + LOG.info("registered onSystemBootReady() listener for OpenFlowPluginProvider"); } @Override @@ -176,9 +215,9 @@ public class OpenFlowPluginProviderImpl implements // Set handler of incoming connections and start switch connection provider switchConnectionProvider.setSwitchConnectionHandler(connectionManager); return switchConnectionProvider.startup(); - }).collect(Collectors.toSet())), new FutureCallback>() { + }).collect(Collectors.toSet())), new FutureCallback>() { @Override - public void onSuccess(final List result) { + public void onSuccess(final List result) { LOG.info("All switchConnectionProviders are up and running ({}).", result.size()); diagStatusProvider.reportStatus(ServiceState.OPERATIONAL); fullyStarted.set(null); @@ -225,74 +264,6 @@ public class OpenFlowPluginProviderImpl implements return listListenableFuture; } - @Override - @PostConstruct - public void initialize() { - registerMXBean(MESSAGE_INTELLIGENCE_AGENCY, MESSAGE_INTELLIGENCE_AGENCY_MX_BEAN_NAME); - - // TODO: copied from OpenFlowPluginProvider (Helium) misusesing the old way of distributing extension converters - // TODO: rewrite later! - OFSessionUtil.getSessionManager().setExtensionConverterProvider(extensionConverterManager); - - // Creates a thread pool that creates new threads as needed, but will reuse previously - // constructed threads when they are available. - // Threads that have not been used for x seconds are terminated and removed from the cache. - executorService = new ThreadPoolLoggingExecutor( - config.getThreadPoolMinThreads().toJava(), - config.getThreadPoolMaxThreads().getValue().toJava(), - config.getThreadPoolTimeout().toJava(), - TimeUnit.SECONDS, new SynchronousQueue<>(), POOL_NAME); - - deviceManager = new DeviceManagerImpl( - config, - dataBroker, - getMessageIntelligenceAgency(), - notificationPublishService, - hashedWheelTimer, - convertorManager, - deviceInitializerProvider, - executorService); - - TranslatorLibraryUtil.injectBasicTranslatorLibrary(deviceManager, convertorManager); - ((ExtensionConverterProviderKeeper) deviceManager).setExtensionConverterProvider(extensionConverterManager); - - rpcManager = new RpcManagerImpl( - config, - rpcProviderRegistry, - extensionConverterManager, - convertorManager, - notificationPublishService); - - statisticsManager = new StatisticsManagerImpl( - config, - rpcProviderRegistry, - convertorManager, - executorService); - - roleManager = new RoleManagerImpl(hashedWheelTimer, config, executorService); - - contextChainHolder = new ContextChainHolderImpl( - executorService, - singletonServicesProvider, - entityOwnershipService, - mastershipChangeServiceManager, - config); - - contextChainHolder.addManager(deviceManager); - contextChainHolder.addManager(statisticsManager); - contextChainHolder.addManager(rpcManager); - contextChainHolder.addManager(roleManager); - - connectionManager = new ConnectionManagerImpl(config, executorService, dataBroker, notificationPublishService); - connectionManager.setDeviceConnectedHandler(contextChainHolder); - connectionManager.setDeviceDisconnectedHandler(contextChainHolder); - - deviceManager.setContextChainHolder(contextChainHolder); - deviceManager.initialize(); - systemReadyMonitor.registerListener(this); - LOG.info("registered onSystemBootReady() listener for OpenFlowPluginProvider"); - } - @Override public ExtensionConverterRegistrator getExtensionConverterRegistrator() { return extensionConverterManager; @@ -310,6 +281,7 @@ public class OpenFlowPluginProviderImpl implements @Override @PreDestroy + @Deactivate @SuppressWarnings("checkstyle:IllegalCatch") public void close() { try { @@ -326,7 +298,6 @@ public class OpenFlowPluginProviderImpl implements gracefulShutdown(roleManager); gracefulShutdown(executorService); gracefulShutdown(hashedWheelTimer); - unregisterMXBean(MESSAGE_INTELLIGENCE_AGENCY_MX_BEAN_NAME); diagStatusProvider.reportStatus(ServiceState.UNREGISTERED); try { if (connectionManager != null) { @@ -369,28 +340,5 @@ public class OpenFlowPluginProviderImpl implements } } - private static void registerMXBean(final Object bean, final String beanName) { - final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); - try { - mbs.registerMBean(bean, new ObjectName(beanName)); - } catch (MalformedObjectNameException - | NotCompliantMBeanException - | MBeanRegistrationException - | InstanceAlreadyExistsException e) { - LOG.warn("Error registering MBean {}", beanName, e); - } - } - - private static void unregisterMXBean(final String beanName) { - final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); - - try { - mbs.unregisterMBean(new ObjectName(beanName)); - } catch (InstanceNotFoundException - | MBeanRegistrationException - | MalformedObjectNameException e) { - LOG.warn("Error unregistering MBean {}", beanName, e); - } - } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/PingPongDataBroker.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/PingPongDataBroker.java index 757a077d49..c09d308450 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/PingPongDataBroker.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/PingPongDataBroker.java @@ -7,13 +7,32 @@ */ package org.opendaylight.openflowplugin.impl; +import static java.util.Objects.requireNonNull; + +import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.mdsal.binding.api.DataBroker; +import org.opendaylight.mdsal.binding.api.TransactionChain; +import org.opendaylight.mdsal.binding.spi.ForwardingDataBroker; /** - * An odl:type="pingpong" {@link DataBroker}. + * A {@link DataBroker} implementation which always creates merging transaction chains. * * @author Michael Vorburger.ch */ -public interface PingPongDataBroker extends DataBroker { +final class PingPongDataBroker extends ForwardingDataBroker { + private final @NonNull DataBroker delegate; + + PingPongDataBroker(final DataBroker delegate) { + this.delegate = requireNonNull(delegate); + } + + @Override + protected DataBroker delegate() { + return delegate; + } + @Override + public TransactionChain createTransactionChain() { + return delegate.createMergingTransactionChain(); + } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/configuration/ConfigurationServiceFactoryImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/configuration/ConfigurationServiceFactoryImpl.java index 336814874a..8acf277e34 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/configuration/ConfigurationServiceFactoryImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/configuration/ConfigurationServiceFactoryImpl.java @@ -27,8 +27,7 @@ public class ConfigurationServiceFactoryImpl implements ConfigurationServiceFact private static final Logger LOG = LoggerFactory.getLogger(ConfigurationServiceFactoryImpl.class); @Override - public ConfigurationService newInstance( - final OpenflowProviderConfig providerConfig) { + public ConfigurationService newInstance(final OpenflowProviderConfig providerConfig) { return new ConfigurationServiceImpl(providerConfig); } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/configuration/ConfigurationServiceFactoryOsgiImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/configuration/OSGiConfigurationServiceFactory.java similarity index 56% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/configuration/ConfigurationServiceFactoryOsgiImpl.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/configuration/OSGiConfigurationServiceFactory.java index 7f09eaba2e..a4ddc6ce26 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/configuration/ConfigurationServiceFactoryOsgiImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/configuration/OSGiConfigurationServiceFactory.java @@ -7,47 +7,51 @@ */ package org.opendaylight.openflowplugin.impl.configuration; +import static java.util.Objects.requireNonNull; + +import com.google.common.collect.Maps; import java.io.IOException; -import java.util.Dictionary; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Map; import org.opendaylight.openflowplugin.api.OFConstants; import org.opendaylight.openflowplugin.api.openflow.configuration.ConfigurationService; +import org.opendaylight.openflowplugin.api.openflow.configuration.ConfigurationServiceFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.openflow.provider.config.rev160510.OpenflowProviderConfig; import org.osgi.framework.BundleContext; -import org.osgi.framework.ServiceReference; +import org.osgi.framework.FrameworkUtil; import org.osgi.service.cm.Configuration; import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -// NOT @Singleton @Service - we do not want this OSGi specific implementation to be auto-discovered in a standalone env -public class ConfigurationServiceFactoryOsgiImpl extends ConfigurationServiceFactoryImpl { - private static final Logger LOG = LoggerFactory.getLogger(ConfigurationServiceFactoryOsgiImpl.class); +@Component(service = ConfigurationServiceFactory.class) +public final class OSGiConfigurationServiceFactory extends ConfigurationServiceFactoryImpl { + private static final Logger LOG = LoggerFactory.getLogger(OSGiConfigurationServiceFactory.class); private final BundleContext bundleContext; - public ConfigurationServiceFactoryOsgiImpl(final BundleContext bundleContext) { - this.bundleContext = bundleContext; + @Activate + public OSGiConfigurationServiceFactory(final BundleContext bundleContext) { + this.bundleContext = requireNonNull(bundleContext); } @Override public ConfigurationService newInstance(final OpenflowProviderConfig providerConfig) { - ConfigurationService cs = super.newInstance(providerConfig); + var cs = super.newInstance(providerConfig); update(cs); return cs; } private void update(final ConfigurationService configurationService) { LOG.info("Loading configuration from '{}' configuration file", OFConstants.CONFIG_FILE_ID); - final ServiceReference serviceReference = - bundleContext.getServiceReference(ConfigurationAdmin.class); + final var serviceReference = bundleContext.getServiceReference(ConfigurationAdmin.class); if (serviceReference == null) { + LOG.debug("No Configuration Admin Service available"); return; } - final ConfigurationAdmin configurationAdmin = bundleContext.getService(serviceReference); + final var configurationAdmin = bundleContext.getService(serviceReference); if (configurationAdmin == null) { + LOG.debug("Failed to get Configuration Admin Service from {}", serviceReference); return; } @@ -60,18 +64,9 @@ public class ConfigurationServiceFactoryOsgiImpl extends ConfigurationServiceFac return; } - final Dictionary properties = configuration.getProperties(); + final var properties = configuration.getProperties(); if (properties != null) { - final Enumeration keys = properties.keys(); - final Map mapProperties = new HashMap<>(properties.size()); - - while (keys.hasMoreElements()) { - final String key = keys.nextElement(); - final String value = properties.get(key).toString(); - mapProperties.put(key, value); - } - - configurationService.update(mapProperties); + configurationService.update(Maps.transformValues(FrameworkUtil.asMap(properties), Object::toString)); } } finally { bundleContext.ungetService(serviceReference); diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ClearStatsCommandProvider.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ClearStatsCommand.java similarity index 53% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ClearStatsCommandProvider.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ClearStatsCommand.java index 5dcc22613a..e9e698f12e 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ClearStatsCommandProvider.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ClearStatsCommand.java @@ -5,25 +5,27 @@ * 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.openflowplugin.impl.karaf; -import java.io.PrintStream; -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.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency; -import org.opendaylight.openflowplugin.impl.OpenFlowPluginProviderImpl; @Command(scope = "ofp", name = "clearStats", description = "Clear openflow statistics.") -public class ClearStatsCommandProvider extends OsgiCommandSupport { +@Service +public class ClearStatsCommand implements Action { + @Reference + Session session; + @Reference + MessageIntelligenceAgency messageIntelligenceAgency; @Override - protected Object doExecute() { - final MessageIntelligenceAgency messageIntelligenceAgency = - OpenFlowPluginProviderImpl.getMessageIntelligenceAgency(); + public Object execute() { messageIntelligenceAgency.resetStatistics(); - PrintStream out = session.getConsole(); - out.print("Openflow plugin statistics cleaned.\n"); + session.getConsole().println("Openflow plugin statistics cleaned."); return null; } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ResetEventTimesComandProvider.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ResetEventTimesCommand.java similarity index 60% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ResetEventTimesComandProvider.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ResetEventTimesCommand.java index 7cd5adb3e0..b387147deb 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ResetEventTimesComandProvider.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ResetEventTimesCommand.java @@ -5,25 +5,28 @@ * 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.openflowplugin.impl.karaf; -import java.io.PrintStream; -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.impl.statistics.ofpspecific.EventsTimeCounter; /** * Created by Martin Bobak <mbobak@cisco.com> on 28.5.2015. */ @Command(scope = "ofp", name = "reset-time-counters", description = "Resets events time counters.") -public class ResetEventTimesComandProvider extends OsgiCommandSupport { +@Service +public class ResetEventTimesCommand implements Action { + @Reference + Session session; @Override - protected Object doExecute() { - PrintStream out = session.getConsole(); + public Object execute() { EventsTimeCounter.resetAllCounters(); - out.print("Events time counters reset.\n"); + session.getConsole().println("Events time counters reset."); return null; } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ResetSessionStatsComandProvider.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ResetSessionStatsCommand.java similarity index 59% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ResetSessionStatsComandProvider.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ResetSessionStatsCommand.java index db383c6af4..e8167c5ad3 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ResetSessionStatsComandProvider.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ResetSessionStatsCommand.java @@ -5,25 +5,28 @@ * 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.openflowplugin.impl.karaf; -import java.io.PrintStream; -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.impl.statistics.ofpspecific.SessionStatistics; /** * Created by Martin Bobak <mbobak@cisco.com> on 28.5.2015. */ @Command(scope = "ofp", name = "reset-session-stats", description = "Resets session statistics counters.") -public class ResetSessionStatsComandProvider extends OsgiCommandSupport { +@Service +public class ResetSessionStatsCommand implements Action { + @Reference + Session session; @Override - protected Object doExecute() { - PrintStream out = session.getConsole(); + public Object execute() { SessionStatistics.resetAllCounters(); - out.print("Session statistics counters reset.\n"); + session.getConsole().println("Session statistics counters reset."); return null; } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowEventTimesComandProvider.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowEventTimesCommand.java similarity index 52% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowEventTimesComandProvider.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowEventTimesCommand.java index 1374857800..22bbea3b08 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowEventTimesComandProvider.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowEventTimesCommand.java @@ -5,31 +5,28 @@ * 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.openflowplugin.impl.karaf; -import java.io.PrintStream; -import java.util.List; -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.impl.statistics.ofpspecific.EventsTimeCounter; /** * Created by Martin Bobak <mbobak@cisco.com> on 28.5.2015. */ @Command(scope = "ofp", name = "show-time-counters", description = "Shows time counts for events.") -public class ShowEventTimesComandProvider extends OsgiCommandSupport { +@Service +public class ShowEventTimesCommand implements Action { + @Reference + Session session; @Override - protected Object doExecute() { - PrintStream out = session.getConsole(); - final List statistics = EventsTimeCounter.provideTimes(); - final StringBuilder result = new StringBuilder(); - for (String line : statistics) { - result.append(line); - result.append("\n"); - } - out.print(result.toString()); + public Object execute() { + final var console = session.getConsole(); + EventsTimeCounter.provideTimes().forEach(console::println); return null; } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowSessionStatsCommandProvider.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowSessionStatsCommand.java similarity index 52% rename from openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowSessionStatsCommandProvider.java rename to openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowSessionStatsCommand.java index 0187ec61d5..94b968d62e 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowSessionStatsCommandProvider.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowSessionStatsCommand.java @@ -5,13 +5,13 @@ * 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.openflowplugin.impl.karaf; -import java.io.PrintStream; -import java.util.List; -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.impl.statistics.ofpspecific.SessionStatistics; /** @@ -19,18 +19,15 @@ import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.SessionStatis */ @Command(scope = "ofp", name = "show-session-stats", description = "Show session statistics.") -public class ShowSessionStatsCommandProvider extends OsgiCommandSupport { +@Service +public class ShowSessionStatsCommand implements Action { + @Reference + Session session; @Override - protected Object doExecute() { - PrintStream out = session.getConsole(); - final List statistics = SessionStatistics.provideStatistics(); - final StringBuilder result = new StringBuilder(); - for (String line : statistics) { - result.append(line); - result.append("\n"); - } - out.print(result.toString()); + public Object execute() { + final var console = session.getConsole(); + SessionStatistics.provideStatistics().forEach(console::println); return null; } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowStatsCommand.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowStatsCommand.java new file mode 100644 index 0000000000..31daa53bfe --- /dev/null +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowStatsCommand.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2015 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.openflowplugin.impl.karaf; + +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.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency; + +@Command(scope = "ofp", name = "showStats", description = "Show openflow statistics.") +@Service +public class ShowStatsCommand implements Action { + @Reference + Session session; + @Reference + MessageIntelligenceAgency messageIntelligenceAgency; + + @Override + public Object execute() { + final var console = session.getConsole(); + messageIntelligenceAgency.provideIntelligence().forEach(console::println); + return null; + } +} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowStatsCommandProvider.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowStatsCommandProvider.java deleted file mode 100644 index 3d8307e6cb..0000000000 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/karaf/ShowStatsCommandProvider.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2015 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.openflowplugin.impl.karaf; - -import java.io.PrintStream; -import java.util.List; -import org.apache.karaf.shell.commands.Command; -import org.apache.karaf.shell.console.OsgiCommandSupport; -import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency; -import org.opendaylight.openflowplugin.impl.OpenFlowPluginProviderImpl; - -@Command(scope = "ofp", name = "showStats", description = "Show openflow statistics.") -public class ShowStatsCommandProvider extends OsgiCommandSupport { - - @Override - protected Object doExecute() { - PrintStream out = session.getConsole(); - final MessageIntelligenceAgency messageIntelligenceAgency = - OpenFlowPluginProviderImpl.getMessageIntelligenceAgency(); - final List statistics = messageIntelligenceAgency.provideIntelligence(); - final StringBuilder result = new StringBuilder(); - for (String line : statistics) { - result.append(line); - result.append("\n"); - } - out.print(result.toString()); - return null; - } -} diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/mastership/MastershipChangeServiceManagerImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/mastership/MastershipChangeServiceManagerImpl.java index 06ecc97a30..a24036ce8a 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/mastership/MastershipChangeServiceManagerImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/mastership/MastershipChangeServiceManagerImpl.java @@ -35,7 +35,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Singleton -@Component(immediate = true) +@Component(immediate = true, service = MastershipChangeServiceManager.class) public final class MastershipChangeServiceManagerImpl implements MastershipChangeServiceManager, AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(MastershipChangeServiceManagerImpl.class); diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/ofpspecific/MessageIntelligenceAgencyImpl.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/ofpspecific/MessageIntelligenceAgencyImpl.java index 866882251d..732240f3d2 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/ofpspecific/MessageIntelligenceAgencyImpl.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/ofpspecific/MessageIntelligenceAgencyImpl.java @@ -9,14 +9,25 @@ package org.opendaylight.openflowplugin.impl.statistics.ofpspecific; import static java.util.Objects.requireNonNull; +import java.lang.management.ManagementFactory; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicLongFieldUpdater; +import javax.annotation.PreDestroy; +import javax.inject.Inject; +import javax.inject.Singleton; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.MBeanRegistrationException; +import javax.management.MalformedObjectNameException; +import javax.management.NotCompliantMBeanException; +import javax.management.ObjectName; import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,9 +36,23 @@ import org.slf4j.LoggerFactory; * {@link org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency}. * Class counts message of {@link StatisticsGroup} type and provides info as debug log. */ -public class MessageIntelligenceAgencyImpl implements MessageIntelligenceAgency, MessageIntelligenceAgencyMXBean { +@Singleton +@Component(immediate = true, service = MessageIntelligenceAgency.class) +public final class MessageIntelligenceAgencyImpl implements MessageIntelligenceAgency, AutoCloseable { private static final Logger LOG = LoggerFactory.getLogger(MessageIntelligenceAgencyImpl.class); + private static final ObjectName MXBEAN_OBJECT_NAME; + + static { + try { + MXBEAN_OBJECT_NAME = new ObjectName("%s:type=%s".formatted( + MessageIntelligenceAgencyMXBean.class.getPackage().getName(), + MessageIntelligenceAgencyMXBean.class.getSimpleName())); + } catch (MalformedObjectNameException e) { + throw new ExceptionInInitializerError(e); + } + } + private static final class MessageCounters { private static final AtomicLongFieldUpdater UPDATER = AtomicLongFieldUpdater.newUpdater(MessageCounters.class, "current"); @@ -50,8 +75,38 @@ public class MessageIntelligenceAgencyImpl implements MessageIntelligenceAgency, } } - private ConcurrentMap, MessageCounters>> inputStats = - new ConcurrentHashMap<>(); + private final Map, MessageCounters>> inputStats = new ConcurrentHashMap<>(); + + private boolean runUnreg; + + @Inject + @Activate + public MessageIntelligenceAgencyImpl() { + try { + ManagementFactory.getPlatformMBeanServer() + .registerMBean((MessageIntelligenceAgencyMXBean) this::provideIntelligence, MXBEAN_OBJECT_NAME); + runUnreg = true; + LOG.info("Registered MBean {}", MXBEAN_OBJECT_NAME); + } catch (NotCompliantMBeanException | MBeanRegistrationException | InstanceAlreadyExistsException e) { + LOG.warn("Error registering MBean {}", MXBEAN_OBJECT_NAME, e); + runUnreg = false; + } + } + + @PreDestroy + @Deactivate + @Override + public void close() { + if (runUnreg) { + runUnreg = false; + try { + ManagementFactory.getPlatformMBeanServer().unregisterMBean(MXBEAN_OBJECT_NAME); + LOG.info("Unregistered MBean {}", MXBEAN_OBJECT_NAME); + } catch (InstanceNotFoundException | MBeanRegistrationException e) { + LOG.warn("Error unregistering MBean {}", MXBEAN_OBJECT_NAME, e); + } + } + } @Override public void spyMessage(final Class message, final StatisticsGroup statGroup) { @@ -66,41 +121,16 @@ public class MessageIntelligenceAgencyImpl implements MessageIntelligenceAgency, * @return corresponding counter */ private MessageCounters getCounters(final Class message, final StatisticsGroup statGroup) { - ConcurrentMap, MessageCounters> groupData = getOrCreateGroupData(statGroup); - MessageCounters counters = getOrCreateCountersPair(message, groupData); - return counters; - } - - private static MessageCounters getOrCreateCountersPair(final Class msgType, - final ConcurrentMap, MessageCounters> groupData) { - final MessageCounters lookup = groupData.get(msgType); - if (lookup != null) { - return lookup; - } - - final MessageCounters newCounters = new MessageCounters(); - final MessageCounters check = groupData.putIfAbsent(msgType, newCounters); - return check == null ? newCounters : check; - - } - - private ConcurrentMap, MessageCounters> getOrCreateGroupData(final StatisticsGroup statGroup) { - final ConcurrentMap, MessageCounters> lookup = inputStats.get(statGroup); - if (lookup != null) { - return lookup; - } - - final ConcurrentMap, MessageCounters> newmap = new ConcurrentHashMap<>(); - final ConcurrentMap, MessageCounters> check = inputStats.putIfAbsent(statGroup, newmap); - - return check == null ? newmap : check; + return inputStats + .computeIfAbsent(statGroup, key -> new ConcurrentHashMap<>()) + .computeIfAbsent(message, key -> new MessageCounters()); } @Override public void run() { // log current counters and cleans it if (LOG.isDebugEnabled()) { - for (String counterItem : provideIntelligence()) { + for (var counterItem : provideIntelligence()) { LOG.debug("Counter: {}", counterItem); } } @@ -108,12 +138,12 @@ public class MessageIntelligenceAgencyImpl implements MessageIntelligenceAgency, @Override public List provideIntelligence() { - List dump = new ArrayList<>(); + final var dump = new ArrayList(); - for (StatisticsGroup statGroup : StatisticsGroup.values()) { - Map, MessageCounters> groupData = inputStats.get(statGroup); + for (var statGroup : StatisticsGroup.values()) { + final var groupData = inputStats.get(statGroup); if (groupData != null) { - for (Entry, MessageCounters> statEntry : groupData.entrySet()) { + for (var statEntry : groupData.entrySet()) { long amountPerInterval = statEntry.getValue().accumulate(); long cumulativeAmount = statEntry.getValue().getCumulative(); dump.add(String.format("%s: MSG[%s] -> +%d | %d", @@ -130,6 +160,6 @@ public class MessageIntelligenceAgencyImpl implements MessageIntelligenceAgency, @Override public void resetStatistics() { - inputStats = new ConcurrentHashMap<>(); + inputStats.clear(); } } diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/ofpspecific/MessageIntelligenceAgencyMXBean.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/ofpspecific/MessageIntelligenceAgencyMXBean.java index bf8602739b..6ffd0da383 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/ofpspecific/MessageIntelligenceAgencyMXBean.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/statistics/ofpspecific/MessageIntelligenceAgencyMXBean.java @@ -5,14 +5,15 @@ * 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.openflowplugin.impl.statistics.ofpspecific; import java.util.List; +import javax.management.MXBean; /** * Created by Martin Bobak <mbobak@cisco.com> on 11.5.2015. */ +@MXBean public interface MessageIntelligenceAgencyMXBean { List provideIntelligence(); diff --git a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/translator/PacketReceivedTranslator.java b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/translator/PacketReceivedTranslator.java index 72e8d64c06..01708f3f19 100644 --- a/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/translator/PacketReceivedTranslator.java +++ b/openflowplugin-impl/src/main/java/org/opendaylight/openflowplugin/impl/translator/PacketReceivedTranslator.java @@ -41,7 +41,6 @@ public class PacketReceivedTranslator implements MessageTranslator - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/openflowplugin-impl/src/main/resources/OSGI-INF/blueprint/openflowplugin-impl.xml b/openflowplugin-impl/src/main/resources/OSGI-INF/blueprint/openflowplugin-impl.xml index 24e9cde403..c89df82dd1 100644 --- a/openflowplugin-impl/src/main/resources/OSGI-INF/blueprint/openflowplugin-impl.xml +++ b/openflowplugin-impl/src/main/resources/OSGI-INF/blueprint/openflowplugin-impl.xml @@ -1,32 +1,12 @@ - - - - - - - - - - - - - - - - org.opendaylight.openflowplugin.api.openflow.OpenFlowPluginProvider - org.opendaylight.openflowplugin.extension.api.OpenFlowPluginExtensionRegistratorProvider - org.opendaylight.openflowplugin.api.openflow.FlowGroupInfoHistories - - + + - - - - - - - - - - - - - - - - - - - diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImplTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImplTest.java index 0bef9563a1..9480822833 100644 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImplTest.java +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/OpenFlowPluginProviderImplTest.java @@ -13,8 +13,8 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.google.common.collect.Lists; import com.google.common.util.concurrent.Futures; +import java.util.List; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -28,52 +28,42 @@ import org.opendaylight.mdsal.common.api.CommitInfo; import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService; import org.opendaylight.mdsal.singleton.api.ClusterSingletonServiceProvider; import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProvider; -import org.opendaylight.openflowjava.protocol.spi.connection.SwitchConnectionProviderList; import org.opendaylight.openflowplugin.api.openflow.configuration.ConfigurationProperty; import org.opendaylight.openflowplugin.api.openflow.configuration.ConfigurationService; import org.opendaylight.openflowplugin.api.openflow.mastership.MastershipChangeServiceManager; +import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency; import org.opendaylight.yangtools.concepts.Registration; import org.opendaylight.yangtools.yang.common.Uint16; import org.opendaylight.yangtools.yang.common.Uint32; @RunWith(MockitoJUnitRunner.class) public class OpenFlowPluginProviderImplTest { - @Mock PingPongDataBroker dataBroker; - @Mock RpcProviderService rpcProviderRegistry; - @Mock NotificationPublishService notificationPublishService; - @Mock DiagStatusProvider ofPluginDiagstatusProvider; - @Mock SystemReadyMonitor systemReadyMonitor; - @Mock WriteTransaction writeTransaction; - @Mock EntityOwnershipService entityOwnershipService; - @Mock Registration entityOwnershipListenerRegistration; - @Mock SwitchConnectionProvider switchConnectionProvider; - @Mock ClusterSingletonServiceProvider clusterSingletonServiceProvider; - @Mock ConfigurationService configurationService; - @Mock MastershipChangeServiceManager mastershipChangeServiceManager; + @Mock + MessageIntelligenceAgency messageIntelligenceAgency; private static final Uint16 THREAD_POOL_MIN_THREADS = Uint16.ONE; private static final Uint16 THREAD_POOL_MAX_THREADS = Uint16.valueOf(32000); @@ -87,7 +77,7 @@ public class OpenFlowPluginProviderImplTest { when(dataBroker.newWriteOnlyTransaction()).thenReturn(writeTransaction); doReturn(CommitInfo.emptyFluentFuture()).when(writeTransaction).commit(); when(entityOwnershipService.registerListener(any(), any())).thenReturn(entityOwnershipListenerRegistration); - when(switchConnectionProvider.startup()).thenReturn(Futures.immediateFuture(true)); + when(switchConnectionProvider.startup()).thenReturn(Futures.immediateFuture(null)); when(switchConnectionProvider.shutdown()).thenReturn(Futures.immediateFuture(true)); when(configurationService.getProperty(eq(ConfigurationProperty.USE_SINGLE_LAYER_SERIALIZATION.toString()), any())).thenReturn(USE_SINGLE_LAYER_SERIALIZATION); @@ -106,23 +96,14 @@ public class OpenFlowPluginProviderImplTest { @Test public void testInitializeAndClose() { - final OpenFlowPluginProviderImpl provider = new OpenFlowPluginProviderImpl( - configurationService, - new SwitchConnectionProviderList(Lists.newArrayList(switchConnectionProvider)), - dataBroker, - rpcProviderRegistry, - notificationPublishService, - clusterSingletonServiceProvider, - entityOwnershipService, - mastershipChangeServiceManager, - ofPluginDiagstatusProvider, - systemReadyMonitor); - - provider.initialize(); - // Calling the onSystemBootReady() callback - provider.onSystemBootReady(); - verify(switchConnectionProvider).startup(); - provider.close(); + try (var provider = new OpenFlowPluginProviderImpl(configurationService, List.of(switchConnectionProvider), + dataBroker, rpcProviderRegistry, notificationPublishService, clusterSingletonServiceProvider, + entityOwnershipService, mastershipChangeServiceManager, messageIntelligenceAgency, + ofPluginDiagstatusProvider, systemReadyMonitor)) { + // Calling the onSystemBootReady() callback + provider.onSystemBootReady(); + verify(switchConnectionProvider).startup(); + } verify(switchConnectionProvider).shutdown(); } } diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/AbstractCommandTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/AbstractCommandTest.java new file mode 100644 index 0000000000..124ab0d3d4 --- /dev/null +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/AbstractCommandTest.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2015 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.openflowplugin.impl.karaf; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.doReturn; + +import java.io.PrintStream; +import java.util.List; +import java.util.function.Function; +import org.apache.karaf.shell.api.console.Session; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +/** + * Created by mirehak on 7/29/15. + */ +@ExtendWith(MockitoExtension.class) +abstract class AbstractCommandTest { + @Mock + protected Session session; + @Mock + protected PrintStream console; + + @BeforeEach + void beforeEach() { + doReturn(console).when(session).getConsole(); + doBeforeEach(); + } + + protected abstract void doBeforeEach(); + + protected static void assertNoActivity(final List allStatLines, + final Function checkFunction) { + assertTrue(checkNoActivity(allStatLines, checkFunction)); + } + + protected static void assertHasActivity(final List allStatLines, + final Function checkFunction) { + assertFalse(checkNoActivity(allStatLines, checkFunction)); + } + + private static boolean checkNoActivity(final List allStatLines, + final Function checkFunction) { + for (var statLine : allStatLines) { + if (!checkFunction.apply(statLine)) { + return false; + } + } + return true; + } +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/AbstractKarafTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/AbstractKarafTest.java deleted file mode 100644 index d47c0e1a38..0000000000 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/AbstractKarafTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2015 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.openflowplugin.impl.karaf; - -import java.io.PrintStream; -import java.util.List; -import java.util.function.Function; -import org.apache.felix.service.command.CommandSession; -import org.junit.Before; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; -import org.mockito.junit.MockitoJUnitRunner; - -/** - * Created by mirehak on 7/29/15. - */ -@RunWith(MockitoJUnitRunner.class) -public abstract class AbstractKarafTest { - @Mock - protected CommandSession cmdSession; - @Mock - protected PrintStream console; - - @Before - public void setUp() { - Mockito.when(cmdSession.getConsole()).thenReturn(console); - doSetUp(); - } - - public abstract void doSetUp(); - - public static boolean checkNoActivity(List allStatLines, Function checkFunction) { - boolean noActivity = true; - for (String statLine : allStatLines) { - noActivity &= checkFunction.apply(statLine); - } - return noActivity; - } -} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ClearStatsCommandProviderTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ClearStatsCommandProviderTest.java deleted file mode 100644 index f6bd07f75e..0000000000 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ClearStatsCommandProviderTest.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2015 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.openflowplugin.impl.karaf; - -import static org.mockito.ArgumentMatchers.anyString; - -import java.util.function.Function; -import org.junit.After; -import org.junit.Assert; -import org.junit.Test; -import org.mockito.Mockito; -import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency; -import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy; -import org.opendaylight.openflowplugin.impl.OpenFlowPluginProviderImpl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; - -/** - * Test for {@link ClearStatsCommandProvider}. - */ -public class ClearStatsCommandProviderTest extends AbstractKarafTest { - - private ClearStatsCommandProvider clearStatsCommandProvider; - private static final Function CHECK_NO_ACTIVITY_FUNCTION = - input -> input.endsWith(": no activity detected"); - private MessageIntelligenceAgency mi5; - - @Override - public void doSetUp() { - clearStatsCommandProvider = new ClearStatsCommandProvider(); - mi5 = OpenFlowPluginProviderImpl.getMessageIntelligenceAgency(); - mi5.resetStatistics(); - Mockito.when(cmdSession.getConsole()).thenReturn(console); - } - - @After - public void tearDown() { - Mockito.verify(console).print(anyString()); - mi5.resetStatistics(); - } - - /** - * Test for {@link ClearStatsCommandProvider#doExecute()} when no stats were touched before. - */ - @Test - public void testDoExecute_clean() throws Exception { - Assert.assertTrue(checkNoActivity(mi5.provideIntelligence(), CHECK_NO_ACTIVITY_FUNCTION)); - clearStatsCommandProvider.execute(cmdSession); - - Assert.assertTrue(checkNoActivity(mi5.provideIntelligence(), CHECK_NO_ACTIVITY_FUNCTION)); - } - - /** - * Test for {@link ClearStatsCommandProvider#doExecute()} when stats were touched before. - */ - @Test - public void testDoExecute_dirty() throws Exception { - mi5 = OpenFlowPluginProviderImpl.getMessageIntelligenceAgency(); - Assert.assertTrue(checkNoActivity(mi5.provideIntelligence(), CHECK_NO_ACTIVITY_FUNCTION)); - mi5.spyMessage(OfHeader.class, MessageSpy.StatisticsGroup.FROM_SWITCH); - Assert.assertFalse(checkNoActivity(mi5.provideIntelligence(), CHECK_NO_ACTIVITY_FUNCTION)); - - clearStatsCommandProvider.execute(cmdSession); - Assert.assertTrue(checkNoActivity(mi5.provideIntelligence(), CHECK_NO_ACTIVITY_FUNCTION)); - } -} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ClearStatsCommandTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ClearStatsCommandTest.java new file mode 100644 index 0000000000..c232e2101e --- /dev/null +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ClearStatsCommandTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2015 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.openflowplugin.impl.karaf; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.verify; + +import java.util.function.Function; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency; +import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy; +import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.MessageIntelligenceAgencyImpl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; + +/** + * Test for {@link ClearStatsCommand}. + */ +class ClearStatsCommandTest extends AbstractCommandTest { + private static final Function CHECK_NO_ACTIVITY_FUNCTION = + input -> input.endsWith(": no activity detected"); + + private final MessageIntelligenceAgency messageIntelligenceAgency = new MessageIntelligenceAgencyImpl(); + + @InjectMocks + private ClearStatsCommand clearStatsCommand; + + @Override + protected void doBeforeEach() { + clearStatsCommand.messageIntelligenceAgency = messageIntelligenceAgency; + messageIntelligenceAgency.resetStatistics(); + assertNoActivity(messageIntelligenceAgency.provideIntelligence(), CHECK_NO_ACTIVITY_FUNCTION); + } + + /** + * Test for {@link ClearStatsCommand#execute()} when no stats were touched before. + */ + @Test + void clearNoActivity() { + clearStatsCommand.execute(); + verify(console).println(anyString()); + assertNoActivity(messageIntelligenceAgency.provideIntelligence(), CHECK_NO_ACTIVITY_FUNCTION); + } + + /** + * Test for {@link ClearStatsCommand#execute()} when stats were touched before. + */ + @Test + void clearHavingActivity() { + messageIntelligenceAgency.spyMessage(OfHeader.class, MessageSpy.StatisticsGroup.FROM_SWITCH); + assertHasActivity(messageIntelligenceAgency.provideIntelligence(), CHECK_NO_ACTIVITY_FUNCTION); + clearStatsCommand.execute(); + verify(console).println(anyString()); + assertNoActivity(messageIntelligenceAgency.provideIntelligence(), CHECK_NO_ACTIVITY_FUNCTION); + } +} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ResetEventTimesComandProviderTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ResetEventTimesComandProviderTest.java deleted file mode 100644 index 02315e8125..0000000000 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ResetEventTimesComandProviderTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2015 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.openflowplugin.impl.karaf; - -import static org.mockito.ArgumentMatchers.anyString; - -import java.util.function.Function; -import org.junit.After; -import org.junit.Assert; -import org.junit.Test; -import org.mockito.Mockito; -import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier; -import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter; - -/** - * Test for {@link ResetEventTimesComandProvider}. - */ -public class ResetEventTimesComandProviderTest extends AbstractKarafTest { - - private ResetEventTimesComandProvider resetEventTimesComandProvider; - private static final Function CHECK_NO_ACTIVITY_FUNCTION = String::isEmpty; - - @Override - public void doSetUp() { - resetEventTimesComandProvider = new ResetEventTimesComandProvider(); - EventsTimeCounter.resetAllCounters(); - } - - @After - public void tearDown() { - Mockito.verify(console).print(anyString()); - EventsTimeCounter.resetAllCounters(); - } - - /** - * Test for {@link ResetEventTimesComandProvider#doExecute()} when no stats were touched before. - */ - @Test - public void testDoExecute_clean() throws Exception { - Assert.assertTrue(checkNoActivity(EventsTimeCounter.provideTimes(), CHECK_NO_ACTIVITY_FUNCTION)); - resetEventTimesComandProvider.execute(cmdSession); - Assert.assertTrue(checkNoActivity(EventsTimeCounter.provideTimes(), CHECK_NO_ACTIVITY_FUNCTION)); - } - - /** - * Test for {@link ResetEventTimesComandProvider#doExecute()} when stats were touched before. - */ - @Test - public void testDoExecute_dirty() throws Exception { - final EventIdentifier dummyEvent = new EventIdentifier("junit", "junitDevice"); - Assert.assertTrue(checkNoActivity(EventsTimeCounter.provideTimes(), CHECK_NO_ACTIVITY_FUNCTION)); - - EventsTimeCounter.markStart(dummyEvent); - EventsTimeCounter.markEnd(dummyEvent); - Assert.assertFalse(checkNoActivity(EventsTimeCounter.provideTimes(), CHECK_NO_ACTIVITY_FUNCTION)); - - resetEventTimesComandProvider.execute(cmdSession); - Assert.assertTrue(checkNoActivity(EventsTimeCounter.provideTimes(), CHECK_NO_ACTIVITY_FUNCTION)); - } -} \ No newline at end of file diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ResetEventTimesCommandTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ResetEventTimesCommandTest.java new file mode 100644 index 0000000000..4003ad1378 --- /dev/null +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ResetEventTimesCommandTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2015 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.openflowplugin.impl.karaf; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.verify; + +import java.util.function.Function; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier; +import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter; + +/** + * Test for {@link ResetEventTimesCommand}. + */ +class ResetEventTimesCommandTest extends AbstractCommandTest { + private static final Function CHECK_NO_ACTIVITY_FUNCTION = String::isEmpty; + + @InjectMocks + private ResetEventTimesCommand resetEventTimesCommand; + + @Override + protected void doBeforeEach() { + EventsTimeCounter.resetAllCounters(); + assertNoActivity(EventsTimeCounter.provideTimes(), CHECK_NO_ACTIVITY_FUNCTION); + } + + /** + * Test for {@link ResetEventTimesCommand#execute()} when no stats were touched before. + */ + @Test + void resetNoActivity() { + resetEventTimesCommand.execute(); + verify(console).println(anyString()); + assertNoActivity(EventsTimeCounter.provideTimes(), CHECK_NO_ACTIVITY_FUNCTION); + } + + /** + * Test for {@link ResetEventTimesCommand#execute()} when stats were touched before. + */ + @Test + void resetHavingActivity() { + final var dummyEvent = new EventIdentifier("junit", "junitDevice"); + EventsTimeCounter.markStart(dummyEvent); + EventsTimeCounter.markEnd(dummyEvent); + assertHasActivity(EventsTimeCounter.provideTimes(), CHECK_NO_ACTIVITY_FUNCTION); + + resetEventTimesCommand.execute(); + verify(console).println(anyString()); + assertNoActivity(EventsTimeCounter.provideTimes(), CHECK_NO_ACTIVITY_FUNCTION); + } +} \ No newline at end of file diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ResetSessionStatsComandProviderTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ResetSessionStatsComandProviderTest.java deleted file mode 100644 index 754988938e..0000000000 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ResetSessionStatsComandProviderTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2015 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.openflowplugin.impl.karaf; - -import static org.mockito.ArgumentMatchers.anyString; - -import java.util.function.Function; -import org.junit.After; -import org.junit.Assert; -import org.junit.Test; -import org.mockito.Mockito; -import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.SessionStatistics; - -/** - * Test for {@link ResetSessionStatsComandProvider}. - */ -public class ResetSessionStatsComandProviderTest extends AbstractKarafTest { - - private ResetSessionStatsComandProvider resetSessionStatsComandProvider; - private static final Function CHECK_NO_ACTIVITY_FUNCTION = String::isEmpty; - - @Override - public void doSetUp() { - resetSessionStatsComandProvider = new ResetSessionStatsComandProvider(); - SessionStatistics.resetAllCounters(); - } - - @After - public void tearDown() { - Mockito.verify(console).print(anyString()); - SessionStatistics.resetAllCounters(); - } - - /** - * Test for {@link ResetSessionStatsComandProvider#doExecute()} when no stats were touched before. - */ - @Test - public void testDoExecute_clean() throws Exception { - Assert.assertTrue(checkNoActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION)); - resetSessionStatsComandProvider.execute(cmdSession); - Assert.assertTrue(checkNoActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION)); - } - - /** - * Test for {@link ResetSessionStatsComandProvider#doExecute()} when stats were touched before. - */ - @Test - public void testDoExecute_dirty() throws Exception { - final String dummySessionId = "junitSessionId"; - Assert.assertTrue(checkNoActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION)); - - SessionStatistics.countEvent(dummySessionId, SessionStatistics.ConnectionStatus.CONNECTION_CREATED); - Assert.assertFalse(checkNoActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION)); - - resetSessionStatsComandProvider.execute(cmdSession); - Assert.assertTrue(checkNoActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION)); - } -} \ No newline at end of file diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ResetSessionStatsCommandTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ResetSessionStatsCommandTest.java new file mode 100644 index 0000000000..ce7c88eba0 --- /dev/null +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ResetSessionStatsCommandTest.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2015 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.openflowplugin.impl.karaf; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.verify; + +import java.util.function.Function; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.SessionStatistics; + +/** + * Test for {@link ResetSessionStatsCommand}. + */ +class ResetSessionStatsCommandTest extends AbstractCommandTest { + @InjectMocks + private ResetSessionStatsCommand resetSessionStatsCommand; + private static final Function CHECK_NO_ACTIVITY_FUNCTION = String::isEmpty; + + @Override + protected void doBeforeEach() { + SessionStatistics.resetAllCounters(); + assertNoActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION); + } + + /** + * Test for {@link ResetSessionStatsCommand#execute()} when no stats were touched before. + */ + @Test + void resetNoActivity() { + resetSessionStatsCommand.execute(); + verify(console, atLeastOnce()).println(anyString()); + assertNoActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION); + } + + /** + * Test for {@link ResetSessionStatsCommand#execute()} when stats were touched before. + */ + @Test + void resetHavingActivity() { + final String dummySessionId = "junitSessionId"; + SessionStatistics.countEvent(dummySessionId, SessionStatistics.ConnectionStatus.CONNECTION_CREATED); + assertHasActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION); + + resetSessionStatsCommand.execute(); + verify(console, atLeastOnce()).println(anyString()); + assertNoActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION); + } +} \ No newline at end of file diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowEventTimesComandProviderTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowEventTimesComandProviderTest.java deleted file mode 100644 index 69b0704d83..0000000000 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowEventTimesComandProviderTest.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2015 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.openflowplugin.impl.karaf; - -import static org.mockito.ArgumentMatchers.contains; - -import java.util.function.Function; -import org.junit.After; -import org.junit.Assert; -import org.junit.Test; -import org.mockito.Mockito; -import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier; -import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter; - -/** - * Test for {@link ShowEventTimesComandProvider}. - */ -public class ShowEventTimesComandProviderTest extends AbstractKarafTest { - - private ShowEventTimesComandProvider showEventTimesComandProvider; - private static final Function CHECK_NO_ACTIVITY_FUNCTION = String::isEmpty; - - @Override - - public void doSetUp() { - showEventTimesComandProvider = new ShowEventTimesComandProvider(); - EventsTimeCounter.resetAllCounters(); - } - - @After - public void tearDown() { - EventsTimeCounter.resetAllCounters(); - } - - /** - * Test for {@link ShowEventTimesComandProvider#doExecute()} when no stats were touched before. - */ - @Test - public void testDoExecute_clean() throws Exception { - Assert.assertTrue(checkNoActivity(EventsTimeCounter.provideTimes(), CHECK_NO_ACTIVITY_FUNCTION)); - showEventTimesComandProvider.execute(cmdSession); - Assert.assertTrue(checkNoActivity(EventsTimeCounter.provideTimes(), CHECK_NO_ACTIVITY_FUNCTION)); - Mockito.verify(console).print(""); - } - - /** - * Test for {@link ShowEventTimesComandProvider#doExecute()} when stats were touched before. - */ - @Test - public void testDoExecute_dirty() throws Exception { - final EventIdentifier dummyEvent = new EventIdentifier("junit", "junitDevice"); - Assert.assertTrue(checkNoActivity(EventsTimeCounter.provideTimes(), CHECK_NO_ACTIVITY_FUNCTION)); - - EventsTimeCounter.markStart(dummyEvent); - EventsTimeCounter.markEnd(dummyEvent); - Assert.assertFalse(checkNoActivity(EventsTimeCounter.provideTimes(), CHECK_NO_ACTIVITY_FUNCTION)); - - showEventTimesComandProvider.execute(cmdSession); - Assert.assertFalse(checkNoActivity(EventsTimeCounter.provideTimes(), CHECK_NO_ACTIVITY_FUNCTION)); - Mockito.verify(console).print(contains("junitDevice")); - } -} \ No newline at end of file diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowEventTimesCommandTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowEventTimesCommandTest.java new file mode 100644 index 0000000000..38a38c9c2a --- /dev/null +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowEventTimesCommandTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 PANTHEON.tech s.r.o. 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.openflowplugin.impl.karaf; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.contains; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import java.util.function.Function; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.EventIdentifier; +import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.EventsTimeCounter; + +/** + * Test for {@link ShowEventTimesCommand}. + */ +class ShowEventTimesCommandTest extends AbstractCommandTest { + private static final Function CHECK_NO_ACTIVITY_FUNCTION = String::isEmpty; + + @InjectMocks + private ShowEventTimesCommand showEventTimesCommand; + + @Override + protected void doBeforeEach() { + EventsTimeCounter.resetAllCounters(); + assertNoActivity(EventsTimeCounter.provideTimes(), CHECK_NO_ACTIVITY_FUNCTION); + } + + /** + * Test for {@link ShowEventTimesCommand#execute()} when no stats were touched before. + */ + @Test + void showNoActivity() { + showEventTimesCommand.execute(); + verify(console, never()).println(anyString()); + assertNoActivity(EventsTimeCounter.provideTimes(), CHECK_NO_ACTIVITY_FUNCTION); + } + + /** + * Test for {@link ShowEventTimesCommand#execute()} when stats were touched before. + */ + @Test + void showHavingActivity() { + final var dummyEvent = new EventIdentifier("junit", "junitDevice"); + EventsTimeCounter.markStart(dummyEvent); + EventsTimeCounter.markEnd(dummyEvent); + assertHasActivity(EventsTimeCounter.provideTimes(), CHECK_NO_ACTIVITY_FUNCTION); + + showEventTimesCommand.execute(); + verify(console).println(contains("junitDevice")); + } +} \ No newline at end of file diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowSessionStatsCommandProviderTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowSessionStatsCommandProviderTest.java deleted file mode 100644 index 5571901276..0000000000 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowSessionStatsCommandProviderTest.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2015 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.openflowplugin.impl.karaf; - -import static org.mockito.ArgumentMatchers.contains; - -import java.util.function.Function; -import org.junit.After; -import org.junit.Assert; -import org.junit.Test; -import org.mockito.Mockito; -import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.SessionStatistics; - -/** - * Test for {@link ShowSessionStatsCommandProvider}. - */ -public class ShowSessionStatsCommandProviderTest extends AbstractKarafTest { - - private ShowSessionStatsCommandProvider showSessionStatsCommandProvider; - private static final Function CHECK_NO_ACTIVITY_FUNCTION = String::isEmpty; - - @Override - - public void doSetUp() { - showSessionStatsCommandProvider = new ShowSessionStatsCommandProvider(); - SessionStatistics.resetAllCounters(); - } - - @After - public void tearDown() { - SessionStatistics.resetAllCounters(); - } - - /** - * Test for {@link ShowEventTimesComandProvider#doExecute()} when no stats were touched before. - */ - @Test - public void testDoExecute_clean() throws Exception { - Assert.assertTrue(checkNoActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION)); - showSessionStatsCommandProvider.execute(cmdSession); - Assert.assertTrue(checkNoActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION)); - Mockito.verify(console).print(""); - } - - /** - * Test for {@link ShowEventTimesComandProvider#doExecute()} when stats were touched before. - */ - @Test - public void testDoExecute_dirty() throws Exception { - final String dummySessionId = "junitSessionId"; - Assert.assertTrue(checkNoActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION)); - - SessionStatistics.countEvent(dummySessionId, SessionStatistics.ConnectionStatus.CONNECTION_CREATED); - Assert.assertFalse(checkNoActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION)); - - showSessionStatsCommandProvider.execute(cmdSession); - Assert.assertFalse(checkNoActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION)); - Mockito.verify(console).print(contains(dummySessionId)); - } -} \ No newline at end of file diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowSessionStatsCommandTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowSessionStatsCommandTest.java new file mode 100644 index 0000000000..1e24c00335 --- /dev/null +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowSessionStatsCommandTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2015 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.openflowplugin.impl.karaf; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.contains; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import java.util.function.Function; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.SessionStatistics; + +/** + * Test for {@link ShowSessionStatsCommand}. + */ +class ShowSessionStatsCommandTest extends AbstractCommandTest { + private static final Function CHECK_NO_ACTIVITY_FUNCTION = String::isEmpty; + + @InjectMocks + private ShowSessionStatsCommand showSessionStatsCommand; + + @Override + protected void doBeforeEach() { + SessionStatistics.resetAllCounters(); + assertNoActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION); + } + + /** + * Test for {@link ShowEventTimesCommand#execute()} when no stats were touched before. + */ + @Test + void showNoActivity() { + showSessionStatsCommand.execute(); + verify(console, never()).println(anyString()); + assertNoActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION); + } + + /** + * Test for {@link ShowEventTimesCommand#execute()} when stats were touched before. + */ + @Test + void showHavingActivity() { + final var dummySessionId = "junitSessionId"; + SessionStatistics.countEvent(dummySessionId, SessionStatistics.ConnectionStatus.CONNECTION_CREATED); + assertHasActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION); + + showSessionStatsCommand.execute(); + verify(console, atLeastOnce()).println(contains(dummySessionId)); + assertHasActivity(SessionStatistics.provideStatistics(), CHECK_NO_ACTIVITY_FUNCTION); + } +} \ No newline at end of file diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowStatsCommandProviderTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowStatsCommandProviderTest.java deleted file mode 100644 index f9bb9763bf..0000000000 --- a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowStatsCommandProviderTest.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2015 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.openflowplugin.impl.karaf; - -import static org.mockito.ArgumentMatchers.matches; - -import java.util.function.Function; -import org.junit.After; -import org.junit.Assert; -import org.junit.Test; -import org.mockito.Mockito; -import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency; -import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy; -import org.opendaylight.openflowplugin.impl.OpenFlowPluginProviderImpl; -import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; - -/** - * Test for {@link ShowStatsCommandProvider}. - */ -public class ShowStatsCommandProviderTest extends AbstractKarafTest { - - private ShowStatsCommandProvider showStatsCommandProvider; - private MessageIntelligenceAgency messageIntelligenceAgency; - - private static final Function CHECK_NO_ACTIVITY_FUNCTION = - input -> input.endsWith(": no activity detected"); - - @Override - public void doSetUp() { - showStatsCommandProvider = new ShowStatsCommandProvider(); - messageIntelligenceAgency = OpenFlowPluginProviderImpl.getMessageIntelligenceAgency(); - messageIntelligenceAgency.resetStatistics(); - } - - @After - public void tearDown() { - // Pattern.DOTALL is set inline via "(?s)" at the beginning - Mockito.verify(console).print(matches("(?s).+")); - messageIntelligenceAgency.resetStatistics(); - } - - /** - * Test for {@link ShowEventTimesComandProvider#doExecute()} when no stats were touched before. - */ - @Test - public void testDoExecute_clean() throws Exception { - Assert.assertTrue(checkNoActivity(messageIntelligenceAgency.provideIntelligence(), CHECK_NO_ACTIVITY_FUNCTION)); - showStatsCommandProvider.execute(cmdSession); - Assert.assertTrue(checkNoActivity(messageIntelligenceAgency.provideIntelligence(), CHECK_NO_ACTIVITY_FUNCTION)); - } - - /** - * Test for {@link ShowEventTimesComandProvider#doExecute()} when stats were touched before. - */ - @Test - public void testDoExecute_dirty() throws Exception { - Assert.assertTrue(checkNoActivity(messageIntelligenceAgency.provideIntelligence(), CHECK_NO_ACTIVITY_FUNCTION)); - - messageIntelligenceAgency.spyMessage(OfHeader.class, MessageSpy.StatisticsGroup.FROM_SWITCH); - Assert.assertFalse(checkNoActivity(messageIntelligenceAgency.provideIntelligence(), - CHECK_NO_ACTIVITY_FUNCTION)); - - showStatsCommandProvider.execute(cmdSession); - Assert.assertFalse(checkNoActivity(messageIntelligenceAgency.provideIntelligence(), - CHECK_NO_ACTIVITY_FUNCTION)); - } -} diff --git a/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowStatsCommandrTest.java b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowStatsCommandrTest.java new file mode 100644 index 0000000000..bc1a3fbf0b --- /dev/null +++ b/openflowplugin-impl/src/test/java/org/opendaylight/openflowplugin/impl/karaf/ShowStatsCommandrTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2015 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.openflowplugin.impl.karaf; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; + +import java.util.function.Function; +import org.junit.jupiter.api.Test; +import org.mockito.InjectMocks; +import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageIntelligenceAgency; +import org.opendaylight.openflowplugin.api.openflow.statistics.ofpspecific.MessageSpy; +import org.opendaylight.openflowplugin.impl.statistics.ofpspecific.MessageIntelligenceAgencyImpl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.protocol.rev130731.OfHeader; + +/** + * Test for {@link ShowStatsCommand}. + */ +class ShowStatsCommandrTest extends AbstractCommandTest { + private final MessageIntelligenceAgency messageIntelligenceAgency = new MessageIntelligenceAgencyImpl(); + + @InjectMocks + private ShowStatsCommand showStatsCommand; + + private static final Function CHECK_NO_ACTIVITY_FUNCTION = + input -> input.endsWith(": no activity detected"); + + @Override + protected void doBeforeEach() { + showStatsCommand.messageIntelligenceAgency = messageIntelligenceAgency; + messageIntelligenceAgency.resetStatistics(); + assertNoActivity(messageIntelligenceAgency.provideIntelligence(), CHECK_NO_ACTIVITY_FUNCTION); + } + + /** + * Test for {@link ShowEventTimesCommand#execute()} when no stats were touched before. + */ + @Test + void showNoActivity() { + showStatsCommand.execute(); + verify(console, never()).println(); + assertNoActivity(messageIntelligenceAgency.provideIntelligence(), CHECK_NO_ACTIVITY_FUNCTION); + } + + /** + * Test for {@link ShowEventTimesCommand#execute()} when stats were touched before. + */ + @Test + void showHavingActivity() { + messageIntelligenceAgency.spyMessage(OfHeader.class, MessageSpy.StatisticsGroup.FROM_SWITCH); + assertHasActivity(messageIntelligenceAgency.provideIntelligence(),CHECK_NO_ACTIVITY_FUNCTION); + + showStatsCommand.execute(); + verify(console, atLeastOnce()).println(anyString()); + assertHasActivity(messageIntelligenceAgency.provideIntelligence(),CHECK_NO_ACTIVITY_FUNCTION); + } +} diff --git a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/extension/ActionExtensionHelper.java b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/extension/ActionExtensionHelper.java index e2b143f848..58a4705543 100644 --- a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/extension/ActionExtensionHelper.java +++ b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/extension/ActionExtensionHelper.java @@ -34,7 +34,6 @@ public final class ActionExtensionHelper { public static org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action processAlienAction(final Action action, final OpenflowVersion ofVersion, final ActionPath actionPath) { ConvertorActionFromOFJava convertor = null; - org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action alienAction = null; final ExtensionConverterProvider extensionConvertorProvider = OFSessionUtil.getExtensionConvertorProvider(); if (extensionConvertorProvider == null) { @@ -58,10 +57,6 @@ public final class ActionExtensionHelper { convertor = extensionConvertorProvider.getActionConverter(key); } - if (convertor != null) { - alienAction = convertor.convert(action, actionPath); - } - - return alienAction; + return convertor != null ? convertor.convert(action, actionPath) : null; } } diff --git a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/MeterConvertor.java b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/MeterConvertor.java index 41c909b03b..2e72405ffc 100644 --- a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/MeterConvertor.java +++ b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/MeterConvertor.java @@ -155,7 +155,6 @@ public class MeterConvertor extends Convertor bands = new ArrayList<>(); if (source instanceof AddMeterInput) { meterModInputBuilder.setCommand(MeterModCommand.OFPMCADD); @@ -182,6 +181,7 @@ public class MeterConvertor extends Convertor bands = new ArrayList<>(); getBandsFromSAL(source.getMeterBandHeaders(), bands); meterModInputBuilder.setBands(bands); } else { diff --git a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/common/IpConversionUtil.java b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/common/IpConversionUtil.java index 7aa60281d6..63aa80a6aa 100644 --- a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/common/IpConversionUtil.java +++ b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/common/IpConversionUtil.java @@ -285,14 +285,13 @@ public final class IpConversionUtil { List partsV6Address = PERCENT_SPLITTER.splitToList(ipv6Address); int colonp; - char ch; boolean sawXdigit; /* Isn't it fun - the above variable names are the same in BSD and Sun sources */ char[] src = partsV6Address.get(0).toCharArray(); - byte[] dst = new byte[INADDR6SZ]; + final byte[] dst = new byte[INADDR6SZ]; colonp = -1; int index1 = 0; @@ -315,7 +314,7 @@ public final class IpConversionUtil { int srcLength = src.length; int val = 0; while (index1 < srcLength) { - ch = src[index1++]; + final char ch = src[index1++]; int chval = Character.digit(ch, 16); /* Business as usual - ipv6 address digit. @@ -444,16 +443,13 @@ public final class IpConversionUtil { int colonp; - char ch; boolean sawXdigit; /* Isn't it fun - the above variable names are the same in BSD and Sun sources */ char[] src = partsV6Prefix.get(0).toCharArray(); - byte[] dst = new byte[INADDR6SZ + 1]; - - int mask = initialMask; + final byte[] dst = new byte[INADDR6SZ + 1]; colonp = -1; int index1 = 0; @@ -473,10 +469,11 @@ public final class IpConversionUtil { int curtok = index1; sawXdigit = false; + int mask = initialMask; int srcLength = src.length; int val = 0; while (index1 < srcLength) { - ch = src[index1++]; + final char ch = src[index1++]; int chval = Character.digit(ch, 16); /* Business as usual - ipv6 address digit. diff --git a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/match/MatchV10ResponseConvertor.java b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/match/MatchV10ResponseConvertor.java index 662ff0d3a0..93ae5a8fb3 100644 --- a/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/match/MatchV10ResponseConvertor.java +++ b/openflowplugin/src/main/java/org/opendaylight/openflowplugin/openflow/md/core/sal/convertor/match/MatchV10ResponseConvertor.java @@ -65,9 +65,6 @@ public class MatchV10ResponseConvertor extends Convertor