geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jinmeil...@apache.org
Subject [geode] branch develop updated: GEODE-3946: add version check when connect to cluster using gfsh (#1259)
Date Thu, 11 Jan 2018 03:29:09 GMT
This is an automated email from the ASF dual-hosted git repository.

jinmeiliao pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git


The following commit(s) were added to refs/heads/develop by this push:
     new c1c7e51  GEODE-3946: add version check when connect to cluster using gfsh (#1259)
c1c7e51 is described below

commit c1c7e51e4b112c4d18e46589ac8f757325e6580f
Author: jinmeiliao <jiliao@pivotal.io>
AuthorDate: Wed Jan 10 19:29:07 2018 -0800

    GEODE-3946: add version check when connect to cluster using gfsh (#1259)
---
 .../org/apache/geode/management/MemberMXBean.java  | 10 ++++-
 .../management/internal/beans/MemberMBean.java     |  5 +++
 .../internal/beans/MemberMBeanBridge.java          |  4 ++
 .../internal/cli/commands/ConnectCommand.java      | 27 +++++++++++-
 .../converters/ConnectionEndpointConverter.java    | 43 ------------------
 .../internal/cli/shell/JmxOperationInvoker.java    |  4 ++
 .../internal/cli/shell/OperationInvoker.java       |  2 +
 .../web/controllers/ShellCommandsController.java   |  6 +++
 .../internal/web/shell/HttpOperationInvoker.java   |  5 +++
 .../cli/commands/ConnectCommandDUnitTest.java      | 51 ++++++++++++++++++++++
 .../internal/cli/commands/ConnectCommandTest.java  | 39 ++++++++++++++++-
 .../test/dunit/standalone/VersionManager.java      |  3 ++
 12 files changed, 152 insertions(+), 47 deletions(-)

diff --git a/geode-core/src/main/java/org/apache/geode/management/MemberMXBean.java b/geode-core/src/main/java/org/apache/geode/management/MemberMXBean.java
index 15a309c..a240106 100644
--- a/geode-core/src/main/java/org/apache/geode/management/MemberMXBean.java
+++ b/geode-core/src/main/java/org/apache/geode/management/MemberMXBean.java
@@ -286,11 +286,19 @@ public interface MemberMXBean {
   String status();
 
   /**
-   * Returns the GemFire version.
+   * Returns the GemFire version, including build id, jdk version, product name and release
version
+   * etc.
    */
+  @ResourceOperation()
   String getVersion();
 
   /**
+   * returns only the version string
+   */
+  @ResourceOperation()
+  String getReleaseVersion();
+
+  /**
    * Returns whether this member is attached to at least one Locator.
    *
    * @return True if this member is attached to a Locator, false otherwise.
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBean.java
b/geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBean.java
index b05258f..f068efe 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBean.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBean.java
@@ -356,6 +356,11 @@ public class MemberMBean extends NotificationBroadcasterSupport implements
Membe
   }
 
   @Override
+  public String getReleaseVersion() {
+    return bridge.getReleaseVersion();
+  }
+
+  @Override
   public boolean hasGatewayReceiver() {
     return bridge.hasGatewayReceiver();
   }
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBeanBridge.java
b/geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBeanBridge.java
index 0b340fd..485e194 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBeanBridge.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/beans/MemberMBeanBridge.java
@@ -1786,4 +1786,8 @@ public class MemberMBeanBridge {
   public long getUsedMemory() {
     return getVMStatistic(StatsKey.VM_USED_MEMORY).longValue() / MBFactor;
   }
+
+  public String getReleaseVersion() {
+    return GemFireVersion.getGemFireVersion();
+  }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConnectCommand.java
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConnectCommand.java
index 789acf3..47b6f73 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConnectCommand.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConnectCommand.java
@@ -64,6 +64,7 @@ import org.apache.geode.management.internal.cli.result.InfoResultData;
 import org.apache.geode.management.internal.cli.result.ResultBuilder;
 import org.apache.geode.management.internal.cli.shell.Gfsh;
 import org.apache.geode.management.internal.cli.shell.JmxOperationInvoker;
+import org.apache.geode.management.internal.cli.shell.OperationInvoker;
 import org.apache.geode.management.internal.cli.util.ConnectionEndpoint;
 import org.apache.geode.management.internal.security.ResourceConstants;
 import org.apache.geode.management.internal.web.shell.HttpOperationInvoker;
@@ -157,7 +158,31 @@ public class ConnectCommand implements GfshCommand {
       result = jmxConnect(gfProperties, useSsl, jmxManagerEndPoint, locatorEndPoint, false);
     }
 
-    return result;
+    OperationInvoker invoker = gfsh.getOperationInvoker();
+    if (invoker == null || !invoker.isConnected()) {
+      return result;
+    }
+
+    String gfshVersion = gfsh.getVersion();
+    String remoteVersion = null;
+    try {
+      remoteVersion = invoker.getRemoteVersion();
+      if (remoteVersion.equalsIgnoreCase(gfshVersion)) {
+        return result;
+      }
+    } catch (Exception e) {
+      gfsh.logInfo("failed to get the the remote version.", e);
+    }
+
+    // will reach here only when remoteVersion is not available or does not match
+    invoker.stop();
+    if (remoteVersion == null) {
+      return ResultBuilder.createUserErrorResult(
+          String.format("Cannot use a %s gfsh client to connect to this cluster.", gfshVersion));
+    } else {
+      return ResultBuilder.createUserErrorResult(String.format(
+          "Cannot use a %s gfsh client to connect to a %s cluster.", gfshVersion, remoteVersion));
+    }
   }
 
   /**
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/converters/ConnectionEndpointConverter.java
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/converters/ConnectionEndpointConverter.java
index ce2965c..208a24a 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/converters/ConnectionEndpointConverter.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/converters/ConnectionEndpointConverter.java
@@ -102,47 +102,4 @@ public class ConnectionEndpointConverter implements Converter<ConnectionEndpoint
 
     return completions.size() > 0;
   }
-
-  public static void main(String[] args) {
-    ConnectionEndpointConverter cec = new ConnectionEndpointConverter();
-
-    try {
-      System.out.println(cec.convertFromText("halibut[2555]", null, null));
-    } catch (Exception e) {
-      e.printStackTrace();
-    }
-
-    try {
-      System.out.println(cec.convertFromText("halibut.pune.gemstone.com[2555]", null, null));
-    } catch (Exception e) {
-      e.printStackTrace();
-    }
-
-    try {
-      System.out.println(cec.convertFromText("halibut[]", null, null));
-    } catch (Exception e) {
-      e.printStackTrace();
-    }
-
-    try {
-      System.out.println(cec.convertFromText("halibut2555]", null, null));
-    } catch (Exception e) {
-      e.printStackTrace();
-    }
-
-    try {
-      System.out.println(cec.convertFromText("halibut[", null, null));
-    } catch (Exception e) {
-      e.printStackTrace();
-    }
-
-    try {
-      System.out.println(cec.convertFromText("halibut", null, null));
-    } catch (Exception e) {
-      e.printStackTrace();
-    }
-
-
-  }
-
 }
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/JmxOperationInvoker.java
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/JmxOperationInvoker.java
index 963ce75..538019b 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/JmxOperationInvoker.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/JmxOperationInvoker.java
@@ -212,6 +212,10 @@ public class JmxOperationInvoker implements OperationInvoker {
     }
   }
 
+  public String getRemoteVersion() {
+    return memberMXBeanProxy.getReleaseVersion();
+  }
+
   @Override
   public Object invoke(String resourceName, String operationName, Object[] params,
       String[] signature) throws JMXInvocationException {
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/OperationInvoker.java
b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/OperationInvoker.java
index cf235e9..44ab84a 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/OperationInvoker.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/shell/OperationInvoker.java
@@ -129,6 +129,8 @@ public interface OperationInvoker {
    */
   public Set<ObjectName> queryNames(ObjectName objectName, QueryExp queryExpression);
 
+  public String getRemoteVersion();
+
   /**
    * Processes the requested command. Sends the command to the GemFire Manager for remote
processing
    * (execution). NOTE refactoring return type in favor of covariant return types.
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/ShellCommandsController.java
b/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/ShellCommandsController.java
index 39b0753..6b2d5f9 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/ShellCommandsController.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/web/controllers/ShellCommandsController.java
@@ -133,6 +133,12 @@ public class ShellCommandsController extends AbstractCommandsController
{
     return GemFireVersion.asString();
   }
 
+  @RequestMapping(method = RequestMethod.GET, value = "/version/release")
+  @ResponseBody
+  public String releaseVersion() {
+    return GemFireVersion.getGemFireVersion();
+  }
+
 
   private ResponseEntity<InputStreamResource> getResponse(String result) {
     CommandResult commandResult = ResultBuilder.fromJson(result);
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/web/shell/HttpOperationInvoker.java
b/geode-core/src/main/java/org/apache/geode/management/internal/web/shell/HttpOperationInvoker.java
index 056cf55..88f7452 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/web/shell/HttpOperationInvoker.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/web/shell/HttpOperationInvoker.java
@@ -405,6 +405,11 @@ public class HttpOperationInvoker implements OperationInvoker {
     return String.format("GemFire Manager HTTP service @ %1$s", httpRequester);
   }
 
+  public String getRemoteVersion() {
+    final URI link = HttpRequester.createURI(baseUrl, "/version/release");
+    return httpRequester.get(link, String.class);
+  }
+
 
   /**
    * Processes the requested command. Sends the command to the GemFire Manager for remote
processing
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ConnectCommandDUnitTest.java
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ConnectCommandDUnitTest.java
new file mode 100644
index 0000000..689ac59
--- /dev/null
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ConnectCommandDUnitTest.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information
regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version
2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain
a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under
the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
express
+ * or implied. See the License for the specific language governing permissions and limitations
under
+ * the License.
+ */
+
+package org.apache.geode.management.internal.cli.commands;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.util.Properties;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.test.dunit.rules.ClusterStartupRule;
+import org.apache.geode.test.dunit.rules.MemberVM;
+import org.apache.geode.test.dunit.standalone.VersionManager;
+import org.apache.geode.test.junit.categories.DistributedTest;
+import org.apache.geode.test.junit.rules.GfshCommandRule;
+
+
+@Category(DistributedTest.class)
+public class ConnectCommandDUnitTest {
+
+  @Rule
+  public ClusterStartupRule cluster = new ClusterStartupRule();
+
+  @Rule
+  public GfshCommandRule gfsh = new GfshCommandRule();
+
+  @Test
+  public void useCurrentGfshToConnectToOlderLocator() throws Exception {
+    MemberVM locator = cluster.startLocatorVM(0, new Properties(), VersionManager.GEODE_130);
+
+    gfsh.executeAndAssertThat("connect --jmx-manager=localhost[" + locator.getJmxPort() +
"]")
+        .statusIsError().containsOutput("Cannot use a")
+        .containsOutput("gfsh client to connect to this cluster");
+    assertThat(gfsh.getGfsh().getOperationInvoker().isConnected()).isFalse();
+  }
+}
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ConnectCommandTest.java
b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ConnectCommandTest.java
index 084d5ff..7d6eecf 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ConnectCommandTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/cli/commands/ConnectCommandTest.java
@@ -40,6 +40,7 @@ import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.mockito.ArgumentCaptor;
 
+import org.apache.geode.management.cli.Result;
 import org.apache.geode.management.internal.cli.i18n.CliStrings;
 import org.apache.geode.management.internal.cli.result.CommandResult;
 import org.apache.geode.management.internal.cli.shell.Gfsh;
@@ -56,6 +57,7 @@ public class ConnectCommandTest {
   private ConnectCommand connectCommand;
   private Gfsh gfsh;
   private CommandResult result;
+  private OperationInvoker operationInvoker;
   private Properties properties;
   private ArgumentCaptor<File> fileCaptor;
 
@@ -63,12 +65,13 @@ public class ConnectCommandTest {
   public void before() throws Exception {
     properties = new Properties();
     gfsh = mock(Gfsh.class);
-    when(gfsh.getOperationInvoker()).thenReturn(mock(OperationInvoker.class));
+    operationInvoker = mock(OperationInvoker.class);
+    when(gfsh.getOperationInvoker()).thenReturn(operationInvoker);
     // using spy instead of mock because we want to call the real method when we do connect
     connectCommand = spy(ConnectCommand.class);
     when(connectCommand.getGfsh()).thenReturn(gfsh);
     doReturn(properties).when(connectCommand).loadProperties(any());
-    CommandResult result = mock(CommandResult.class);
+    result = mock(CommandResult.class);
     when(connectCommand.httpConnect(any(), any(), anyBoolean())).thenReturn(result);
     when(connectCommand.jmxConnect(any(), anyBoolean(), any(), any(), anyBoolean()))
         .thenReturn(result);
@@ -297,4 +300,36 @@ public class ConnectCommandTest {
     assertThat(properties.getProperty(SSL_KEYSTORE)).isEqualTo("keystore2");
     assertThat(properties.getProperty(SSL_KEYSTORE_PASSWORD)).isEqualTo("password");
   }
+
+  @Test
+  public void connectToManagerWithDifferentVersion() {
+    when(gfsh.getVersion()).thenReturn("1.2");
+    when(operationInvoker.getRemoteVersion()).thenReturn("1.3");
+    when(operationInvoker.isConnected()).thenReturn(true);
+    gfshParserRule.executeAndAssertThat(connectCommand, "connect --locator=localhost:4040")
+        .statusIsError()
+        .containsOutput("Cannot use a 1.2 gfsh client to connect to a 1.3 cluster.");
+  }
+
+  @Test
+  public void connectToOlderManagerWithNewerGfsh() {
+    when(gfsh.getVersion()).thenReturn("1.5");
+    when(operationInvoker.getRemoteVersion())
+        .thenThrow(new RuntimeException("release version not available"));
+    when(operationInvoker.isConnected()).thenReturn(true);
+
+    gfshParserRule.executeAndAssertThat(connectCommand, "connect --locator=localhost:4040")
+        .statusIsError().containsOutput("Cannot use a 1.5 gfsh client to connect to this
cluster.");
+  }
+
+  @Test
+  public void connectToAValidManager() {
+    when(gfsh.getVersion()).thenReturn("1.5");
+    when(operationInvoker.getRemoteVersion()).thenReturn("1.5");
+    when(operationInvoker.isConnected()).thenReturn(true);
+
+    when(result.getStatus()).thenReturn(Result.Status.OK);
+    gfshParserRule.executeAndAssertThat(connectCommand, "connect --locator=localhost:4040")
+        .statusIsSuccess();
+  }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/VersionManager.java
b/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/VersionManager.java
index 6cf7bd0..f13718b 100755
--- a/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/VersionManager.java
+++ b/geode-core/src/test/java/org/apache/geode/test/dunit/standalone/VersionManager.java
@@ -38,6 +38,9 @@ import org.apache.geode.test.dunit.Host;
  */
 public class VersionManager {
   public static final String CURRENT_VERSION = "000";
+  public static final String GEODE_110 = "110";
+  public static final String GEODE_120 = "120";
+  public static final String GEODE_130 = "130";
 
   private static VersionManager instance;
 

-- 
To stop receiving notification emails like this one, please contact
['"commits@geode.apache.org" <commits@geode.apache.org>'].

Mime
View raw message