From c9e7789769467b79f315c3457f1ff9ba7634392c Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Fri, 15 Mar 2024 15:34:25 +0100 Subject: [PATCH] Remove getreconciliationstate -d parameter The implementation of this command is deeply flawed and does not work for anything but localhost in any reasonable deployment. Remove it. JIRA: OPNFLWPLUG-1128 Change-Id: Id2b9ddcd662177828675c91bdc0590e4d6860439 Signed-off-by: Robert Varga --- applications/southbound-cli/pom.xml | 8 - .../cli/GetReconciliationStateProvider.java | 190 ++---------------- .../resources/OSGI-INF/blueprint/commands.xml | 2 - 3 files changed, 12 insertions(+), 188 deletions(-) diff --git a/applications/southbound-cli/pom.xml b/applications/southbound-cli/pom.xml index 7f96952cc5..24986b3dbc 100644 --- a/applications/southbound-cli/pom.xml +++ b/applications/southbound-cli/pom.xml @@ -13,10 +13,6 @@ bundle - - com.google.code.gson - gson - com.guicedee.services javax.inject @@ -40,10 +36,6 @@ org.opendaylight.yangtools yang-common - - org.opendaylight.infrautils - diagstatus-api - org.opendaylight.openflowplugin openflowplugin-api 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/GetReconciliationStateProvider.java index b942d1df0c..6edce23129 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/GetReconciliationStateProvider.java @@ -7,110 +7,38 @@ */ package org.opendaylight.openflowplugin.applications.southboundcli.cli; -import com.google.common.net.InetAddresses; -import com.google.gson.Gson; -import com.google.gson.JsonElement; -import com.google.gson.JsonParser; -import com.google.gson.reflect.TypeToken; -import java.lang.reflect.Type; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpResponse; -import java.nio.charset.StandardCharsets; -import java.time.Duration; import java.util.ArrayList; -import java.util.Base64; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; import org.apache.karaf.shell.commands.Command; -import org.apache.karaf.shell.commands.Option; import org.apache.karaf.shell.console.OsgiCommandSupport; -import org.eclipse.jdt.annotation.Nullable; -import org.opendaylight.infrautils.diagstatus.ClusterMemberInfo; import org.opendaylight.openflowplugin.applications.frm.ReconciliationJMXServiceMBean; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; @Command(scope = "openflow", name = "getreconciliationstate", description = "Print reconciliation state for all devices") public class GetReconciliationStateProvider extends OsgiCommandSupport { - private static final Logger LOG = LoggerFactory.getLogger(GetReconciliationStateProvider.class); - - // FIXME: this is fugly: it is an unexpressed dependency on FRM bean as well as Jolokia - private static final String URL_PREFIX = "http://"; - private static final String URL_SEPARATOR = "/"; - private static final String URL_SEPARATOR_COLON = ":"; - private static final String HTTP_JOL_OKIA_BASE_URI = "/jolokia/exec/"; - private static final int HTTP_TIMEOUT = 5000; - private static final String JMX_OBJECT_NAME = "org.opendaylight.openflowplugin.frm:type=ReconciliationState"; - private static final String JMX_ATTRIBUTE_NAME = "acquireReconciliationStates"; - // FIXME: hard-coded credentials - private static final String JMX_REST_HTTP_AUTH_UNAME_PWD = "admin:admin"; - - @Option(name = "-d", description = "Node Id") - String nodeId; - - private final Integer httpPort; private final ReconciliationJMXServiceMBean reconciliationJMXServiceMBean; - private final ClusterMemberInfo clusterMemberInfoProvider; - public GetReconciliationStateProvider(final ReconciliationJMXServiceMBean reconciliationJMXServiceMBean, - final ClusterMemberInfo clusterMemberInfoProvider, - final @Nullable Integer httpPort) { + public GetReconciliationStateProvider(final ReconciliationJMXServiceMBean reconciliationJMXServiceMBean) { this.reconciliationJMXServiceMBean = reconciliationJMXServiceMBean; - this.clusterMemberInfoProvider = clusterMemberInfoProvider; - this.httpPort = httpPort; } @Override protected Object doExecute() { - List result = new ArrayList<>(); - Map reconciliationStates = getClusterwideReconcilitionStates(); - if (nodeId == null) { - if (!reconciliationStates.isEmpty()) { - reconciliationStates.forEach((datapathId, reconciliationState) -> { - String status = String.format("%-17s %-50s", datapathId, reconciliationState); - result.add(status); - }); - printReconciliationStates(result); - } else { - session.getConsole().println("Reconciliation data not available"); - } - } - else { - String reconciliationState = getReconciliationStateForNode(); - if (reconciliationState != null) { - String status = String.format("%-17s %-50s", nodeId, reconciliationState); + final var reconciliationStates = reconciliationJMXServiceMBean.acquireReconciliationStates(); + if (!reconciliationStates.isEmpty()) { + final var result = new ArrayList(); + reconciliationStates.forEach((datapathId, reconciliationState) -> { + String status = String.format("%-17s %-50s", datapathId, reconciliationState); result.add(status); - printReconciliationStates(result); - } else { - session.getConsole().println("Reconciliation data not available for the specified node"); - } + }); + session.getConsole().println(getHeaderOutput()); + session.getConsole().println(getLineSeparator()); + result.stream().forEach(p -> session.getConsole().println(p)); + } else { + session.getConsole().println("Reconciliation data not available"); } return null; } - private String getReconciliationStateForNode() { - //first checking reconciliation state locally - String reconciliationState = reconciliationJMXServiceMBean.acquireReconciliationStates().get(nodeId); - if (reconciliationState == null) { - //checking reconciliation state in the cluster - reconciliationState = getClusterwideReconcilitionStates().get(nodeId); - } - return reconciliationState; - } - - private void printReconciliationStates(final List result) { - session.getConsole().println(getHeaderOutput()); - session.getConsole().println(getLineSeparator()); - result.stream().forEach(p -> session.getConsole().println(p)); - } - private static String getHeaderOutput() { return String.format("%-17s %-25s %-25s", "DatapathId", "Reconciliation Status", "Reconciliation Time"); } @@ -118,98 +46,4 @@ public class GetReconciliationStateProvider extends OsgiCommandSupport { private static String getLineSeparator() { return "-------------------------------------------------------------------"; } - - @SuppressWarnings("IllegalCatch") - private Map getClusterwideReconcilitionStates() { - Map clusterwideReconcStates = new HashMap<>(); - List clusterIPAddresses = clusterMemberInfoProvider.getClusterMembers().stream() - .map(InetAddress::getHostAddress).collect(Collectors.toList()); - LOG.debug("The ip address of nodes in the cluster : {}", clusterIPAddresses); - if (!clusterIPAddresses.isEmpty()) { - String selfAddress = clusterMemberInfoProvider.getSelfAddress() != null - ? clusterMemberInfoProvider.getSelfAddress().getHostAddress() : "localhost"; - LOG.trace("The ip address of local node is {}", selfAddress); - for (String memberAddress : clusterIPAddresses) { - try { - if (memberAddress.equals(selfAddress)) { - clusterwideReconcStates.putAll(getLocalStatusSummary()); - } else { - clusterwideReconcStates.putAll(getRemoteReconciliationStates(memberAddress)); - } - } catch (Exception e) { - LOG.error("Exception while reaching Host {}", memberAddress, e); - } - } - } else { - LOG.info("Could not obtain cluster members or the cluster-command is being executed locally\n"); - } - return clusterwideReconcStates; - } - - @SuppressWarnings("IllegalCatch") - private Map getRemoteReconciliationStates(final String ipAddress) { - Map jmxReconciliationStates = new HashMap<>(); - try { - String getReconcilationRemoteResponse = invokeRemoteRestOperation(ipAddress); - if (getReconcilationRemoteResponse != null) { - JsonElement rootObj = JsonParser.parseString(getReconcilationRemoteResponse); - String remoteJMXOperationResult = rootObj.getAsJsonObject().get("value").toString(); - Type type = new TypeToken>() {}.getType(); - jmxReconciliationStates.putAll(new Gson().fromJson(remoteJMXOperationResult, type)); - } - } catch (Exception e) { - LOG.error("Exception during reconciliation states from device with ip address {}", ipAddress, e); - } - return jmxReconciliationStates; - } - - private Map getLocalStatusSummary() { - return reconciliationJMXServiceMBean.acquireReconciliationStates(); - } - - private String invokeRemoteRestOperation(final String ipAddress) throws Exception { - String restUrl = buildRemoteReconcilationUrl(ipAddress); - LOG.info("invokeRemoteReconcilationState() REST URL: {}", restUrl); - String authString = JMX_REST_HTTP_AUTH_UNAME_PWD; - String authStringEnc = Base64.getEncoder().encodeToString(authString.getBytes(StandardCharsets.UTF_8)); - HttpRequest request = HttpRequest.newBuilder(URI.create(restUrl)) - .timeout(Duration.ofMillis(HTTP_TIMEOUT)) - .header("Authorization", "Basic " + authStringEnc) - .header("Accept", "application/json") - .GET() - .build(); - - LOG.debug("sending http request for accessing remote reconcilation"); - HttpResponse response = HttpClient.newBuilder() - .connectTimeout(request.timeout().orElseThrow().plusMillis(1000)) - .build() - .send(request, HttpResponse.BodyHandlers.ofString()); - // Response code for success should be 200 - Integer httpResponseCode = response.statusCode(); - LOG.debug("http response received for remote reconcilation {}", httpResponseCode); - String respStr = response.body(); - if (httpResponseCode > 299) { - LOG.error("Non-200 http response code received {} for URL {}", httpResponseCode, restUrl); - if (respStr == null || respStr.isEmpty()) { - return "Service Status Retrieval failed. HTTP Response Code : " + httpResponseCode + "\n"; - } - } - LOG.trace("HTTP Response is - {} for URL {}", respStr, restUrl); - - return respStr; - } - - - String buildRemoteReconcilationUrl(final String host) { - String targetHostAsString; - InetAddress hostInetAddress = InetAddresses.forString(host); - if (hostInetAddress instanceof Inet6Address) { - targetHostAsString = '[' + hostInetAddress.getHostAddress() + ']'; - } else { - targetHostAsString = hostInetAddress.getHostAddress(); - } - return new StringBuilder().append(URL_PREFIX).append(targetHostAsString).append(URL_SEPARATOR_COLON) - .append(httpPort).append(HTTP_JOL_OKIA_BASE_URI).append(JMX_OBJECT_NAME) - .append(URL_SEPARATOR).append(JMX_ATTRIBUTE_NAME).toString(); - } } \ No newline at end of file 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 index ab5e08badd..6c68e0924a 100644 --- a/applications/southbound-cli/src/main/resources/OSGI-INF/blueprint/commands.xml +++ b/applications/southbound-cli/src/main/resources/OSGI-INF/blueprint/commands.xml @@ -46,8 +46,6 @@ - - -- 2.36.6