Add HTTP command for modifying global state and client config

- Add several command handlers
- Update cluster state manager

Signed-off-by: Eric Zhao <sczyh16@gmail.com>
This commit is contained in:
Eric Zhao 2018-12-09 22:56:56 +08:00
parent 2d1313f220
commit a5819e092d
8 changed files with 186 additions and 21 deletions

View File

@ -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<String> {
@Override
public CommandResponse<String> handle(CommandRequest request) {
ClusterClientConfig config = new ClusterClientConfig()
.setServerHost(ClusterClientConfigManager.getServerHost())
.setServerPort(ClusterClientConfigManager.getServerPort())
.setRequestTimeout(ClusterClientConfigManager.getRequestTimeout());
return CommandResponse.ofSuccess(JSON.toJSONString(config));
}
}

View File

@ -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<String> {
@Override
public CommandResponse<String> 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");
}
}
}

View File

@ -1 +1,2 @@
com.alibaba.csp.sentinel.command.handler.ModifyClusterClientConfigHandler
com.alibaba.csp.sentinel.command.handler.ModifyClusterClientConfigHandler
com.alibaba.csp.sentinel.command.handler.FetchClusterClientConfigHandler

View File

@ -43,6 +43,8 @@ public final class ClusterStateManager {
private static volatile SentinelProperty<Integer> stateProperty = new DynamicSentinelProperty<Integer>();
private static final PropertyListener<Integer> 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.
* </p>
*/
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.
* </p>
*/
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;
}
}
}

View File

@ -13,7 +13,7 @@
<packaging>jar</packaging>
<properties>
<nacos.version>0.4.0</nacos.version>
<nacos.version>0.2.1</nacos.version>
</properties>
<dependencies>

View File

@ -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<String> {
@Override
public CommandResponse<String> 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;
}
}

View File

@ -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<String> {
@Override
public CommandResponse<String> 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);
}
}
}

View File

@ -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
com.alibaba.csp.sentinel.command.handler.VersionCommandHandler
com.alibaba.csp.sentinel.command.handler.FetchClusterModeCommandHandler
com.alibaba.csp.sentinel.command.handler.ModifyClusterModeCommandHandler