Browse Source

dashboard: code and document refinement

Signed-off-by: Eric Zhao <sczyh16@gmail.com>
master
Eric Zhao 5 years ago
parent
commit
b7956c6bb4
30 changed files with 193 additions and 183 deletions
  1. +12
    -7
      sentinel-dashboard/Sentinel_Dashboard_Feature.md
  2. +14
    -14
      sentinel-dashboard/pom.xml
  3. +9
    -5
      sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/config/DashboardConfig.java
  4. +14
    -19
      sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/AppController.java
  5. +1
    -1
      sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/MachineRegistryController.java
  6. +13
    -11
      sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/ResourceController.java
  7. +2
    -4
      sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/datasource/entity/ApplicationEntity.java
  8. +1
    -1
      sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/datasource/entity/MachineEntity.java
  9. +20
    -33
      sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/AppInfo.java
  10. +1
    -7
      sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/AppManagement.java
  11. +17
    -2
      sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/MachineDiscovery.java
  12. +8
    -8
      sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/MachineInfo.java
  13. +11
    -3
      sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/SimpleMachineDiscovery.java
  14. +1
    -1
      sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/vo/MachineInfoVo.java
  15. +2
    -10
      sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/rule/FlowRuleApiProvider.java
  16. +3
    -0
      sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/util/MachineUtils.java
  17. +1
    -1
      sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/authority.js
  18. +1
    -1
      sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/cluster_single.js
  19. +1
    -1
      sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/degrade.js
  20. +1
    -1
      sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_v1.js
  21. +1
    -1
      sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_v2.js
  22. +2
    -3
      sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/identity.js
  23. +1
    -1
      sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/param_flow.js
  24. +1
    -1
      sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/system.js
  25. +9
    -9
      sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/discovery/AppInfoTest.java
  26. +9
    -5
      sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/discovery/MachineInfoTest.java
  27. +15
    -8
      sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/repository/metric/InMemoryMetricsRepositoryTest.java
  28. +6
    -6
      sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/ApolloConfig.java
  29. +8
    -7
      sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/FlowRuleApolloProvider.java
  30. +8
    -12
      sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/FlowRuleApolloPublisher.java

+ 12
- 7
sentinel-dashboard/Sentinel_Dashboard_Feature.md View File

@@ -49,8 +49,9 @@ Sentinel 提供了多种规则来保护系统的不同部分。流量控制规

## 3. 配置项

控制台的一些特性可以通过配置项来进行配置,配置项主要有两个来源:`System.getProperty()`和`System.getenv()`,同时存在时后者可以覆盖前者。
> 环境变量因为不支持`.`所以需要将其更换为`_`。
控制台的一些特性可以通过配置项来进行配置,配置项主要有两个来源:`System.getProperty()` 和 `System.getenv()`,同时存在时后者可以覆盖前者。

> 通过环境变量进行配置时,因为不支持 `.` 所以需要将其更换为 `_`。

项 | 类型 | 默认值 | 最小值 | 描述
--- | --- | --- | --- | ---
@@ -61,15 +62,20 @@ sentinel.dashboard.autoRemoveMachineMillis | Integer | 0 | 300000 | 距离最近

配置示例:

命令行
- 命令行方式:

```shell
java -Dsentinel.dashboard.app.hideAppNoMachineMillis=60000
```
java

- Java 方式:

```java
System.setProperty("sentinel.dashboard.app.hideAppNoMachineMillis", "60000");
```
环境变量

- 环境变量方式:

```shell
sentinel_dashboard_app_hideAppNoMachineMillis=60000
```
@@ -77,5 +83,4 @@ sentinel_dashboard_app_hideAppNoMachineMillis=60000
更多:

- [Sentinel 控制台启动和客户端接入](./README.md)
- [控制台 Wiki](https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0)

- [控制台 Wiki](https://github.com/alibaba/Sentinel/wiki/%E6%8E%A7%E5%88%B6%E5%8F%B0)

+ 14
- 14
sentinel-dashboard/pom.xml View File

@@ -16,7 +16,6 @@
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.boot.version>2.0.5.RELEASE</spring.boot.version>
<apollo.openapi.version>1.2.0</apollo.openapi.version>
</properties>

<dependencies>
@@ -39,12 +38,6 @@
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@@ -99,6 +92,20 @@
<artifactId>fastjson</artifactId>
</dependency>

<!-- for Nacos rule publisher sample -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<scope>test</scope>
</dependency>
<!-- for Apollo rule publisher sample -->
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-openapi</artifactId>
<version>1.2.0</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
@@ -109,13 +116,6 @@
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.ctrip.framework.apollo/apollo-openapi -->
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-openapi</artifactId>
<version>${apollo.openapi.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.stefanbirkner</groupId>
<artifactId>system-rules</artifactId>


+ 9
- 5
sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/config/DashboardConfig.java View File

@@ -34,22 +34,26 @@ import org.springframework.lang.NonNull;
*
*/
public class DashboardConfig {

public static final int DEFAULT_MACHINE_HEALTHY_TIMEOUT_MS = 60_000;

/**
* hide app in sidebar when it had no healthy machine after specific period in millis
* Hide application name in sidebar when it has no healthy machines after specific period in millisecond.
*/
public static final String CONFIG_HIDE_APP_NO_MACHINE_MILLIS = "sentinel.dashboard.app.hideAppNoMachineMillis";
/**
* remove app when it had no healthy machine after specific period in millis
* Remove application when it has no healthy machines after specific period in millisecond.
*/
public static final String CONFIG_REMOVE_APP_NO_MACHINE_MILLIS = "sentinel.dashboard.removeAppNoMachineMillis";
/**
* unhealthy millis
* Timeout
*/
public static final String CONFIG_UNHEALTHY_MACHINE_MILLIS = "sentinel.dashboard.unhealthyMachineMillis";
/**
* auto remove unhealthy machine after specific period in millis
* Auto remove unhealthy machine after specific period in millisecond.
*/
public static final String CONFIG_AUTO_REMOVE_MACHINE_MILLIS = "sentinel.dashboard.autoRemoveMachineMillis";

private static final ConcurrentMap<String, Object> cacheMap = new ConcurrentHashMap<>();
@NonNull
@@ -94,7 +98,7 @@ public class DashboardConfig {
}
public static int getUnhealthyMachineMillis() {
return getConfigInt(CONFIG_UNHEALTHY_MACHINE_MILLIS, 60000, 30000);
return getConfigInt(CONFIG_UNHEALTHY_MACHINE_MILLIS, DEFAULT_MACHINE_HEALTHY_TIMEOUT_MS, 30000);
}
public static void clearCache() {


+ 14
- 19
sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/AppController.java View File

@@ -28,40 +28,36 @@ import com.alibaba.csp.sentinel.dashboard.discovery.MachineInfo;
import com.alibaba.csp.sentinel.dashboard.domain.Result;
import com.alibaba.csp.sentinel.dashboard.domain.vo.MachineInfoVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
* 这个Controller负责app,机器信息的交互.
* @author Carpenter Lee
*/
@Controller
@RequestMapping(value = "/app", produces = MediaType.APPLICATION_JSON_VALUE)
@RestController
@RequestMapping(value = "/app")
public class AppController {

@Autowired
AppManagement appManagement;
private AppManagement appManagement;

@ResponseBody
@RequestMapping("/names.json")
Result<List<String>> queryApps(HttpServletRequest request) {
@GetMapping("/names.json")
public Result<List<String>> queryApps(HttpServletRequest request) {
return Result.ofSuccess(appManagement.getAppNames());
}

@ResponseBody
@RequestMapping("/briefinfos.json")
Result<List<AppInfo>> queryAppInfos(HttpServletRequest request) {
@GetMapping("/briefinfos.json")
public Result<List<AppInfo>> queryAppInfos(HttpServletRequest request) {
List<AppInfo> list = new ArrayList<>(appManagement.getBriefApps());
Collections.sort(list, Comparator.comparing(AppInfo::getApp));
return Result.ofSuccess(list);
}

@ResponseBody
@RequestMapping(value = "/{app}/machines.json")
Result<List<MachineInfoVo>> getMachinesByApp(@PathVariable("app") String app) {
@GetMapping(value = "/{app}/machines.json")
public Result<List<MachineInfoVo>> getMachinesByApp(@PathVariable("app") String app) {
AppInfo appInfo = appManagement.getDetailApp(app);
if (appInfo == null) {
return Result.ofSuccess(null);
@@ -81,9 +77,8 @@ public class AppController {
return Result.ofSuccess(MachineInfoVo.fromMachineInfoList(list));
}
@ResponseBody
@RequestMapping(value = "/{app}/machine/remove.json")
Result<String> removeMachineById(
@GetMapping(value = "/{app}/machine/remove.json")
public Result<String> removeMachineById(
@PathVariable("app") String app,
@RequestParam(name = "ip") String ip,
@RequestParam(name = "port") int port) {


+ 1
- 1
sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/MachineRegistryController.java View File

@@ -63,7 +63,7 @@ public class MachineRegistryController {
machineInfo.setIp(ip);
machineInfo.setPort(port);
machineInfo.setHeartbeatVersion(version);
machineInfo.setLastHeatbeat(System.currentTimeMillis());
machineInfo.setLastHeartbeat(System.currentTimeMillis());
machineInfo.setVersion(sentinelVersion);
appManagement.addMachine(machineInfo);
return Result.ofSuccessMsg("success");


+ 13
- 11
sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/controller/ResourceController.java View File

@@ -25,24 +25,25 @@ import com.alibaba.csp.sentinel.dashboard.domain.ResourceTreeNode;
import com.alibaba.csp.sentinel.dashboard.client.SentinelApiClient;
import com.alibaba.csp.sentinel.dashboard.domain.Result;
import com.alibaba.csp.sentinel.dashboard.domain.vo.ResourceVo;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

/**
* @author leyou
* @author Carpenter Lee
*/
@Controller
@RequestMapping(value = "/resource", produces = MediaType.APPLICATION_JSON_VALUE)
@RestController
@RequestMapping(value = "/resource")
public class ResourceController {

private static Logger logger = LoggerFactory.getLogger(ResourceController.class);

@Autowired
SentinelApiClient httpFetcher;
private SentinelApiClient httpFetcher;

/**
* Fetch real time statistics info of the machine.
@@ -54,9 +55,9 @@ public class ResourceController {
* @param searchKey key to search
* @return node statistics info.
*/
@ResponseBody
@RequestMapping("/machineResource.json")
Result<?> fetchIdentityOfMachine(String ip, Integer port, String type, String searchKey) {
@GetMapping("/machineResource.json")
public Result<List<ResourceVo>> fetchResourceChainListOfMachine(String ip, Integer port, String type,
String searchKey) {
if (StringUtil.isEmpty(ip) || port == null) {
return Result.ofFail(-1, "invalid param, give ip, port");
}
@@ -73,7 +74,8 @@ public class ResourceController {
ResourceTreeNode treeNode = ResourceTreeNode.fromNodeVoList(nodeVos);
treeNode.searchIgnoreCase(searchKey);
return Result.ofSuccess(ResourceVo.fromResourceTreeNode(treeNode));
} else {// cluster
} else {
// Normal (cluster node).
List<NodeVo> nodeVos = httpFetcher.fetchClusterNodeOfMachine(ip, port, true);
if (nodeVos == null) {
return Result.ofSuccess(null);


+ 2
- 4
sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/datasource/entity/ApplicationEntity.java View File

@@ -23,6 +23,7 @@ import com.alibaba.csp.sentinel.dashboard.discovery.AppInfo;
* @author leyou
*/
public class ApplicationEntity {

private Long id;
private Date gmtCreate;
private Date gmtModified;
@@ -79,10 +80,7 @@ public class ApplicationEntity {
}

public AppInfo toAppInfo() {
AppInfo appInfo = new AppInfo();
appInfo.setApp(app);

return appInfo;
return new AppInfo(app);
}

@Override


+ 1
- 1
sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/datasource/entity/MachineEntity.java View File

@@ -103,7 +103,7 @@ public class MachineEntity {
machineInfo.setHostname(hostname);
machineInfo.setIp(ip);
machineInfo.setPort(port);
machineInfo.setLastHeatbeat(timestamp.getTime());
machineInfo.setLastHeartbeat(timestamp.getTime());
machineInfo.setHeartbeatVersion(timestamp.getTime());

return machineInfo;


+ 20
- 33
sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/AppInfo.java View File

@@ -25,26 +25,12 @@ import java.util.concurrent.ConcurrentHashMap;
import com.alibaba.csp.sentinel.dashboard.config.DashboardConfig;

public class AppInfo {
private static final Comparator<MachineInfo> COMPARATOR_BY_MACHINE_HEARTBEAT_DESC = new Comparator<MachineInfo>() {

@Override
public int compare(MachineInfo o1, MachineInfo o2) {
if (o1.getLastHeatbeat() < o2.getLastHeatbeat()) {
return -1;
}
if (o1.getLastHeatbeat() > o2.getLastHeatbeat()) {
return 1;
}
return 0;
}
};

private String app = "";

private Set<MachineInfo> machines = ConcurrentHashMap.newKeySet();

public AppInfo() {
}
public AppInfo() {}

public AppInfo(String app) {
this.app = app;
@@ -76,7 +62,7 @@ public class AppInfo {
machines.remove(machineInfo);
return machines.add(machineInfo);
}
public synchronized boolean removeMachine(String ip, int port) {
Iterator<MachineInfo> it = machines.iterator();
while (it.hasNext()) {
@@ -88,44 +74,45 @@ public class AppInfo {
}
return false;
}
public Optional<MachineInfo> getMachine(String ip, int port) {
return machines.stream()
.filter(e -> e.getIp().equals(ip) && e.getPort().equals(port))
.findFirst();
}
private boolean heartbeatJudge(int threshold) {
private boolean heartbeatJudge(final int threshold) {
if (machines.size() == 0) {
return false;
}
if (threshold > 0) {
long healthyCount = machines.stream()
.filter(m -> m.isHealthy())
.count();
.filter(MachineInfo::isHealthy)
.count();
if (healthyCount == 0) {
// no machine
long recentHeartBeat = machines.stream()
.max(COMPARATOR_BY_MACHINE_HEARTBEAT_DESC).get().getLastHeatbeat();
return System.currentTimeMillis() - recentHeartBeat < threshold;
// No healthy machines.
return machines.stream()
.max(Comparator.comparingLong(MachineInfo::getLastHeartbeat))
.map(e -> System.currentTimeMillis() - e.getLastHeartbeat() < threshold)
.orElse(false);
}
}
return true;
}
/**
* having no healthy machine and should not be displayed
*
* @return
* Check whether current application has no healthy machines and should not be displayed.
*
* @return true if the application should be displayed in the sidebar, otherwise false
*/
public boolean isShown() {
return heartbeatJudge(DashboardConfig.getHideAppNoMachineMillis());
}
/**
* having no healthy machine and should be removed
*
* @return
* Check whether current application has no healthy machines and should be removed.
*
* @return true if the application is dead and should be removed, otherwise false
*/
public boolean isDead() {
return !heartbeatJudge(DashboardConfig.getRemoveAppNoMachineMillis());


+ 1
- 7
sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/AppManagement.java View File

@@ -27,16 +27,10 @@ import org.springframework.stereotype.Component;
@Component
public class AppManagement implements MachineDiscovery {

//@Value("${appmanagement.maxnode}")
//private Integer maxNode;
//
//@Value("${discovery.type}")
//private String type;

@Autowired
private ApplicationContext context;

MachineDiscovery machineDiscovery;
private MachineDiscovery machineDiscovery;

@PostConstruct
public void init() {


+ 17
- 2
sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/MachineDiscovery.java View File

@@ -27,10 +27,25 @@ public interface MachineDiscovery {
Set<AppInfo> getBriefApps();

AppInfo getDetailApp(String app);

/**
* Remove the given app from the application registry.
*
* @param app application name
* @since 1.5.0
*/
void removeApp(String app);

long addMachine(MachineInfo machineInfo);

/**
* Remove the given machine instance from the application registry.
*
* @param app the application name of the machine
* @param ip machine IP
* @param port machine port
* @return true if removed, otherwise false
* @since 1.5.0
*/
boolean removeMachine(String app, String ip, int port);
}

+ 8
- 8
sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/MachineInfo.java View File

@@ -26,7 +26,7 @@ public class MachineInfo implements Comparable<MachineInfo> {
private String hostname = "";
private String ip = "";
private Integer port = -1;
private long lastHeatbeat;
private long lastHeartbeat;
private long heartbeatVersion;

/**
@@ -96,7 +96,7 @@ public class MachineInfo implements Comparable<MachineInfo> {
}
public boolean isHealthy() {
long delta = System.currentTimeMillis() - lastHeatbeat;
long delta = System.currentTimeMillis() - lastHeartbeat;
return delta < DashboardConfig.getUnhealthyMachineMillis();
}
@@ -107,18 +107,18 @@ public class MachineInfo implements Comparable<MachineInfo> {
*/
public boolean isDead() {
if (DashboardConfig.getAutoRemoveMachineMillis() > 0) {
long delta = System.currentTimeMillis() - lastHeatbeat;
long delta = System.currentTimeMillis() - lastHeartbeat;
return delta > DashboardConfig.getAutoRemoveMachineMillis();
}
return false;
}
public long getLastHeatbeat() {
return lastHeatbeat;
public long getLastHeartbeat() {
return lastHeartbeat;
}
public void setLastHeatbeat(long lastHeatbeat) {
this.lastHeatbeat = lastHeatbeat;
public void setLastHeartbeat(long lastHeartbeat) {
this.lastHeartbeat = lastHeartbeat;
}

@Override
@@ -143,7 +143,7 @@ public class MachineInfo implements Comparable<MachineInfo> {
.append(", ip='").append(ip).append('\'')
.append(", port=").append(port)
.append(", heartbeatVersion=").append(heartbeatVersion)
.append(", lastHeartbeat=").append(lastHeatbeat)
.append(", lastHeartbeat=").append(lastHeartbeat)
.append(", version='").append(version).append('\'')
.append(", healthy=").append(isHealthy())
.append('}').toString();


+ 11
- 3
sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/discovery/SimpleMachineDiscovery.java View File

@@ -20,6 +20,9 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import com.alibaba.csp.sentinel.util.AssertUtil;

import org.springframework.stereotype.Component;

@@ -28,17 +31,20 @@ import org.springframework.stereotype.Component;
*/
@Component
public class SimpleMachineDiscovery implements MachineDiscovery {
protected ConcurrentHashMap<String, AppInfo> apps = new ConcurrentHashMap<>();

private final ConcurrentMap<String, AppInfo> apps = new ConcurrentHashMap<>();

@Override
public long addMachine(MachineInfo machineInfo) {
AppInfo appInfo = apps.computeIfAbsent(machineInfo.getApp(), app -> new AppInfo(app));
AssertUtil.notNull(machineInfo, "machineInfo cannot be null");
AppInfo appInfo = apps.computeIfAbsent(machineInfo.getApp(), AppInfo::new);
appInfo.addMachine(machineInfo);
return 1;
}
@Override
public boolean removeMachine(String app, String ip, int port) {
AssertUtil.assertNotBlank(app, "app name cannot be blank");
AppInfo appInfo = apps.get(app);
if (appInfo != null) {
return appInfo.removeMachine(ip, port);
@@ -53,6 +59,7 @@ public class SimpleMachineDiscovery implements MachineDiscovery {

@Override
public AppInfo getDetailApp(String app) {
AssertUtil.assertNotBlank(app, "app name cannot be blank");
return apps.get(app);
}

@@ -63,6 +70,7 @@ public class SimpleMachineDiscovery implements MachineDiscovery {

@Override
public void removeApp(String app) {
AssertUtil.assertNotBlank(app, "app name cannot be blank");
apps.remove(app);
}



+ 1
- 1
sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/domain/vo/MachineInfoVo.java View File

@@ -49,7 +49,7 @@ public class MachineInfoVo {
vo.setHostname(machine.getHostname());
vo.setIp(machine.getIp());
vo.setPort(machine.getPort());
vo.setLastHeartbeat(machine.getLastHeatbeat());
vo.setLastHeartbeat(machine.getLastHeartbeat());
vo.setHeartbeatVersion(machine.getHeartbeatVersion());
vo.setVersion(machine.getVersion());
vo.setHealthy(machine.isHealthy());


+ 2
- 10
sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/rule/FlowRuleApiProvider.java View File

@@ -47,16 +47,8 @@ public class FlowRuleApiProvider implements DynamicRuleProvider<List<FlowRuleEnt
}
List<MachineInfo> list = appManagement.getDetailApp(appName).getMachines()
.stream()
.filter(e -> e.isHealthy())
.sorted((e1, e2) -> {
if (e1.getLastHeatbeat() < e2.getLastHeatbeat()) {
return 1;
} else if (e1.getLastHeatbeat() > e2.getLastHeatbeat()) {
return -1;
} else {
return 0;
}
}).collect(Collectors.toList());
.filter(MachineInfo::isHealthy)
.sorted((e1, e2) -> Long.compare(e2.getLastHeartbeat(), e1.getLastHeartbeat())).collect(Collectors.toList());
if (list.isEmpty()) {
return new ArrayList<>();
} else {


+ 3
- 0
sentinel-dashboard/src/main/java/com/alibaba/csp/sentinel/dashboard/util/MachineUtils.java View File

@@ -24,6 +24,7 @@ import com.alibaba.csp.sentinel.util.function.Tuple2;
* @author Eric Zhao
*/
public final class MachineUtils {

public static Optional<Integer> parseCommandPort(String machineIp) {
try {
if (!machineIp.contains("@")) {
@@ -53,4 +54,6 @@ public final class MachineUtils {
return Optional.empty();
}
}

private MachineUtils() {}
}

+ 1
- 1
sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/authority.js View File

@@ -202,7 +202,7 @@ angular.module('sentinelDashboardApp').controller('AuthorityRuleController', ['$
$scope.machines = [];
$scope.macsInputOptions = [];
data.data.forEach(function (item) {
if (item.health) {
if (item.healthy) {
$scope.macsInputOptions.push({
text: item.ip + ':' + item.port,
value: item.ip + ':' + item.port


+ 1
- 1
sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/cluster_single.js View File

@@ -217,7 +217,7 @@ app.controller('SentinelClusterSingleController', ['$scope', '$stateParams', 'ng
$scope.macsInputOptionsOrigin = [];
$scope.macsInputOptions = [];
data.data.forEach(function (item) {
if (item.health) {
if (item.healthy) {
$scope.macsInputOptionsOrigin.push({
text: item.ip + ':' + item.port,
value: item.ip + ':' + item.port


+ 1
- 1
sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/degrade.js View File

@@ -177,7 +177,7 @@ app.controller('DegradeCtl', ['$scope', '$stateParams', 'DegradeService', 'ngDia
$scope.machines = [];
$scope.macsInputOptions = [];
data.data.forEach(function (item) {
if (item.health) {
if (item.healthy) {
$scope.macsInputOptions.push({
text: item.ip + ':' + item.port,
value: item.ip + ':' + item.port


+ 1
- 1
sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_v1.js View File

@@ -195,7 +195,7 @@ app.controller('FlowControllerV1', ['$scope', '$stateParams', 'FlowServiceV1', '
$scope.machines = [];
$scope.macsInputOptions = [];
data.data.forEach(function (item) {
if (item.health) {
if (item.healthy) {
$scope.macsInputOptions.push({
text: item.ip + ':' + item.port,
value: item.ip + ':' + item.port


+ 1
- 1
sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/flow_v2.js View File

@@ -196,7 +196,7 @@ app.controller('FlowControllerV2', ['$scope', '$stateParams', 'FlowServiceV2', '
$scope.machines = [];
$scope.macsInputOptions = [];
data.data.forEach(function (item) {
if (item.health) {
if (item.healthy) {
$scope.macsInputOptions.push({
text: item.ip + ':' + item.port,
value: item.ip + ':' + item.port


+ 2
- 3
sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/identity.js View File

@@ -387,13 +387,12 @@ app.controller('IdentityCtl', ['$scope', '$stateParams', 'IdentityService',
function queryAppMachines() {
MachineService.getAppMachines($scope.app).success(
function (data) {
if (data.code == 0) {
// $scope.machines = data.data;
if (data.code === 0) {
if (data.data) {
$scope.machines = [];
$scope.macsInputOptions = [];
data.data.forEach(function (item) {
if (item.health) {
if (item.healthy) {
$scope.macsInputOptions.push({
text: item.ip + ':' + item.port,
value: item.ip + ':' + item.port


+ 1
- 1
sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/param_flow.js View File

@@ -294,7 +294,7 @@ angular.module('sentinelDashboardApp').controller('ParamFlowController', ['$scop
$scope.machines = [];
$scope.macsInputOptions = [];
data.data.forEach(function (item) {
if (item.health) {
if (item.healthy) {
$scope.macsInputOptions.push({
text: item.ip + ':' + item.port,
value: item.ip + ':' + item.port


+ 1
- 1
sentinel-dashboard/src/main/webapp/resources/app/scripts/controllers/system.js View File

@@ -205,7 +205,7 @@ app.controller('SystemCtl', ['$scope', '$stateParams', 'SystemService', 'ngDialo
$scope.machines = [];
$scope.macsInputOptions = [];
data.data.forEach(function (item) {
if (item.health) {
if (item.healthy) {
$scope.macsInputOptions.push({
text: item.ip + ':' + item.port,
value: item.ip + ':' + item.port


+ 9
- 9
sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/discovery/AppInfoTest.java View File

@@ -79,7 +79,7 @@ public class AppInfoTest {
machineInfo.setHostname("bogon");
machineInfo.setIp("127.0.0.1");
machineInfo.setPort(3389);
machineInfo.setLastHeatbeat(System.currentTimeMillis());
machineInfo.setLastHeartbeat(System.currentTimeMillis());
machineInfo.setHeartbeatVersion(1);
machineInfo.setVersion("0.4.1");
appInfo.addMachine(machineInfo);
@@ -92,7 +92,7 @@ public class AppInfoTest {
machineInfo.setHostname("bogon");
machineInfo.setIp("127.0.0.1");
machineInfo.setPort(3389);
machineInfo.setLastHeatbeat(System.currentTimeMillis());
machineInfo.setLastHeartbeat(System.currentTimeMillis());
machineInfo.setHeartbeatVersion(1);
machineInfo.setVersion("0.4.2");
appInfo.addMachine(machineInfo);
@@ -105,7 +105,7 @@ public class AppInfoTest {
machineInfo.setHostname("bogon");
machineInfo.setIp("127.0.0.1");
machineInfo.setPort(3390);
machineInfo.setLastHeatbeat(System.currentTimeMillis());
machineInfo.setLastHeartbeat(System.currentTimeMillis());
machineInfo.setHeartbeatVersion(1);
machineInfo.setVersion("0.4.3");
appInfo.addMachine(machineInfo);
@@ -116,7 +116,7 @@ public class AppInfoTest {
appInfo.removeMachine("127.0.0.1", 3390);
assertEquals(0, appInfo.getMachines().size());
}
@Test
public void testHealthyAndDead() {
System.setProperty(DashboardConfig.CONFIG_HIDE_APP_NO_MACHINE_MILLIS, "60000");
@@ -128,25 +128,25 @@ public class AppInfoTest {
{
MachineInfo machineInfo = MachineInfo.of(appName, "127.0.0.1", 8801);
machineInfo.setHeartbeatVersion(1);
machineInfo.setLastHeatbeat(System.currentTimeMillis());
machineInfo.setLastHeartbeat(System.currentTimeMillis());
appInfo.addMachine(machineInfo);
}
assertTrue(appInfo.isShown());
assertFalse(appInfo.isDead());
{
MachineInfo machineInfo = MachineInfo.of(appName, "127.0.0.1", 8801);
machineInfo.setHeartbeatVersion(1);
machineInfo.setLastHeatbeat(System.currentTimeMillis() - 70000);
machineInfo.setLastHeartbeat(System.currentTimeMillis() - 70000);
appInfo.addMachine(machineInfo);
}
assertFalse(appInfo.isShown());
assertFalse(appInfo.isDead());
{
MachineInfo machineInfo = MachineInfo.of(appName, "127.0.0.1", 8801);
machineInfo.setHeartbeatVersion(1);
machineInfo.setLastHeatbeat(System.currentTimeMillis() - 700000);
machineInfo.setLastHeartbeat(System.currentTimeMillis() - 700000);
appInfo.addMachine(machineInfo);
}
assertFalse(appInfo.isShown());


+ 9
- 5
sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/discovery/MachineInfoTest.java View File

@@ -21,7 +21,11 @@ import org.junit.Test;

import com.alibaba.csp.sentinel.dashboard.config.DashboardConfig;

/**
* @author Jason Joo
*/
public class MachineInfoTest {

@Test
public void testHealthyAndDead() {
System.setProperty(DashboardConfig.CONFIG_UNHEALTHY_MACHINE_MILLIS, "60000");
@@ -29,15 +33,15 @@ public class MachineInfoTest {
DashboardConfig.clearCache();
MachineInfo machineInfo = new MachineInfo();
machineInfo.setHeartbeatVersion(1);
machineInfo.setLastHeatbeat(System.currentTimeMillis() - 10000);
machineInfo.setLastHeartbeat(System.currentTimeMillis() - 10000);
assertTrue(machineInfo.isHealthy());
assertFalse(machineInfo.isDead());
machineInfo.setLastHeatbeat(System.currentTimeMillis() - 100000);
machineInfo.setLastHeartbeat(System.currentTimeMillis() - 100000);
assertFalse(machineInfo.isHealthy());
assertFalse(machineInfo.isDead());
machineInfo.setLastHeatbeat(System.currentTimeMillis() - 1000000);
machineInfo.setLastHeartbeat(System.currentTimeMillis() - 1000000);
assertFalse(machineInfo.isHealthy());
assertTrue(machineInfo.isDead());
}


+ 15
- 8
sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/repository/metric/InMemoryMetricsRepositoryTest.java View File

@@ -119,13 +119,11 @@ public class InMemoryMetricsRepositoryTest {
try {
cyclicBarrier.await();
inMemoryMetricsRepository.listResourcesOfApp(DEFAULT_APP);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}, executorService
));
}, executorService)
);
}

// batch add metric entity
@@ -142,11 +140,20 @@ public class InMemoryMetricsRepositoryTest {
}

CompletableFuture all = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));

try {
all.join();
} catch (ConcurrentModificationException e) {
all.get(10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
fail("concurrent error occurred");
} catch (ExecutionException e) {
e.getCause().printStackTrace();
if (e.getCause() instanceof ConcurrentModificationException) {
fail("concurrent error occurred");
} else {
fail("unexpected exception");
}
} catch (TimeoutException e) {
fail("allOf future timeout");
}
}


+ 6
- 6
sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/ApolloConfig.java View File

@@ -19,11 +19,11 @@ import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.config.ConfigFactory;
import com.alibaba.nacos.api.config.ConfigService;

import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;

/**
@@ -44,11 +44,11 @@ public class ApolloConfig {
}

@Bean
public ApolloOpenApiClient apolloOpenApiClient(){
public ApolloOpenApiClient apolloOpenApiClient() {
ApolloOpenApiClient client = ApolloOpenApiClient.newBuilder()
.withPortalUrl("http://localhost:10034")
.withToken("token")
.build();
.withPortalUrl("http://localhost:10034")
.withToken("token")
.build();
return client;

}


+ 8
- 7
sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/FlowRuleApolloProvider.java View File

@@ -20,10 +20,12 @@ import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRuleProvider;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.StringUtil;

import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
import com.ctrip.framework.apollo.openapi.dto.OpenNamespaceDTO;
@@ -46,17 +48,16 @@ public class FlowRuleApolloProvider implements DynamicRuleProvider<List<FlowRule
String flowDataId = ApolloConfigUtil.getFlowDataId(appName);
OpenNamespaceDTO openNamespaceDTO = apolloOpenApiClient.getNamespace(appId, "DEV", "default", "application");
String rules = openNamespaceDTO
.getItems()
.stream()
.filter(p -> p.getKey().equals(flowDataId))
.map(OpenItemDTO::getValue)
.findFirst()
.orElse("");
.getItems()
.stream()
.filter(p -> p.getKey().equals(flowDataId))
.map(OpenItemDTO::getValue)
.findFirst()
.orElse("");

if (StringUtil.isEmpty(rules)) {
return new ArrayList<>();
}
return converter.convert(rules);

}
}

+ 8
- 12
sentinel-dashboard/src/test/java/com/alibaba/csp/sentinel/dashboard/rule/apollo/FlowRuleApolloPublisher.java View File

@@ -19,11 +19,12 @@ import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.csp.sentinel.dashboard.datasource.entity.rule.FlowRuleEntity;
import com.alibaba.csp.sentinel.dashboard.rule.DynamicRulePublisher;
import com.alibaba.csp.sentinel.datasource.Converter;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.alibaba.nacos.api.config.ConfigService;
import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
import com.ctrip.framework.apollo.openapi.dto.NamespaceReleaseDTO;
import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
@@ -47,27 +48,22 @@ public class FlowRuleApolloPublisher implements DynamicRulePublisher<List<FlowRu
return;
}

/**
* Increase the configuration
*/
// Increase the configuration
String appId = "appId";
String flowDataId = ApolloConfigUtil.getFlowDataId(app);
OpenItemDTO openItemDTO = new OpenItemDTO();
openItemDTO.setKey(flowDataId);
openItemDTO.setValue(converter.convert(rules));
openItemDTO.setComment("Program auto-join");
openItemDTO.setDataChangeCreatedBy("hantianwei");
apolloOpenApiClient.createOrUpdateItem(appId,"DEV","default","application",openItemDTO);
openItemDTO.setDataChangeCreatedBy("some-operator");
apolloOpenApiClient.createOrUpdateItem(appId, "DEV", "default", "application", openItemDTO);

/**
* Release configuration
*/
// Release configuration
NamespaceReleaseDTO namespaceReleaseDTO = new NamespaceReleaseDTO();
namespaceReleaseDTO.setEmergencyPublish(true);
namespaceReleaseDTO.setReleaseComment("Modify or add configurations");
namespaceReleaseDTO.setReleasedBy("hantianwei");
namespaceReleaseDTO.setReleasedBy("some-operator");
namespaceReleaseDTO.setReleaseTitle("Modify or add configurations");
apolloOpenApiClient.publishNamespace(appId,"DEV","default","application",namespaceReleaseDTO);

apolloOpenApiClient.publishNamespace(appId, "DEV", "default", "application", namespaceReleaseDTO);
}
}

Loading…
Cancel
Save