dashboard: refinement and support HTTP POST request for update operations in SentinelApiClient (#620)
* Restructure: SentinelApiClient to support posting and refine it to make it simple * Enhancement: SentinelVersion parsing logic * Bug fix: comparison bug of SentinelVersion
This commit is contained in:
parent
73f166e258
commit
359e65932c
|
|
@ -16,54 +16,67 @@
|
||||||
package com.alibaba.csp.sentinel.dashboard.client;
|
package com.alibaba.csp.sentinel.dashboard.client;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.alibaba.csp.sentinel.command.CommandConstants;
|
import com.alibaba.csp.sentinel.command.CommandConstants;
|
||||||
import com.alibaba.csp.sentinel.config.SentinelConfig;
|
import com.alibaba.csp.sentinel.config.SentinelConfig;
|
||||||
import com.alibaba.csp.sentinel.command.vo.NodeVo;
|
import com.alibaba.csp.sentinel.command.vo.NodeVo;
|
||||||
import com.alibaba.csp.sentinel.dashboard.util.AsyncUtils;
|
import com.alibaba.csp.sentinel.dashboard.util.AsyncUtils;
|
||||||
|
import com.alibaba.csp.sentinel.slots.block.Rule;
|
||||||
|
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
|
||||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
|
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
|
||||||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
|
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
|
||||||
|
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
|
||||||
import com.alibaba.csp.sentinel.slots.system.SystemRule;
|
import com.alibaba.csp.sentinel.slots.system.SystemRule;
|
||||||
import com.alibaba.csp.sentinel.util.AssertUtil;
|
import com.alibaba.csp.sentinel.util.AssertUtil;
|
||||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
import com.alibaba.csp.sentinel.util.StringUtil;
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.csp.sentinel.dashboard.datasource.entity.SentinelVersion;
|
||||||
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity;
|
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.AuthorityRuleEntity;
|
||||||
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity;
|
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.DegradeRuleEntity;
|
||||||
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
|
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
|
||||||
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleEntity;
|
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.ParamFlowRuleEntity;
|
||||||
|
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.RuleEntity;
|
||||||
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.SystemRuleEntity;
|
import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.SystemRuleEntity;
|
||||||
|
import com.alibaba.csp.sentinel.dashboard.discovery.AppManagement;
|
||||||
import com.alibaba.csp.sentinel.dashboard.domain.cluster.ClusterClientInfoVO;
|
import com.alibaba.csp.sentinel.dashboard.domain.cluster.ClusterClientInfoVO;
|
||||||
import com.alibaba.csp.sentinel.dashboard.domain.cluster.state.ClusterServerStateVO;
|
import com.alibaba.csp.sentinel.dashboard.domain.cluster.state.ClusterServerStateVO;
|
||||||
import com.alibaba.csp.sentinel.dashboard.domain.cluster.state.ClusterStateSimpleEntity;
|
import com.alibaba.csp.sentinel.dashboard.domain.cluster.state.ClusterStateSimpleEntity;
|
||||||
import com.alibaba.csp.sentinel.dashboard.domain.cluster.config.ClusterClientConfig;
|
import com.alibaba.csp.sentinel.dashboard.domain.cluster.config.ClusterClientConfig;
|
||||||
import com.alibaba.csp.sentinel.dashboard.domain.cluster.config.ServerFlowConfig;
|
import com.alibaba.csp.sentinel.dashboard.domain.cluster.config.ServerFlowConfig;
|
||||||
import com.alibaba.csp.sentinel.dashboard.domain.cluster.config.ServerTransportConfig;
|
import com.alibaba.csp.sentinel.dashboard.domain.cluster.config.ServerTransportConfig;
|
||||||
import com.alibaba.csp.sentinel.dashboard.util.RuleUtils;
|
import com.alibaba.csp.sentinel.dashboard.util.VersionUtils;
|
||||||
|
|
||||||
import org.apache.http.HttpResponse;
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.NameValuePair;
|
||||||
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
import org.apache.http.client.methods.HttpGet;
|
import org.apache.http.client.methods.HttpGet;
|
||||||
import org.apache.http.client.utils.URIBuilder;
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.client.methods.HttpUriRequest;
|
||||||
import org.apache.http.concurrent.FutureCallback;
|
import org.apache.http.concurrent.FutureCallback;
|
||||||
import org.apache.http.entity.ContentType;
|
import org.apache.http.entity.ContentType;
|
||||||
import org.apache.http.impl.client.DefaultRedirectStrategy;
|
import org.apache.http.impl.client.DefaultRedirectStrategy;
|
||||||
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
|
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
|
||||||
import org.apache.http.impl.nio.client.HttpAsyncClients;
|
import org.apache.http.impl.nio.client.HttpAsyncClients;
|
||||||
import org.apache.http.impl.nio.reactor.IOReactorConfig;
|
import org.apache.http.impl.nio.reactor.IOReactorConfig;
|
||||||
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
import org.apache.http.util.EntityUtils;
|
import org.apache.http.util.EntityUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -73,7 +86,6 @@ import org.springframework.stereotype.Component;
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class SentinelApiClient {
|
public class SentinelApiClient {
|
||||||
|
|
||||||
private static Logger logger = LoggerFactory.getLogger(SentinelApiClient.class);
|
private static Logger logger = LoggerFactory.getLogger(SentinelApiClient.class);
|
||||||
|
|
||||||
private static final Charset DEFAULT_CHARSET = Charset.forName(SentinelConfig.charset());
|
private static final Charset DEFAULT_CHARSET = Charset.forName(SentinelConfig.charset());
|
||||||
|
|
@ -104,7 +116,10 @@ public class SentinelApiClient {
|
||||||
|
|
||||||
private CloseableHttpAsyncClient httpClient;
|
private CloseableHttpAsyncClient httpClient;
|
||||||
|
|
||||||
private final boolean enableHttps = false;
|
private static final SentinelVersion version160 = new SentinelVersion(1, 6, 0);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AppManagement appManagement;
|
||||||
|
|
||||||
public SentinelApiClient() {
|
public SentinelApiClient() {
|
||||||
IOReactorConfig ioConfig = IOReactorConfig.custom().setConnectTimeout(3000).setSoTimeout(10000)
|
IOReactorConfig ioConfig = IOReactorConfig.custom().setConnectTimeout(3000).setSoTimeout(10000)
|
||||||
|
|
@ -121,89 +136,55 @@ public class SentinelApiClient {
|
||||||
private boolean isSuccess(int statusCode) {
|
private boolean isSuccess(int statusCode) {
|
||||||
return statusCode >= 200 && statusCode < 300;
|
return statusCode >= 200 && statusCode < 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isCommandNotFound(int statusCode, String body) {
|
private boolean isCommandNotFound(int statusCode, String body) {
|
||||||
return statusCode == 400 && StringUtil.isNotEmpty(body) && body.contains(CommandConstants.MSG_UNKNOWN_COMMAND_PREFIX);
|
return statusCode == 400 && StringUtil.isNotEmpty(body) && body.contains(CommandConstants.MSG_UNKNOWN_COMMAND_PREFIX);
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompletableFuture<String> executeCommand(String command, URI uri) {
|
private StringBuilder queryString(Map<String, String> params) {
|
||||||
CompletableFuture<String> future = new CompletableFuture<>();
|
StringBuilder queryStringBuilder = new StringBuilder();
|
||||||
if (StringUtil.isBlank(command) || uri == null) {
|
for (Entry<String, String> entry : params.entrySet()) {
|
||||||
future.completeExceptionally(new IllegalArgumentException("Bad URL or command name"));
|
if (StringUtil.isEmpty(entry.getValue())) {
|
||||||
return future;
|
continue;
|
||||||
|
}
|
||||||
|
String name = urlEncode(entry.getKey());
|
||||||
|
String value = urlEncode(entry.getValue());
|
||||||
|
if (name != null && value != null) {
|
||||||
|
if (queryStringBuilder.length() > 0) {
|
||||||
|
queryStringBuilder.append('&');
|
||||||
|
}
|
||||||
|
queryStringBuilder.append(name).append('=').append(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
final HttpGet httpGet = new HttpGet(uri);
|
return queryStringBuilder;
|
||||||
httpClient.execute(httpGet, new FutureCallback<HttpResponse>() {
|
|
||||||
@Override
|
|
||||||
public void completed(final HttpResponse response) {
|
|
||||||
int statusCode = response.getStatusLine().getStatusCode();
|
|
||||||
try {
|
|
||||||
String value = getBody(response);
|
|
||||||
if (isSuccess(statusCode)) {
|
|
||||||
future.complete(value);
|
|
||||||
} else {
|
|
||||||
if (isCommandNotFound(statusCode, value)) {
|
|
||||||
future.completeExceptionally(new CommandNotFoundException(command));
|
|
||||||
} else {
|
|
||||||
future.completeExceptionally(new CommandFailedException(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception ex) {
|
|
||||||
future.completeExceptionally(ex);
|
|
||||||
logger.error("HTTP request failed: " + uri.toString(), ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void failed(final Exception ex) {
|
|
||||||
future.completeExceptionally(ex);
|
|
||||||
logger.error("HTTP request failed: " + uri.toString(), ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cancelled() {
|
|
||||||
future.complete(null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return future;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String httpGetContent(String url) {
|
private HttpUriRequest postRequest(String url, Map<String, String> params) {
|
||||||
final HttpGet httpGet = new HttpGet(url);
|
HttpPost httpPost = new HttpPost(url);
|
||||||
final CountDownLatch latch = new CountDownLatch(1);
|
if (params != null && params.size() > 0) {
|
||||||
final AtomicReference<String> reference = new AtomicReference<>();
|
List<NameValuePair> list = new ArrayList<>(params.size());
|
||||||
httpClient.execute(httpGet, new FutureCallback<HttpResponse>() {
|
for (Entry<String, String> entry : params.entrySet()) {
|
||||||
@Override
|
list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
|
||||||
public void completed(final HttpResponse response) {
|
|
||||||
try {
|
|
||||||
reference.set(getBody(response));
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.info("httpGetContent " + url + " error:", e);
|
|
||||||
} finally {
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
@Override
|
httpPost.setEntity(new UrlEncodedFormEntity(list));
|
||||||
public void failed(final Exception ex) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
latch.countDown();
|
logger.warn("httpPostContent encode entity error: {}", params, e);
|
||||||
logger.info("httpGetContent " + url + " failed:", ex);
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
@Override
|
return httpPost;
|
||||||
public void cancelled() {
|
}
|
||||||
latch.countDown();
|
|
||||||
}
|
private String urlEncode(String str) {
|
||||||
});
|
|
||||||
try {
|
try {
|
||||||
latch.await(5, TimeUnit.SECONDS);
|
return URLEncoder.encode(str, DEFAULT_CHARSET.name());
|
||||||
} catch (Exception e) {
|
} catch (UnsupportedEncodingException e) {
|
||||||
logger.info("wait http client error:", e);
|
logger.info("encode string error: {}", str, e);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return reference.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getBody(HttpResponse response) throws Exception {
|
private String getBody(HttpResponse response) throws Exception {
|
||||||
Charset charset = null;
|
Charset charset = null;
|
||||||
try {
|
try {
|
||||||
|
|
@ -216,25 +197,184 @@ public class SentinelApiClient {
|
||||||
}
|
}
|
||||||
return EntityUtils.toString(response.getEntity(), charset != null ? charset : DEFAULT_CHARSET);
|
return EntityUtils.toString(response.getEntity(), charset != null ? charset : DEFAULT_CHARSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* With no param
|
||||||
|
*
|
||||||
|
* @param ip
|
||||||
|
* @param port
|
||||||
|
* @param api
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private CompletableFuture<String> executeCommand(String ip, int port, String api, boolean useHttpPost) {
|
||||||
|
return executeCommand(ip, port, api, null, useHttpPost);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No app specified, force to GET
|
||||||
|
*
|
||||||
|
* @param ip
|
||||||
|
* @param port
|
||||||
|
* @param api
|
||||||
|
* @param params
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private CompletableFuture<String> executeCommand(String ip, int port, String api, Map<String, String> params, boolean useHttpPost) {
|
||||||
|
return executeCommand(null, ip, port, api, params, useHttpPost);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prefer to execute request using POST
|
||||||
|
*
|
||||||
|
* @param app
|
||||||
|
* @param ip
|
||||||
|
* @param port
|
||||||
|
* @param api
|
||||||
|
* @param params
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private CompletableFuture<String> executeCommand(String app, String ip, int port, String api, Map<String, String> params, boolean useHttpPost) {
|
||||||
|
CompletableFuture<String> future = new CompletableFuture<>();
|
||||||
|
if (StringUtil.isBlank(ip) || StringUtil.isBlank(api)) {
|
||||||
|
future.completeExceptionally(new IllegalArgumentException("Bad URL or command name"));
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
StringBuilder urlBuilder = new StringBuilder();
|
||||||
|
urlBuilder.append("http://");
|
||||||
|
urlBuilder.append(ip).append(':').append(port).append('/').append(api);
|
||||||
|
if (params == null) {
|
||||||
|
params = Collections.emptyMap();
|
||||||
|
}
|
||||||
|
boolean supportPost = StringUtil.isNotEmpty(app) && Optional.ofNullable(appManagement.getDetailApp(app))
|
||||||
|
.flatMap(e -> e.getMachine(ip, port))
|
||||||
|
.flatMap(m -> VersionUtils.parseVersion(m.getVersion())
|
||||||
|
.map(v -> v.greaterOrEqual(version160)))
|
||||||
|
.orElse(false);
|
||||||
|
if (!useHttpPost || !supportPost) {
|
||||||
|
// Using GET in older versions, append parameters after url
|
||||||
|
if (!params.isEmpty()) {
|
||||||
|
if (urlBuilder.indexOf("?") == -1) {
|
||||||
|
urlBuilder.append('?');
|
||||||
|
} else {
|
||||||
|
urlBuilder.append('&');
|
||||||
|
}
|
||||||
|
urlBuilder.append(queryString(params));
|
||||||
|
}
|
||||||
|
return executeCommand(new HttpGet(urlBuilder.toString()));
|
||||||
|
} else {
|
||||||
|
// Using POST
|
||||||
|
return executeCommand(postRequest(urlBuilder.toString(), params));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<String> executeCommand(HttpUriRequest request) {
|
||||||
|
CompletableFuture<String> future = new CompletableFuture<>();
|
||||||
|
httpClient.execute(request, new FutureCallback<HttpResponse>() {
|
||||||
|
@Override
|
||||||
|
public void completed(final HttpResponse response) {
|
||||||
|
int statusCode = response.getStatusLine().getStatusCode();
|
||||||
|
try {
|
||||||
|
String value = getBody(response);
|
||||||
|
if (isSuccess(statusCode)) {
|
||||||
|
future.complete(value);
|
||||||
|
} else {
|
||||||
|
if (isCommandNotFound(statusCode, value)) {
|
||||||
|
future.completeExceptionally(new CommandNotFoundException(request.getURI().getPath()));
|
||||||
|
} else {
|
||||||
|
future.completeExceptionally(new CommandFailedException(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception ex) {
|
||||||
|
future.completeExceptionally(ex);
|
||||||
|
logger.error("HTTP request failed: {}", request.getURI().toString(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void failed(final Exception ex) {
|
||||||
|
future.completeExceptionally(ex);
|
||||||
|
logger.error("HTTP request failed: {}", request.getURI().toString(), ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelled() {
|
||||||
|
future.complete(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
|
||||||
public void close() throws Exception {
|
public void close() throws Exception {
|
||||||
httpClient.close();
|
httpClient.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<NodeVo> fetchResourceOfMachine(String ip, int port, String type) {
|
@Nullable
|
||||||
String url = "http://" + ip + ":" + port + "/" + RESOURCE_URL_PATH + "?type=" + type;
|
private <T> CompletableFuture<List<T>> fetchItemsAsync(String ip, int port, String api, String type, Class<T> ruleType) {
|
||||||
String body = httpGetContent(url);
|
AssertUtil.notEmpty(ip, "Bad machine IP");
|
||||||
if (body == null) {
|
AssertUtil.isTrue(port > 0, "Bad machine port");
|
||||||
|
Map<String, String> params = null;
|
||||||
|
if (StringUtil.isNotEmpty(type)) {
|
||||||
|
params = new HashMap<>(1);
|
||||||
|
params.put("type", type);
|
||||||
|
}
|
||||||
|
return executeCommand(ip, port, api, params, false)
|
||||||
|
.thenApply(json -> JSON.parseArray(json, ruleType));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private <T> List<T> fetchItems(String ip, int port, String api, String type, Class<T> ruleType) {
|
||||||
|
try {
|
||||||
|
AssertUtil.notEmpty(ip, "Bad machine IP");
|
||||||
|
AssertUtil.isTrue(port > 0, "Bad machine port");
|
||||||
|
Map<String, String> params = null;
|
||||||
|
if (StringUtil.isNotEmpty(type)) {
|
||||||
|
params = new HashMap<>(1);
|
||||||
|
params.put("type", type);
|
||||||
|
}
|
||||||
|
return fetchItemsAsync(ip, port, api, type, ruleType).get();
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
logger.error("Error when fetching items from api: {} -> {}", api, type, e);
|
||||||
return null;
|
return null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("Error when fetching items: {} -> {}", api, type, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends Rule> List<T> fetchRules(String ip, int port, String type, Class<T> ruleType) {
|
||||||
|
return fetchItems(ip, port, GET_RULES_PATH, type, ruleType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean setRules(String app, String ip, int port, String type, List<? extends RuleEntity> entities) {
|
||||||
|
if (entities == null) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return JSON.parseArray(body, NodeVo.class);
|
AssertUtil.notEmpty(app, "Bad app name");
|
||||||
|
AssertUtil.notEmpty(ip, "Bad machine IP");
|
||||||
|
AssertUtil.isTrue(port > 0, "Bad machine port");
|
||||||
|
String data = JSON.toJSONString(
|
||||||
|
entities.stream().map(r -> r.toRule()).collect(Collectors.toList()));
|
||||||
|
Map<String, String> params = new HashMap<>(2);
|
||||||
|
params.put("type", type);
|
||||||
|
params.put("data", data);
|
||||||
|
String result = executeCommand(app, ip, port, SET_RULES_PATH, params, true).get();
|
||||||
|
logger.info("setRules: {}", result);
|
||||||
|
return true;
|
||||||
|
} catch (InterruptedException | ExecutionException e) {
|
||||||
|
logger.warn("setRules api failed: {}", type, e);
|
||||||
|
return false;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.info("parse ResourceOfMachine error", e);
|
logger.warn("setRules failed", e);
|
||||||
return null;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<NodeVo> fetchResourceOfMachine(String ip, int port, String type) {
|
||||||
|
return fetchItems(ip, port, RESOURCE_URL_PATH, type, NodeVo.class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch cluster node.
|
* Fetch cluster node.
|
||||||
*
|
*
|
||||||
|
|
@ -248,24 +388,11 @@ public class SentinelApiClient {
|
||||||
if (includeZero) {
|
if (includeZero) {
|
||||||
type = "zero";
|
type = "zero";
|
||||||
}
|
}
|
||||||
String url = "http://" + ip + ":" + port + "/" + CLUSTER_NODE_PATH + "?type=" + type;
|
return fetchItems(ip, port, CLUSTER_NODE_PATH, type, NodeVo.class);
|
||||||
String body = httpGetContent(url);
|
|
||||||
if (body == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return JSON.parseArray(body, NodeVo.class);
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.info("parse ClusterNodeOfMachine error", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<FlowRuleEntity> fetchFlowRuleOfMachine(String app, String ip, int port) {
|
public List<FlowRuleEntity> fetchFlowRuleOfMachine(String app, String ip, int port) {
|
||||||
String url = "http://" + ip + ":" + port + "/" + GET_RULES_PATH + "?type=" + FLOW_RULE_TYPE;
|
List<FlowRule> rules = fetchRules(ip, port, FLOW_RULE_TYPE, FlowRule.class);
|
||||||
String body = httpGetContent(url);
|
|
||||||
logger.info("FlowRule Body:{}", body);
|
|
||||||
List<FlowRule> rules = RuleUtils.parseFlowRule(body);
|
|
||||||
if (rules != null) {
|
if (rules != null) {
|
||||||
return rules.stream().map(rule -> FlowRuleEntity.fromFlowRule(app, ip, port, rule))
|
return rules.stream().map(rule -> FlowRuleEntity.fromFlowRule(app, ip, port, rule))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
@ -275,10 +402,7 @@ public class SentinelApiClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<DegradeRuleEntity> fetchDegradeRuleOfMachine(String app, String ip, int port) {
|
public List<DegradeRuleEntity> fetchDegradeRuleOfMachine(String app, String ip, int port) {
|
||||||
String url = "http://" + ip + ":" + port + "/" + GET_RULES_PATH + "?type=" + DEGRADE_RULE_TYPE;
|
List<DegradeRule> rules = fetchRules(ip, port, DEGRADE_RULE_TYPE, DegradeRule.class);
|
||||||
String body = httpGetContent(url);
|
|
||||||
logger.info("Degrade Body:{}", body);
|
|
||||||
List<DegradeRule> rules = RuleUtils.parseDegradeRule(body);
|
|
||||||
if (rules != null) {
|
if (rules != null) {
|
||||||
return rules.stream().map(rule -> DegradeRuleEntity.fromDegradeRule(app, ip, port, rule))
|
return rules.stream().map(rule -> DegradeRuleEntity.fromDegradeRule(app, ip, port, rule))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
@ -288,10 +412,7 @@ public class SentinelApiClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SystemRuleEntity> fetchSystemRuleOfMachine(String app, String ip, int port) {
|
public List<SystemRuleEntity> fetchSystemRuleOfMachine(String app, String ip, int port) {
|
||||||
String url = "http://" + ip + ":" + port + "/" + GET_RULES_PATH + "?type=" + SYSTEM_RULE_TYPE;
|
List<SystemRule> rules = fetchRules(ip, port, SYSTEM_RULE_TYPE, SystemRule.class);
|
||||||
String body = httpGetContent(url);
|
|
||||||
logger.info("SystemRule Body:{}", body);
|
|
||||||
List<SystemRule> rules = RuleUtils.parseSystemRule(body);
|
|
||||||
if (rules != null) {
|
if (rules != null) {
|
||||||
return rules.stream().map(rule -> SystemRuleEntity.fromSystemRule(app, ip, port, rule))
|
return rules.stream().map(rule -> SystemRuleEntity.fromSystemRule(app, ip, port, rule))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
@ -314,12 +435,7 @@ public class SentinelApiClient {
|
||||||
AssertUtil.notEmpty(app, "Bad app name");
|
AssertUtil.notEmpty(app, "Bad app name");
|
||||||
AssertUtil.notEmpty(ip, "Bad machine IP");
|
AssertUtil.notEmpty(ip, "Bad machine IP");
|
||||||
AssertUtil.isTrue(port > 0, "Bad machine port");
|
AssertUtil.isTrue(port > 0, "Bad machine port");
|
||||||
URIBuilder uriBuilder = new URIBuilder();
|
return fetchItemsAsync(ip, port, GET_PARAM_RULE_PATH, null, ParamFlowRule.class)
|
||||||
String commandName = GET_PARAM_RULE_PATH;
|
|
||||||
uriBuilder.setScheme("http").setHost(ip).setPort(port)
|
|
||||||
.setPath(commandName);
|
|
||||||
return executeCommand(commandName, uriBuilder.build())
|
|
||||||
.thenApply(RuleUtils::parseParamFlowRule)
|
|
||||||
.thenApply(rules -> rules.stream()
|
.thenApply(rules -> rules.stream()
|
||||||
.map(e -> ParamFlowRuleEntity.fromAuthorityRule(app, ip, port, e))
|
.map(e -> ParamFlowRuleEntity.fromAuthorityRule(app, ip, port, e))
|
||||||
.collect(Collectors.toList())
|
.collect(Collectors.toList())
|
||||||
|
|
@ -343,23 +459,13 @@ public class SentinelApiClient {
|
||||||
AssertUtil.notEmpty(app, "Bad app name");
|
AssertUtil.notEmpty(app, "Bad app name");
|
||||||
AssertUtil.notEmpty(ip, "Bad machine IP");
|
AssertUtil.notEmpty(ip, "Bad machine IP");
|
||||||
AssertUtil.isTrue(port > 0, "Bad machine port");
|
AssertUtil.isTrue(port > 0, "Bad machine port");
|
||||||
URIBuilder uriBuilder = new URIBuilder();
|
Map<String, String> params = new HashMap<>(1);
|
||||||
uriBuilder.setScheme("http").setHost(ip).setPort(port)
|
params.put("type", AUTHORITY_TYPE);
|
||||||
.setPath(GET_RULES_PATH)
|
List<AuthorityRule> rules = fetchRules(ip, port, AUTHORITY_TYPE, AuthorityRule.class);
|
||||||
.setParameter("type", AUTHORITY_TYPE);
|
return Optional.ofNullable(rules).map(r -> r.stream()
|
||||||
try {
|
|
||||||
String body = httpGetContent(uriBuilder.build().toString());
|
|
||||||
return Optional.ofNullable(body)
|
|
||||||
.map(RuleUtils::parseAuthorityRule)
|
|
||||||
.map(rules -> rules.stream()
|
|
||||||
.map(e -> AuthorityRuleEntity.fromAuthorityRule(app, ip, port, e))
|
.map(e -> AuthorityRuleEntity.fromAuthorityRule(app, ip, port, e))
|
||||||
.collect(Collectors.toList())
|
.collect(Collectors.toList())
|
||||||
)
|
).orElse(null);
|
||||||
.orElse(null);
|
|
||||||
} catch (URISyntaxException e) {
|
|
||||||
logger.error("Error when fetching authority rules", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -373,23 +479,7 @@ public class SentinelApiClient {
|
||||||
* @return whether successfully set the rules.
|
* @return whether successfully set the rules.
|
||||||
*/
|
*/
|
||||||
public boolean setFlowRuleOfMachine(String app, String ip, int port, List<FlowRuleEntity> rules) {
|
public boolean setFlowRuleOfMachine(String app, String ip, int port, List<FlowRuleEntity> rules) {
|
||||||
if (rules == null) {
|
return setRules(app, ip, port, FLOW_RULE_TYPE, rules);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (ip == null) {
|
|
||||||
throw new IllegalArgumentException("ip is null");
|
|
||||||
}
|
|
||||||
String data = JSON.toJSONString(rules.stream().map(FlowRuleEntity::toFlowRule).collect(Collectors.toList()));
|
|
||||||
try {
|
|
||||||
data = URLEncoder.encode(data, DEFAULT_CHARSET.name());
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
logger.info("encode rule error", e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
String url = "http://" + ip + ":" + port + "/" + SET_RULES_PATH + "?type=" + FLOW_RULE_TYPE + "&data=" + data;
|
|
||||||
String result = httpGetContent(url);
|
|
||||||
logger.info("setFlowRule: " + result);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -403,25 +493,7 @@ public class SentinelApiClient {
|
||||||
* @return whether successfully set the rules.
|
* @return whether successfully set the rules.
|
||||||
*/
|
*/
|
||||||
public boolean setDegradeRuleOfMachine(String app, String ip, int port, List<DegradeRuleEntity> rules) {
|
public boolean setDegradeRuleOfMachine(String app, String ip, int port, List<DegradeRuleEntity> rules) {
|
||||||
if (rules == null) {
|
return setRules(app, ip, port, DEGRADE_RULE_TYPE, rules);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (ip == null) {
|
|
||||||
throw new IllegalArgumentException("ip is null");
|
|
||||||
}
|
|
||||||
String data = JSON.toJSONString(
|
|
||||||
rules.stream().map(DegradeRuleEntity::toDegradeRule).collect(Collectors.toList()));
|
|
||||||
try {
|
|
||||||
data = URLEncoder.encode(data, DEFAULT_CHARSET.name());
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
logger.info("encode rule error", e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
String url = "http://" + ip + ":" + port + "/" + SET_RULES_PATH + "?type=" + DEGRADE_RULE_TYPE + "&data="
|
|
||||||
+ data;
|
|
||||||
String result = httpGetContent(url);
|
|
||||||
logger.info("setDegradeRule: " + result);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -435,45 +507,11 @@ public class SentinelApiClient {
|
||||||
* @return whether successfully set the rules.
|
* @return whether successfully set the rules.
|
||||||
*/
|
*/
|
||||||
public boolean setSystemRuleOfMachine(String app, String ip, int port, List<SystemRuleEntity> rules) {
|
public boolean setSystemRuleOfMachine(String app, String ip, int port, List<SystemRuleEntity> rules) {
|
||||||
if (rules == null) {
|
return setRules(app, ip, port, SYSTEM_RULE_TYPE, rules);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (ip == null) {
|
|
||||||
throw new IllegalArgumentException("ip is null");
|
|
||||||
}
|
|
||||||
String data = JSON.toJSONString(
|
|
||||||
rules.stream().map(SystemRuleEntity::toSystemRule).collect(Collectors.toList()));
|
|
||||||
try {
|
|
||||||
data = URLEncoder.encode(data, DEFAULT_CHARSET.name());
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
logger.info("encode rule error", e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
String url = "http://" + ip + ":" + port + "/" + SET_RULES_PATH + "?type=" + SYSTEM_RULE_TYPE + "&data=" + data;
|
|
||||||
String result = httpGetContent(url);
|
|
||||||
logger.info("setSystemRule: " + result);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setAuthorityRuleOfMachine(String app, String ip, int port, List<AuthorityRuleEntity> rules) {
|
public boolean setAuthorityRuleOfMachine(String app, String ip, int port, List<AuthorityRuleEntity> rules) {
|
||||||
if (rules == null) {
|
return setRules(app, ip, port, AUTHORITY_TYPE, rules);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (StringUtil.isBlank(ip) || port <= 0) {
|
|
||||||
throw new IllegalArgumentException("Invalid IP or port");
|
|
||||||
}
|
|
||||||
String data = JSON.toJSONString(
|
|
||||||
rules.stream().map(AuthorityRuleEntity::getRule).collect(Collectors.toList()));
|
|
||||||
try {
|
|
||||||
data = URLEncoder.encode(data, DEFAULT_CHARSET.name());
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
logger.info("Encode rule error", e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
String url = "http://" + ip + ":" + port + "/" + SET_RULES_PATH + "?type=" + AUTHORITY_TYPE + "&data=" + data;
|
|
||||||
String result = httpGetContent(url);
|
|
||||||
logger.info("Push authority rules: " + result);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<Void> setParamFlowRuleOfMachine(String app, String ip, int port, List<ParamFlowRuleEntity> rules) {
|
public CompletableFuture<Void> setParamFlowRuleOfMachine(String app, String ip, int port, List<ParamFlowRuleEntity> rules) {
|
||||||
|
|
@ -487,12 +525,9 @@ public class SentinelApiClient {
|
||||||
String data = JSON.toJSONString(
|
String data = JSON.toJSONString(
|
||||||
rules.stream().map(ParamFlowRuleEntity::getRule).collect(Collectors.toList())
|
rules.stream().map(ParamFlowRuleEntity::getRule).collect(Collectors.toList())
|
||||||
);
|
);
|
||||||
data = URLEncoder.encode(data, DEFAULT_CHARSET.name());
|
Map<String, String> params = new HashMap<>(1);
|
||||||
URIBuilder uriBuilder = new URIBuilder();
|
params.put("data", data);
|
||||||
uriBuilder.setScheme("http").setHost(ip).setPort(port)
|
return executeCommand(app, ip, port, SET_PARAM_RULE_PATH, params, true)
|
||||||
.setPath(SET_PARAM_RULE_PATH)
|
|
||||||
.setParameter("data", data);
|
|
||||||
return executeCommand(SET_PARAM_RULE_PATH, uriBuilder.build())
|
|
||||||
.thenCompose(e -> {
|
.thenCompose(e -> {
|
||||||
if (CommandConstants.MSG_SUCCESS.equals(e)) {
|
if (CommandConstants.MSG_SUCCESS.equals(e)) {
|
||||||
return CompletableFuture.completedFuture(null);
|
return CompletableFuture.completedFuture(null);
|
||||||
|
|
@ -514,10 +549,7 @@ public class SentinelApiClient {
|
||||||
return AsyncUtils.newFailedFuture(new IllegalArgumentException("Invalid parameter"));
|
return AsyncUtils.newFailedFuture(new IllegalArgumentException("Invalid parameter"));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
URIBuilder uriBuilder = new URIBuilder();
|
return executeCommand(ip, port, FETCH_CLUSTER_MODE_PATH, false)
|
||||||
uriBuilder.setScheme("http").setHost(ip).setPort(port)
|
|
||||||
.setPath(FETCH_CLUSTER_MODE_PATH);
|
|
||||||
return executeCommand(FETCH_CLUSTER_MODE_PATH, uriBuilder.build())
|
|
||||||
.thenApply(r -> JSON.parseObject(r, ClusterStateSimpleEntity.class));
|
.thenApply(r -> JSON.parseObject(r, ClusterStateSimpleEntity.class));
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
logger.warn("Error when fetching cluster mode", ex);
|
logger.warn("Error when fetching cluster mode", ex);
|
||||||
|
|
@ -530,11 +562,9 @@ public class SentinelApiClient {
|
||||||
return AsyncUtils.newFailedFuture(new IllegalArgumentException("Invalid parameter"));
|
return AsyncUtils.newFailedFuture(new IllegalArgumentException("Invalid parameter"));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
URIBuilder uriBuilder = new URIBuilder();
|
Map<String, String> params = new HashMap<>(1);
|
||||||
uriBuilder.setScheme("http").setHost(ip).setPort(port)
|
params.put("mode", String.valueOf(mode));
|
||||||
.setPath(MODIFY_CLUSTER_MODE_PATH)
|
return executeCommand(ip, port, MODIFY_CLUSTER_MODE_PATH, params, false)
|
||||||
.setParameter("mode", String.valueOf(mode));
|
|
||||||
return executeCommand(MODIFY_CLUSTER_MODE_PATH, uriBuilder.build())
|
|
||||||
.thenCompose(e -> {
|
.thenCompose(e -> {
|
||||||
if (CommandConstants.MSG_SUCCESS.equals(e)) {
|
if (CommandConstants.MSG_SUCCESS.equals(e)) {
|
||||||
return CompletableFuture.completedFuture(null);
|
return CompletableFuture.completedFuture(null);
|
||||||
|
|
@ -554,10 +584,7 @@ public class SentinelApiClient {
|
||||||
return AsyncUtils.newFailedFuture(new IllegalArgumentException("Invalid parameter"));
|
return AsyncUtils.newFailedFuture(new IllegalArgumentException("Invalid parameter"));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
URIBuilder uriBuilder = new URIBuilder();
|
return executeCommand(ip, port, FETCH_CLUSTER_CLIENT_CONFIG_PATH, false)
|
||||||
uriBuilder.setScheme("http").setHost(ip).setPort(port)
|
|
||||||
.setPath(FETCH_CLUSTER_CLIENT_CONFIG_PATH);
|
|
||||||
return executeCommand(FETCH_CLUSTER_CLIENT_CONFIG_PATH, uriBuilder.build())
|
|
||||||
.thenApply(r -> JSON.parseObject(r, ClusterClientInfoVO.class));
|
.thenApply(r -> JSON.parseObject(r, ClusterClientInfoVO.class));
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
logger.warn("Error when fetching cluster client config", ex);
|
logger.warn("Error when fetching cluster client config", ex);
|
||||||
|
|
@ -570,11 +597,9 @@ public class SentinelApiClient {
|
||||||
return AsyncUtils.newFailedFuture(new IllegalArgumentException("Invalid parameter"));
|
return AsyncUtils.newFailedFuture(new IllegalArgumentException("Invalid parameter"));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
URIBuilder uriBuilder = new URIBuilder();
|
Map<String, String> params = new HashMap<>(1);
|
||||||
uriBuilder.setScheme("http").setHost(ip).setPort(port)
|
params.put("data", JSON.toJSONString(config));
|
||||||
.setPath(MODIFY_CLUSTER_CLIENT_CONFIG_PATH)
|
return executeCommand(app, ip, port, MODIFY_CLUSTER_CLIENT_CONFIG_PATH, params, true)
|
||||||
.setParameter("data", JSON.toJSONString(config));
|
|
||||||
return executeCommand(MODIFY_CLUSTER_MODE_PATH, uriBuilder.build())
|
|
||||||
.thenCompose(e -> {
|
.thenCompose(e -> {
|
||||||
if (CommandConstants.MSG_SUCCESS.equals(e)) {
|
if (CommandConstants.MSG_SUCCESS.equals(e)) {
|
||||||
return CompletableFuture.completedFuture(null);
|
return CompletableFuture.completedFuture(null);
|
||||||
|
|
@ -594,11 +619,9 @@ public class SentinelApiClient {
|
||||||
return AsyncUtils.newFailedFuture(new IllegalArgumentException("Invalid parameter"));
|
return AsyncUtils.newFailedFuture(new IllegalArgumentException("Invalid parameter"));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
URIBuilder uriBuilder = new URIBuilder();
|
Map<String, String> params = new HashMap<>(1);
|
||||||
uriBuilder.setScheme("http").setHost(ip).setPort(port)
|
params.put("data", JSON.toJSONString(config));
|
||||||
.setPath(MODIFY_CLUSTER_SERVER_FLOW_CONFIG_PATH)
|
return executeCommand(app, ip, port, MODIFY_CLUSTER_SERVER_FLOW_CONFIG_PATH, params, true)
|
||||||
.setParameter("data", JSON.toJSONString(config));
|
|
||||||
return executeCommand(MODIFY_CLUSTER_SERVER_FLOW_CONFIG_PATH, uriBuilder.build())
|
|
||||||
.thenCompose(e -> {
|
.thenCompose(e -> {
|
||||||
if (CommandConstants.MSG_SUCCESS.equals(e)) {
|
if (CommandConstants.MSG_SUCCESS.equals(e)) {
|
||||||
return CompletableFuture.completedFuture(null);
|
return CompletableFuture.completedFuture(null);
|
||||||
|
|
@ -618,12 +641,10 @@ public class SentinelApiClient {
|
||||||
return AsyncUtils.newFailedFuture(new IllegalArgumentException("Invalid parameter"));
|
return AsyncUtils.newFailedFuture(new IllegalArgumentException("Invalid parameter"));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
URIBuilder uriBuilder = new URIBuilder();
|
Map<String, String> params = new HashMap<>(2);
|
||||||
uriBuilder.setScheme("http").setHost(ip).setPort(port)
|
params.put("port", config.getPort().toString());
|
||||||
.setPath(MODIFY_CLUSTER_SERVER_TRANSPORT_CONFIG_PATH)
|
params.put("idleSeconds", config.getIdleSeconds().toString());
|
||||||
.setParameter("port", config.getPort().toString())
|
return executeCommand(app, ip, port, MODIFY_CLUSTER_SERVER_TRANSPORT_CONFIG_PATH, params, false)
|
||||||
.setParameter("idleSeconds", config.getIdleSeconds().toString());
|
|
||||||
return executeCommand(MODIFY_CLUSTER_SERVER_TRANSPORT_CONFIG_PATH, uriBuilder.build())
|
|
||||||
.thenCompose(e -> {
|
.thenCompose(e -> {
|
||||||
if (CommandConstants.MSG_SUCCESS.equals(e)) {
|
if (CommandConstants.MSG_SUCCESS.equals(e)) {
|
||||||
return CompletableFuture.completedFuture(null);
|
return CompletableFuture.completedFuture(null);
|
||||||
|
|
@ -643,16 +664,14 @@ public class SentinelApiClient {
|
||||||
return AsyncUtils.newFailedFuture(new IllegalArgumentException("Invalid parameter"));
|
return AsyncUtils.newFailedFuture(new IllegalArgumentException("Invalid parameter"));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
URIBuilder uriBuilder = new URIBuilder();
|
Map<String, String> params = new HashMap<>(1);
|
||||||
uriBuilder.setScheme("http").setHost(ip).setPort(port)
|
params.put("data", JSON.toJSONString(set));
|
||||||
.setPath(MODIFY_CLUSTER_SERVER_NAMESPACE_SET_PATH)
|
return executeCommand(app, ip, port, MODIFY_CLUSTER_SERVER_NAMESPACE_SET_PATH, params, true)
|
||||||
.setParameter("data", JSON.toJSONString(set));
|
|
||||||
return executeCommand(MODIFY_CLUSTER_SERVER_NAMESPACE_SET_PATH, uriBuilder.build())
|
|
||||||
.thenCompose(e -> {
|
.thenCompose(e -> {
|
||||||
if (CommandConstants.MSG_SUCCESS.equals(e)) {
|
if (CommandConstants.MSG_SUCCESS.equals(e)) {
|
||||||
return CompletableFuture.completedFuture(null);
|
return CompletableFuture.completedFuture(null);
|
||||||
} else {
|
} else {
|
||||||
logger.warn("Error when modifying cluster server NamespaceSet: " + e);
|
logger.warn("Error when modifying cluster server NamespaceSet", e);
|
||||||
return AsyncUtils.newFailedFuture(new RuntimeException(e));
|
return AsyncUtils.newFailedFuture(new RuntimeException(e));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -667,10 +686,7 @@ public class SentinelApiClient {
|
||||||
return AsyncUtils.newFailedFuture(new IllegalArgumentException("Invalid parameter"));
|
return AsyncUtils.newFailedFuture(new IllegalArgumentException("Invalid parameter"));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
URIBuilder uriBuilder = new URIBuilder();
|
return executeCommand(ip, port, FETCH_CLUSTER_SERVER_BASIC_INFO_PATH, false)
|
||||||
uriBuilder.setScheme("http").setHost(ip).setPort(port)
|
|
||||||
.setPath(FETCH_CLUSTER_SERVER_BASIC_INFO_PATH);
|
|
||||||
return executeCommand(FETCH_CLUSTER_SERVER_BASIC_INFO_PATH, uriBuilder.build())
|
|
||||||
.thenApply(r -> JSON.parseObject(r, ClusterServerStateVO.class));
|
.thenApply(r -> JSON.parseObject(r, ClusterServerStateVO.class));
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
logger.warn("Error when fetching cluster sever all config and basic info", ex);
|
logger.warn("Error when fetching cluster sever all config and basic info", ex);
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,32 @@ package com.alibaba.csp.sentinel.dashboard.datasource.entity;
|
||||||
* @since 0.2.1
|
* @since 0.2.1
|
||||||
*/
|
*/
|
||||||
public class SentinelVersion {
|
public class SentinelVersion {
|
||||||
|
|
||||||
private int majorVersion;
|
private int majorVersion;
|
||||||
private int minorVersion;
|
private int minorVersion;
|
||||||
private int fixVersion;
|
private int fixVersion;
|
||||||
private String postfix;
|
private String postfix;
|
||||||
|
|
||||||
|
public SentinelVersion() {
|
||||||
|
this(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SentinelVersion(int major, int minor, int fix) {
|
||||||
|
this(major, minor, fix, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SentinelVersion(int major, int minor, int fix, String postfix) {
|
||||||
|
this.majorVersion = major;
|
||||||
|
this.minorVersion = minor;
|
||||||
|
this.fixVersion = fix;
|
||||||
|
this.postfix = postfix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 000, 000, 000
|
||||||
|
*/
|
||||||
|
public int getFullVersion() {
|
||||||
|
return majorVersion * 1000000 + minorVersion * 1000 + fixVersion;
|
||||||
|
}
|
||||||
|
|
||||||
public int getMajorVersion() {
|
public int getMajorVersion() {
|
||||||
return majorVersion;
|
return majorVersion;
|
||||||
|
|
@ -66,18 +87,14 @@ public class SentinelVersion {
|
||||||
if (version == null) {
|
if (version == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return this.majorVersion > version.majorVersion
|
return getFullVersion() > version.getFullVersion();
|
||||||
|| this.minorVersion > version.minorVersion
|
|
||||||
|| this.fixVersion > version.fixVersion;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean greaterOrEqual(SentinelVersion version) {
|
public boolean greaterOrEqual(SentinelVersion version) {
|
||||||
if (version == null) {
|
if (version == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return this.majorVersion >= version.majorVersion
|
return getFullVersion() >= version.getFullVersion();
|
||||||
|| this.minorVersion >= version.minorVersion
|
|
||||||
|| this.fixVersion >= version.fixVersion;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -87,9 +104,7 @@ public class SentinelVersion {
|
||||||
|
|
||||||
SentinelVersion that = (SentinelVersion)o;
|
SentinelVersion that = (SentinelVersion)o;
|
||||||
|
|
||||||
if (majorVersion != that.majorVersion) { return false; }
|
if (getFullVersion() != that.getFullVersion()) { return false; }
|
||||||
if (minorVersion != that.minorVersion) { return false; }
|
|
||||||
if (fixVersion != that.fixVersion) { return false; }
|
|
||||||
return postfix != null ? postfix.equals(that.postfix) : that.postfix == null;
|
return postfix != null ? postfix.equals(that.postfix) : that.postfix == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package com.alibaba.csp.sentinel.dashboard.datasource.entity.rule;
|
package com.alibaba.csp.sentinel.dashboard.datasource.entity.rule;
|
||||||
|
|
||||||
|
import com.alibaba.csp.sentinel.slots.block.Rule;
|
||||||
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
|
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
|
||||||
import com.alibaba.csp.sentinel.util.AssertUtil;
|
import com.alibaba.csp.sentinel.util.AssertUtil;
|
||||||
|
|
||||||
|
|
@ -55,4 +56,9 @@ public class AuthorityRuleEntity extends AbstractRuleEntity<AuthorityRule> {
|
||||||
public int getStrategy() {
|
public int getStrategy() {
|
||||||
return rule.getStrategy();
|
return rule.getStrategy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Rule toRule() {
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,8 @@ public class DegradeRuleEntity implements RuleEntity {
|
||||||
this.gmtModified = gmtModified;
|
this.gmtModified = gmtModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DegradeRule toDegradeRule() {
|
@Override
|
||||||
|
public DegradeRule toRule() {
|
||||||
DegradeRule rule = new DegradeRule();
|
DegradeRule rule = new DegradeRule();
|
||||||
rule.setResource(resource);
|
rule.setResource(resource);
|
||||||
rule.setLimitApp(limitApp);
|
rule.setLimitApp(limitApp);
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,8 @@ public class FlowRuleEntity implements RuleEntity {
|
||||||
this.gmtModified = gmtModified;
|
this.gmtModified = gmtModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FlowRule toFlowRule() {
|
@Override
|
||||||
|
public FlowRule toRule() {
|
||||||
FlowRule flowRule = new FlowRule();
|
FlowRule flowRule = new FlowRule();
|
||||||
flowRule.setCount(this.count);
|
flowRule.setCount(this.count);
|
||||||
flowRule.setGrade(this.grade);
|
flowRule.setGrade(this.grade);
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ package com.alibaba.csp.sentinel.dashboard.datasource.entity.rule;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.alibaba.csp.sentinel.slots.block.Rule;
|
||||||
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowClusterConfig;
|
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowClusterConfig;
|
||||||
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowItem;
|
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowItem;
|
||||||
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
|
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
|
||||||
|
|
@ -84,4 +85,9 @@ public class ParamFlowRuleEntity extends AbstractRuleEntity<ParamFlowRule> {
|
||||||
public ParamFlowClusterConfig getClusterConfig() {
|
public ParamFlowClusterConfig getClusterConfig() {
|
||||||
return rule.getClusterConfig();
|
return rule.getClusterConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Rule toRule() {
|
||||||
|
return rule;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ package com.alibaba.csp.sentinel.dashboard.datasource.entity.rule;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
import com.alibaba.csp.sentinel.slots.block.Rule;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author leyou
|
* @author leyou
|
||||||
*/
|
*/
|
||||||
|
|
@ -33,4 +35,6 @@ public interface RuleEntity {
|
||||||
Integer getPort();
|
Integer getPort();
|
||||||
|
|
||||||
Date getGmtCreate();
|
Date getGmtCreate();
|
||||||
|
|
||||||
|
Rule toRule();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,8 @@ public class SystemRuleEntity implements RuleEntity {
|
||||||
this.gmtModified = gmtModified;
|
this.gmtModified = gmtModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SystemRule toSystemRule() {
|
@Override
|
||||||
|
public SystemRule toRule() {
|
||||||
SystemRule rule = new SystemRule();
|
SystemRule rule = new SystemRule();
|
||||||
rule.setHighestSystemLoad(avgLoad);
|
rule.setHighestSystemLoad(avgLoad);
|
||||||
rule.setAvgRt(avgRt);
|
rule.setAvgRt(avgRt);
|
||||||
|
|
|
||||||
|
|
@ -1,97 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.dashboard.util;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
|
|
||||||
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
|
|
||||||
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
|
|
||||||
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
|
|
||||||
import com.alibaba.csp.sentinel.slots.system.SystemRule;
|
|
||||||
import com.alibaba.csp.sentinel.util.StringUtil;
|
|
||||||
import com.alibaba.fastjson.JSON;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Eric Zhao
|
|
||||||
* @since 0.2.1
|
|
||||||
*/
|
|
||||||
public final class RuleUtils {
|
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(RuleUtils.class);
|
|
||||||
|
|
||||||
public static List<FlowRule> parseFlowRule(String body) {
|
|
||||||
try {
|
|
||||||
return JSON.parseArray(body, FlowRule.class);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.error("parser FlowRule error: ", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<DegradeRule> parseDegradeRule(String body) {
|
|
||||||
try {
|
|
||||||
return JSON.parseArray(body, DegradeRule.class);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.error("parser DegradeRule error: ", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<AuthorityRule> parseAuthorityRule(String body) {
|
|
||||||
if (StringUtil.isBlank(body)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return JSON.parseArray(body, AuthorityRule.class);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.error("Error when parsing authority rules", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse parameter flow rules.
|
|
||||||
*
|
|
||||||
* @param body raw string content
|
|
||||||
* @return parsed rule list; null if error occurs or empty content
|
|
||||||
*/
|
|
||||||
public static List<ParamFlowRule> parseParamFlowRule(String body) {
|
|
||||||
if (StringUtil.isBlank(body)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return JSON.parseArray(body, ParamFlowRule.class);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.error("Error when parsing parameter flow rules", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<SystemRule> parseSystemRule(String body) {
|
|
||||||
try {
|
|
||||||
return JSON.parseArray(body, SystemRule.class);
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.info("parser SystemRule error: ", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private RuleUtils() {}
|
|
||||||
}
|
|
||||||
|
|
@ -32,7 +32,7 @@ public final class VersionUtils {
|
||||||
/**
|
/**
|
||||||
* Parse version of Sentinel from raw string.
|
* Parse version of Sentinel from raw string.
|
||||||
*
|
*
|
||||||
* @param s version string
|
* @param versionFull version string
|
||||||
* @return parsed {@link SentinelVersion} if the version is valid; empty if
|
* @return parsed {@link SentinelVersion} if the version is valid; empty if
|
||||||
* there is something wrong with the format
|
* there is something wrong with the format
|
||||||
*/
|
*/
|
||||||
|
|
@ -41,25 +41,50 @@ public final class VersionUtils {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
String versionFull = s;
|
||||||
SentinelVersion version = new SentinelVersion();
|
SentinelVersion version = new SentinelVersion();
|
||||||
String[] postArr = s.split("-");
|
|
||||||
if (postArr.length > 1) {
|
// postfix
|
||||||
version.setPostfix(postArr[1]);
|
int index = versionFull.indexOf("-");
|
||||||
}
|
if (index == 0) {
|
||||||
String[] arr = postArr[0].split("\\.");
|
// Start with "-"
|
||||||
if (arr.length == 2) {
|
|
||||||
version.setMajorVersion(Integer.valueOf(arr[0]))
|
|
||||||
.setMinorVersion(Integer.valueOf(arr[1]))
|
|
||||||
.setFixVersion(0);
|
|
||||||
} else if (arr.length == 3) {
|
|
||||||
version.setMajorVersion(Integer.valueOf(arr[0]))
|
|
||||||
.setMinorVersion(Integer.valueOf(arr[1]))
|
|
||||||
.setFixVersion(Integer.valueOf(arr[2]));
|
|
||||||
} else {
|
|
||||||
// Wrong format, return empty.
|
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
return Optional.of(version);
|
if (index == versionFull.length() - 1) {
|
||||||
|
// End with "-"
|
||||||
|
} else if (index > 0) {
|
||||||
|
version.setPostfix(versionFull.substring(index + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index >= 0) {
|
||||||
|
versionFull = versionFull.substring(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
// x.x.x
|
||||||
|
int segment = 0;
|
||||||
|
int[] ver = new int[3];
|
||||||
|
while (segment < ver.length) {
|
||||||
|
index = versionFull.indexOf('.');
|
||||||
|
if (index < 0) {
|
||||||
|
if (versionFull.length() > 0) {
|
||||||
|
ver[segment] = Integer.valueOf(versionFull);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ver[segment] = Integer.valueOf(versionFull.substring(0, index));
|
||||||
|
versionFull = versionFull.substring(index + 1);
|
||||||
|
segment ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ver[0] < 1) {
|
||||||
|
// Wrong format, return empty.
|
||||||
|
return Optional.empty();
|
||||||
|
} else {
|
||||||
|
return Optional.of(version
|
||||||
|
.setMajorVersion(ver[0])
|
||||||
|
.setMinorVersion(ver[1])
|
||||||
|
.setFixVersion(ver[2]));
|
||||||
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
// Parse fail, return empty.
|
// Parse fail, return empty.
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
package com.alibaba.csp.sentinel.dashboard.datasource.entity;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class SentinelVersionTest {
|
||||||
|
@Test
|
||||||
|
public void testEqual() {
|
||||||
|
assertEquals(new SentinelVersion(1, 0, 0), new SentinelVersion(1, 0, 0));
|
||||||
|
assertNotEquals(new SentinelVersion(1, 0, 0), new SentinelVersion(1, 2, 3));
|
||||||
|
assertNotEquals(new SentinelVersion(1, 0, 0), new SentinelVersion(1, 0, 0, ""));
|
||||||
|
assertEquals(new SentinelVersion(1, 0, 0, ""), new SentinelVersion(1, 0, 0, ""));
|
||||||
|
assertNotEquals(new SentinelVersion(1, 0, 0, ""), new SentinelVersion(1, 0, 0, null));
|
||||||
|
assertEquals(new SentinelVersion(1, 0, 0, null), new SentinelVersion(1, 0, 0, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGreater() {
|
||||||
|
assertTrue(new SentinelVersion(2, 0, 0).greaterThan(new SentinelVersion(1, 0, 0)));
|
||||||
|
assertTrue(new SentinelVersion(1, 1, 0).greaterThan(new SentinelVersion(1, 0, 0)));
|
||||||
|
assertTrue(new SentinelVersion(1, 1, 2).greaterThan(new SentinelVersion(1, 1, 0)));
|
||||||
|
assertTrue(new SentinelVersion(1, 1, 4).greaterThan(new SentinelVersion(1, 1, 3)));
|
||||||
|
assertFalse(new SentinelVersion(1, 0, 0).greaterThan(new SentinelVersion(1, 0, 0)));
|
||||||
|
assertFalse(new SentinelVersion(1, 0, 0).greaterThan(new SentinelVersion(1, 1, 0)));
|
||||||
|
assertFalse(new SentinelVersion(1, 1, 3).greaterThan(new SentinelVersion(1, 1, 3)));
|
||||||
|
assertFalse(new SentinelVersion(1, 1, 2).greaterThan(new SentinelVersion(1, 1, 3)));
|
||||||
|
assertFalse(new SentinelVersion(1, 0, 0, "").greaterThan(new SentinelVersion(1, 0, 0)));
|
||||||
|
assertTrue(new SentinelVersion(1, 0, 1).greaterThan(new SentinelVersion(1, 0, 0)));
|
||||||
|
assertTrue(new SentinelVersion(1, 0, 1, "a").greaterThan(new SentinelVersion(1, 0, 0, "b")));
|
||||||
|
assertFalse(new SentinelVersion(1, 0, 0, "b").greaterThan(new SentinelVersion(1, 0, 0, "a")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
package com.alibaba.csp.sentinel.dashboard.util;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import com.alibaba.csp.sentinel.dashboard.datasource.entity.SentinelVersion;
|
||||||
|
|
||||||
|
public class VersionUtilsTest {
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
Optional<SentinelVersion> version = VersionUtils.parseVersion("1.2.3");
|
||||||
|
assertTrue(version.isPresent());
|
||||||
|
assertEquals(1, version.get().getMajorVersion());
|
||||||
|
assertEquals(2, version.get().getMinorVersion());
|
||||||
|
assertEquals(3, version.get().getFixVersion());
|
||||||
|
assertNull(version.get().getPostfix());
|
||||||
|
|
||||||
|
version = VersionUtils.parseVersion("1.2");
|
||||||
|
assertTrue(version.isPresent());
|
||||||
|
assertEquals(1, version.get().getMajorVersion());
|
||||||
|
assertEquals(2, version.get().getMinorVersion());
|
||||||
|
assertEquals(0, version.get().getFixVersion());
|
||||||
|
assertNull(version.get().getPostfix());
|
||||||
|
|
||||||
|
version = VersionUtils.parseVersion("1.");
|
||||||
|
assertTrue(version.isPresent());
|
||||||
|
assertEquals(1, version.get().getMajorVersion());
|
||||||
|
assertEquals(0, version.get().getMinorVersion());
|
||||||
|
assertEquals(0, version.get().getFixVersion());
|
||||||
|
assertNull(version.get().getPostfix());
|
||||||
|
|
||||||
|
version = VersionUtils.parseVersion("1.2.");
|
||||||
|
assertTrue(version.isPresent());
|
||||||
|
assertEquals(1, version.get().getMajorVersion());
|
||||||
|
assertEquals(2, version.get().getMinorVersion());
|
||||||
|
assertEquals(0, version.get().getFixVersion());
|
||||||
|
assertNull(version.get().getPostfix());
|
||||||
|
|
||||||
|
version = VersionUtils.parseVersion("1.2.3.");
|
||||||
|
assertTrue(version.isPresent());
|
||||||
|
assertEquals(1, version.get().getMajorVersion());
|
||||||
|
assertEquals(2, version.get().getMinorVersion());
|
||||||
|
assertEquals(3, version.get().getFixVersion());
|
||||||
|
assertNull(version.get().getPostfix());
|
||||||
|
|
||||||
|
version = VersionUtils.parseVersion("1.2.3.4");
|
||||||
|
assertTrue(version.isPresent());
|
||||||
|
assertEquals(1, version.get().getMajorVersion());
|
||||||
|
assertEquals(2, version.get().getMinorVersion());
|
||||||
|
assertEquals(3, version.get().getFixVersion());
|
||||||
|
assertNull(version.get().getPostfix());
|
||||||
|
|
||||||
|
version = VersionUtils.parseVersion("1");
|
||||||
|
assertTrue(version.isPresent());
|
||||||
|
assertEquals(1, version.get().getMajorVersion());
|
||||||
|
assertEquals(0, version.get().getMinorVersion());
|
||||||
|
assertEquals(0, version.get().getFixVersion());
|
||||||
|
assertNull(version.get().getPostfix());
|
||||||
|
|
||||||
|
version = VersionUtils.parseVersion("1.2.3-");
|
||||||
|
assertTrue(version.isPresent());
|
||||||
|
assertEquals(1, version.get().getMajorVersion());
|
||||||
|
assertEquals(2, version.get().getMinorVersion());
|
||||||
|
assertEquals(3, version.get().getFixVersion());
|
||||||
|
assertNull(version.get().getPostfix());
|
||||||
|
|
||||||
|
version = VersionUtils.parseVersion("-");
|
||||||
|
assertFalse(version.isPresent());
|
||||||
|
|
||||||
|
version = VersionUtils.parseVersion("-t");
|
||||||
|
assertFalse(version.isPresent());
|
||||||
|
|
||||||
|
version = VersionUtils.parseVersion("");
|
||||||
|
assertFalse(version.isPresent());
|
||||||
|
|
||||||
|
version = VersionUtils.parseVersion(null);
|
||||||
|
assertFalse(version.isPresent());
|
||||||
|
|
||||||
|
version = VersionUtils.parseVersion("1.2.3-SNAPSHOTS");
|
||||||
|
assertTrue(version.isPresent());
|
||||||
|
assertEquals(1, version.get().getMajorVersion());
|
||||||
|
assertEquals(2, version.get().getMinorVersion());
|
||||||
|
assertEquals(3, version.get().getFixVersion());
|
||||||
|
assertEquals("SNAPSHOTS", version.get().getPostfix());
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue