From a5819e092dafaa097606fb37bc7cd8256276882b Mon Sep 17 00:00:00 2001
From: Eric Zhao
Date: Sun, 9 Dec 2018 22:56:56 +0800
Subject: [PATCH] Add HTTP command for modifying global state and client config
- Add several command handlers
- Update cluster state manager
Signed-off-by: Eric Zhao
---
.../FetchClusterClientConfigHandler.java | 42 +++++++++++++++
.../ModifyClusterClientConfigHandler.java | 26 +++++++---
...libaba.csp.sentinel.command.CommandHandler | 3 +-
.../sentinel/cluster/ClusterStateManager.java | 33 +++++++-----
.../sentinel-datasource-nacos/pom.xml | 2 +-
.../FetchClusterModeCommandHandler.java | 51 +++++++++++++++++++
.../ModifyClusterModeCommandHandler.java | 46 +++++++++++++++++
...libaba.csp.sentinel.command.CommandHandler | 4 +-
8 files changed, 186 insertions(+), 21 deletions(-)
create mode 100644 sentinel-cluster/sentinel-cluster-client-default/src/main/java/com/alibaba/csp/sentinel/command/handler/FetchClusterClientConfigHandler.java
create mode 100644 sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/FetchClusterModeCommandHandler.java
create mode 100644 sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/ModifyClusterModeCommandHandler.java
diff --git a/sentinel-cluster/sentinel-cluster-client-default/src/main/java/com/alibaba/csp/sentinel/command/handler/FetchClusterClientConfigHandler.java b/sentinel-cluster/sentinel-cluster-client-default/src/main/java/com/alibaba/csp/sentinel/command/handler/FetchClusterClientConfigHandler.java
new file mode 100644
index 00000000..407d7311
--- /dev/null
+++ b/sentinel-cluster/sentinel-cluster-client-default/src/main/java/com/alibaba/csp/sentinel/command/handler/FetchClusterClientConfigHandler.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * Licensed 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 com.alibaba.csp.sentinel.command.handler;
+
+import com.alibaba.csp.sentinel.cluster.client.config.ClusterClientConfig;
+import com.alibaba.csp.sentinel.cluster.client.config.ClusterClientConfigManager;
+import com.alibaba.csp.sentinel.command.CommandHandler;
+import com.alibaba.csp.sentinel.command.CommandRequest;
+import com.alibaba.csp.sentinel.command.CommandResponse;
+import com.alibaba.csp.sentinel.command.annotation.CommandMapping;
+import com.alibaba.fastjson.JSON;
+
+/**
+ * @author Eric Zhao
+ * @since 1.4.0
+ */
+@CommandMapping(name = "cluster/client/fetchConfig")
+public class FetchClusterClientConfigHandler implements CommandHandler {
+
+ @Override
+ public CommandResponse handle(CommandRequest request) {
+ ClusterClientConfig config = new ClusterClientConfig()
+ .setServerHost(ClusterClientConfigManager.getServerHost())
+ .setServerPort(ClusterClientConfigManager.getServerPort())
+ .setRequestTimeout(ClusterClientConfigManager.getRequestTimeout());
+ return CommandResponse.ofSuccess(JSON.toJSONString(config));
+ }
+}
+
diff --git a/sentinel-cluster/sentinel-cluster-client-default/src/main/java/com/alibaba/csp/sentinel/command/handler/ModifyClusterClientConfigHandler.java b/sentinel-cluster/sentinel-cluster-client-default/src/main/java/com/alibaba/csp/sentinel/command/handler/ModifyClusterClientConfigHandler.java
index 5cc5b4f8..8614fb8f 100644
--- a/sentinel-cluster/sentinel-cluster-client-default/src/main/java/com/alibaba/csp/sentinel/command/handler/ModifyClusterClientConfigHandler.java
+++ b/sentinel-cluster/sentinel-cluster-client-default/src/main/java/com/alibaba/csp/sentinel/command/handler/ModifyClusterClientConfigHandler.java
@@ -15,28 +15,42 @@
*/
package com.alibaba.csp.sentinel.command.handler;
+import java.net.URLDecoder;
+
import com.alibaba.csp.sentinel.cluster.client.config.ClusterClientConfig;
import com.alibaba.csp.sentinel.cluster.client.config.ClusterClientConfigManager;
import com.alibaba.csp.sentinel.command.CommandHandler;
import com.alibaba.csp.sentinel.command.CommandRequest;
import com.alibaba.csp.sentinel.command.CommandResponse;
import com.alibaba.csp.sentinel.command.annotation.CommandMapping;
+import com.alibaba.csp.sentinel.log.RecordLog;
+import com.alibaba.csp.sentinel.util.StringUtil;
+import com.alibaba.fastjson.JSON;
/**
* @author Eric Zhao
* @since 1.4.0
*/
-@CommandMapping(name = "modifyClusterConfig")
+@CommandMapping(name = "cluster/client/modifyConfig")
public class ModifyClusterClientConfigHandler implements CommandHandler {
@Override
public CommandResponse handle(CommandRequest request) {
+ String data = request.getParam("data");
+ if (StringUtil.isBlank(data)) {
+ return CommandResponse.ofFailure(new IllegalArgumentException("empty data"));
+ }
+ try {
+ data = URLDecoder.decode(data, "utf-8");
+ RecordLog.info("[ModifyClusterClientConfigHandler] Receiving cluster client config: " + data);
+ ClusterClientConfig clusterClientConfig = JSON.parseObject(data, ClusterClientConfig.class);
+ ClusterClientConfigManager.applyNewConfig(clusterClientConfig);
- // TODO: parse the new config;
- ClusterClientConfig clusterClientConfig = null;
- ClusterClientConfigManager.applyNewConfig(clusterClientConfig);
-
- return CommandResponse.ofSuccess("ok");
+ return CommandResponse.ofSuccess("ok");
+ } catch (Exception e) {
+ RecordLog.warn("[ModifyClusterClientConfigHandler] Decode client cluster config error", e);
+ return CommandResponse.ofFailure(e, "decode client cluster config error");
+ }
}
}
diff --git a/sentinel-cluster/sentinel-cluster-client-default/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.command.CommandHandler b/sentinel-cluster/sentinel-cluster-client-default/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.command.CommandHandler
index a0af73b5..80d3582c 100755
--- a/sentinel-cluster/sentinel-cluster-client-default/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.command.CommandHandler
+++ b/sentinel-cluster/sentinel-cluster-client-default/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.command.CommandHandler
@@ -1 +1,2 @@
-com.alibaba.csp.sentinel.command.handler.ModifyClusterClientConfigHandler
\ No newline at end of file
+com.alibaba.csp.sentinel.command.handler.ModifyClusterClientConfigHandler
+com.alibaba.csp.sentinel.command.handler.FetchClusterClientConfigHandler
\ No newline at end of file
diff --git a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/cluster/ClusterStateManager.java b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/cluster/ClusterStateManager.java
index 2800b2f6..2a27c745 100644
--- a/sentinel-core/src/main/java/com/alibaba/csp/sentinel/cluster/ClusterStateManager.java
+++ b/sentinel-core/src/main/java/com/alibaba/csp/sentinel/cluster/ClusterStateManager.java
@@ -43,6 +43,8 @@ public final class ClusterStateManager {
private static volatile SentinelProperty stateProperty = new DynamicSentinelProperty();
private static final PropertyListener PROPERTY_LISTENER = new ClusterStatePropertyListener();
+ private static final Object UPDATE_LOCK = new Object();
+
static {
InitExecutor.doInit();
stateProperty.addListener(PROPERTY_LISTENER);
@@ -75,9 +77,9 @@ public final class ClusterStateManager {
* it will be turned off. Then the cluster client will be started.
*
*/
- public static void setToClient() {
+ public static boolean setToClient() {
if (mode == CLUSTER_CLIENT) {
- return;
+ return true;
}
mode = CLUSTER_CLIENT;
sleepIfNeeded();
@@ -91,11 +93,14 @@ public final class ClusterStateManager {
if (tokenClient != null) {
tokenClient.start();
RecordLog.info("[ClusterStateManager] Changing cluster mode to client");
+ return true;
} else {
RecordLog.warn("[ClusterStateManager] Cannot change to client (no client SPI found)");
+ return false;
}
} catch (Exception ex) {
RecordLog.warn("[ClusterStateManager] Error when changing cluster mode to client", ex);
+ return false;
}
}
@@ -105,9 +110,9 @@ public final class ClusterStateManager {
* it will be turned off. Then the cluster server will be started.
*
*/
- public static void setToServer() {
+ public static boolean setToServer() {
if (mode == CLUSTER_SERVER) {
- return;
+ return true;
}
mode = CLUSTER_SERVER;
sleepIfNeeded();
@@ -121,11 +126,14 @@ public final class ClusterStateManager {
if (server != null) {
server.start();
RecordLog.info("[ClusterStateManager] Changing cluster mode to server");
+ return true;
} else {
RecordLog.warn("[ClusterStateManager] Cannot change to server (no server SPI found)");
+ return false;
}
} catch (Exception ex) {
RecordLog.warn("[ClusterStateManager] Error when changing cluster mode to server", ex);
+ return false;
}
}
@@ -163,20 +171,21 @@ public final class ClusterStateManager {
public void configUpdate(Integer value) {
applyState(value);
}
+ }
- private synchronized void applyState(Integer state) {
- if (state == null || state < 0) {
- return;
- }
+ public static boolean applyState(Integer state) {
+ if (state == null || state < 0) {
+ return false;
+ }
+ synchronized (UPDATE_LOCK) {
switch (state) {
case CLUSTER_CLIENT:
- setToClient();
- break;
+ return setToClient();
case CLUSTER_SERVER:
- setToServer();
- break;
+ return setToServer();
default:
RecordLog.warn("[ClusterStateManager] Ignoring unknown cluster state: " + state);
+ return false;
}
}
}
diff --git a/sentinel-extension/sentinel-datasource-nacos/pom.xml b/sentinel-extension/sentinel-datasource-nacos/pom.xml
index 54f686d5..dd0b0444 100644
--- a/sentinel-extension/sentinel-datasource-nacos/pom.xml
+++ b/sentinel-extension/sentinel-datasource-nacos/pom.xml
@@ -13,7 +13,7 @@
jar
- 0.4.0
+ 0.2.1
diff --git a/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/FetchClusterModeCommandHandler.java b/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/FetchClusterModeCommandHandler.java
new file mode 100644
index 00000000..11eac68f
--- /dev/null
+++ b/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/FetchClusterModeCommandHandler.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * Licensed 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 com.alibaba.csp.sentinel.command.handler;
+
+import com.alibaba.csp.sentinel.cluster.ClusterStateManager;
+import com.alibaba.csp.sentinel.cluster.client.TokenClientProvider;
+import com.alibaba.csp.sentinel.cluster.server.EmbeddedClusterTokenServerProvider;
+import com.alibaba.csp.sentinel.command.CommandHandler;
+import com.alibaba.csp.sentinel.command.CommandRequest;
+import com.alibaba.csp.sentinel.command.CommandResponse;
+import com.alibaba.csp.sentinel.command.annotation.CommandMapping;
+import com.alibaba.fastjson.JSONObject;
+
+/**
+ * @author Eric Zhao
+ * @since 1.4.0
+ */
+@CommandMapping(name = "getClusterMode")
+public class FetchClusterModeCommandHandler implements CommandHandler {
+
+ @Override
+ public CommandResponse handle(CommandRequest request) {
+ JSONObject res = new JSONObject()
+ .fluentPut("mode", ClusterStateManager.getMode())
+ .fluentPut("lastModified", ClusterStateManager.getLastModified())
+ .fluentPut("clientAvailable", isClusterClientSpiAvailable())
+ .fluentPut("serverAvailable", isClusterServerSpiAvailable());
+ return CommandResponse.ofSuccess(res.toJSONString());
+ }
+
+ private boolean isClusterClientSpiAvailable() {
+ return TokenClientProvider.getClient() != null;
+ }
+
+ private boolean isClusterServerSpiAvailable() {
+ return EmbeddedClusterTokenServerProvider.getServer() != null;
+ }
+}
diff --git a/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/ModifyClusterModeCommandHandler.java b/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/ModifyClusterModeCommandHandler.java
new file mode 100644
index 00000000..1d67292e
--- /dev/null
+++ b/sentinel-transport/sentinel-transport-common/src/main/java/com/alibaba/csp/sentinel/command/handler/ModifyClusterModeCommandHandler.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 1999-2018 Alibaba Group Holding Ltd.
+ *
+ * Licensed 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 com.alibaba.csp.sentinel.command.handler;
+
+import com.alibaba.csp.sentinel.cluster.ClusterStateManager;
+import com.alibaba.csp.sentinel.command.CommandHandler;
+import com.alibaba.csp.sentinel.command.CommandRequest;
+import com.alibaba.csp.sentinel.command.CommandResponse;
+import com.alibaba.csp.sentinel.command.annotation.CommandMapping;
+
+/**
+ * @author Eric Zhao
+ * @since 1.4.0
+ */
+@CommandMapping(name = "setClusterMode")
+public class ModifyClusterModeCommandHandler implements CommandHandler {
+
+ @Override
+ public CommandResponse handle(CommandRequest request) {
+ try {
+ int mode = Integer.valueOf(request.getParam("mode"));
+ if (ClusterStateManager.applyState(mode)) {
+ return CommandResponse.ofSuccess("success");
+ } else {
+ return CommandResponse.ofSuccess("failed");
+ }
+ } catch (NumberFormatException ex) {
+ return CommandResponse.ofFailure(new IllegalArgumentException("invalid mode"));
+ } catch (Exception ex) {
+ return CommandResponse.ofFailure(ex);
+ }
+ }
+}
diff --git a/sentinel-transport/sentinel-transport-common/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.command.CommandHandler b/sentinel-transport/sentinel-transport-common/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.command.CommandHandler
index 1dd95c88..4cd2606e 100755
--- a/sentinel-transport/sentinel-transport-common/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.command.CommandHandler
+++ b/sentinel-transport/sentinel-transport-common/src/main/resources/META-INF/services/com.alibaba.csp.sentinel.command.CommandHandler
@@ -11,4 +11,6 @@ com.alibaba.csp.sentinel.command.handler.ModifyRulesCommandHandler
com.alibaba.csp.sentinel.command.handler.OnOffGetCommandHandler
com.alibaba.csp.sentinel.command.handler.OnOffSetCommandHandler
com.alibaba.csp.sentinel.command.handler.SendMetricCommandHandler
-com.alibaba.csp.sentinel.command.handler.VersionCommandHandler
\ No newline at end of file
+com.alibaba.csp.sentinel.command.handler.VersionCommandHandler
+com.alibaba.csp.sentinel.command.handler.FetchClusterModeCommandHandler
+com.alibaba.csp.sentinel.command.handler.ModifyClusterModeCommandHandler
\ No newline at end of file