Merge branch 'master' of github.com:thingsboard/thingsboard into new-nodes
This commit is contained in:
commit
34b1df6b73
@ -52,6 +52,8 @@ import javax.annotation.PostConstruct;
|
|||||||
import javax.annotation.PreDestroy;
|
import javax.annotation.PreDestroy;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent.Type.CHILD_REMOVED;
|
import static org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent.Type.CHILD_REMOVED;
|
||||||
@ -96,11 +98,13 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi
|
|||||||
@Lazy
|
@Lazy
|
||||||
private ClusterRoutingService routingService;
|
private ClusterRoutingService routingService;
|
||||||
|
|
||||||
|
private ExecutorService reconnectExecutorService;
|
||||||
|
|
||||||
private CuratorFramework client;
|
private CuratorFramework client;
|
||||||
private PathChildrenCache cache;
|
private PathChildrenCache cache;
|
||||||
private String nodePath;
|
private String nodePath;
|
||||||
|
|
||||||
private volatile boolean stopped = false;
|
private volatile boolean stopped = true;
|
||||||
|
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
@ -110,9 +114,15 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi
|
|||||||
Assert.notNull(zkConnectionTimeout, MiscUtils.missingProperty("zk.connection_timeout_ms"));
|
Assert.notNull(zkConnectionTimeout, MiscUtils.missingProperty("zk.connection_timeout_ms"));
|
||||||
Assert.notNull(zkSessionTimeout, MiscUtils.missingProperty("zk.session_timeout_ms"));
|
Assert.notNull(zkSessionTimeout, MiscUtils.missingProperty("zk.session_timeout_ms"));
|
||||||
|
|
||||||
|
reconnectExecutorService = Executors.newSingleThreadExecutor();
|
||||||
|
|
||||||
log.info("Initializing discovery service using ZK connect string: {}", zkUrl);
|
log.info("Initializing discovery service using ZK connect string: {}", zkUrl);
|
||||||
|
|
||||||
zkNodesDir = zkDir + "/nodes";
|
zkNodesDir = zkDir + "/nodes";
|
||||||
|
initZkClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initZkClient() {
|
||||||
try {
|
try {
|
||||||
client = CuratorFrameworkFactory.newClient(zkUrl, zkSessionTimeout, zkConnectionTimeout, new RetryForever(zkRetryInterval));
|
client = CuratorFrameworkFactory.newClient(zkUrl, zkSessionTimeout, zkConnectionTimeout, new RetryForever(zkRetryInterval));
|
||||||
client.start();
|
client.start();
|
||||||
@ -120,6 +130,8 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi
|
|||||||
cache = new PathChildrenCache(client, zkNodesDir, true);
|
cache = new PathChildrenCache(client, zkNodesDir, true);
|
||||||
cache.getListenable().addListener(this);
|
cache.getListenable().addListener(this);
|
||||||
cache.start();
|
cache.start();
|
||||||
|
stopped = false;
|
||||||
|
log.info("ZK client connected");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("Failed to connect to ZK: {}", e.getMessage(), e);
|
log.error("Failed to connect to ZK: {}", e.getMessage(), e);
|
||||||
CloseableUtils.closeQuietly(cache);
|
CloseableUtils.closeQuietly(cache);
|
||||||
@ -128,12 +140,20 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreDestroy
|
private void destroyZkClient() {
|
||||||
public void destroy() {
|
|
||||||
stopped = true;
|
stopped = true;
|
||||||
unpublishCurrentServer();
|
try {
|
||||||
|
unpublishCurrentServer();
|
||||||
|
} catch (Exception e) {}
|
||||||
CloseableUtils.closeQuietly(cache);
|
CloseableUtils.closeQuietly(cache);
|
||||||
CloseableUtils.closeQuietly(client);
|
CloseableUtils.closeQuietly(client);
|
||||||
|
log.info("ZK client disconnected");
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreDestroy
|
||||||
|
public void destroy() {
|
||||||
|
destroyZkClient();
|
||||||
|
reconnectExecutorService.shutdownNow();
|
||||||
log.info("Stopped discovery service");
|
log.info("Stopped discovery service");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,20 +200,21 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi
|
|||||||
return (client, newState) -> {
|
return (client, newState) -> {
|
||||||
log.info("[{}:{}] ZK state changed: {}", self.getHost(), self.getPort(), newState);
|
log.info("[{}:{}] ZK state changed: {}", self.getHost(), self.getPort(), newState);
|
||||||
if (newState == ConnectionState.LOST) {
|
if (newState == ConnectionState.LOST) {
|
||||||
reconnect();
|
reconnectExecutorService.submit(this::reconnect);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean reconnectInProgress = false;
|
private volatile boolean reconnectInProgress = false;
|
||||||
|
|
||||||
private synchronized void reconnect() {
|
private synchronized void reconnect() {
|
||||||
if (!reconnectInProgress) {
|
if (!reconnectInProgress) {
|
||||||
reconnectInProgress = true;
|
reconnectInProgress = true;
|
||||||
try {
|
try {
|
||||||
client.blockUntilConnected();
|
destroyZkClient();
|
||||||
|
initZkClient();
|
||||||
publishCurrentServer();
|
publishCurrentServer();
|
||||||
} catch (InterruptedException e) {
|
} catch (Exception e) {
|
||||||
log.error("Failed to reconnect to ZK: {}", e.getMessage(), e);
|
log.error("Failed to reconnect to ZK: {}", e.getMessage(), e);
|
||||||
} finally {
|
} finally {
|
||||||
reconnectInProgress = false;
|
reconnectInProgress = false;
|
||||||
|
|||||||
@ -273,23 +273,17 @@ updates:
|
|||||||
spring.mvc.cors:
|
spring.mvc.cors:
|
||||||
mappings:
|
mappings:
|
||||||
# Intercept path
|
# Intercept path
|
||||||
"/api/auth/**":
|
"[/api/**]":
|
||||||
#Comma-separated list of origins to allow. '*' allows all origins. When not set,CORS support is disabled.
|
#Comma-separated list of origins to allow. '*' allows all origins. When not set,CORS support is disabled.
|
||||||
allowed-origins: "*"
|
allowed-origins: "*"
|
||||||
#Comma-separated list of methods to allow. '*' allows all methods.
|
#Comma-separated list of methods to allow. '*' allows all methods.
|
||||||
allowed-methods: "POST,GET,OPTIONS"
|
allowed-methods: "*"
|
||||||
#Comma-separated list of headers to allow in a request. '*' allows all headers.
|
#Comma-separated list of headers to allow in a request. '*' allows all headers.
|
||||||
allowed-headers: "*"
|
allowed-headers: "*"
|
||||||
#How long, in seconds, the response from a pre-flight request can be cached by clients.
|
#How long, in seconds, the response from a pre-flight request can be cached by clients.
|
||||||
max-age: "1800"
|
max-age: "1800"
|
||||||
#Set whether credentials are supported. When not set, credentials are not supported.
|
#Set whether credentials are supported. When not set, credentials are not supported.
|
||||||
allow-credentials: "true"
|
allow-credentials: "true"
|
||||||
"/api/v1/**":
|
|
||||||
allowed-origins: "*"
|
|
||||||
allowed-methods: "*"
|
|
||||||
allowed-headers: "*"
|
|
||||||
max-age: "1800"
|
|
||||||
allow-credentials: "true"
|
|
||||||
|
|
||||||
# spring serve gzip compressed static resources
|
# spring serve gzip compressed static resources
|
||||||
spring.resources.chain:
|
spring.resources.chain:
|
||||||
|
|||||||
4
pom.xml
4
pom.xml
@ -50,7 +50,7 @@
|
|||||||
<commons-validator.version>1.5.0</commons-validator.version>
|
<commons-validator.version>1.5.0</commons-validator.version>
|
||||||
<commons-io.version>2.5</commons-io.version>
|
<commons-io.version>2.5</commons-io.version>
|
||||||
<commons-csv.version>1.4</commons-csv.version>
|
<commons-csv.version>1.4</commons-csv.version>
|
||||||
<jackson.version>2.9.7</jackson.version>
|
<jackson.version>2.9.8</jackson.version>
|
||||||
<json-schema-validator.version>2.2.6</json-schema-validator.version>
|
<json-schema-validator.version>2.2.6</json-schema-validator.version>
|
||||||
<scala.version>2.11</scala.version>
|
<scala.version>2.11</scala.version>
|
||||||
<akka.version>2.4.2</akka.version>
|
<akka.version>2.4.2</akka.version>
|
||||||
@ -59,7 +59,7 @@
|
|||||||
<velocity.version>1.7</velocity.version>
|
<velocity.version>1.7</velocity.version>
|
||||||
<velocity-tools.version>2.0</velocity-tools.version>
|
<velocity-tools.version>2.0</velocity-tools.version>
|
||||||
<mail.version>1.4.3</mail.version>
|
<mail.version>1.4.3</mail.version>
|
||||||
<curator.version>4.0.1</curator.version>
|
<curator.version>4.2.0</curator.version>
|
||||||
<protobuf.version>3.6.1</protobuf.version>
|
<protobuf.version>3.6.1</protobuf.version>
|
||||||
<grpc.version>1.16.1</grpc.version>
|
<grpc.version>1.16.1</grpc.version>
|
||||||
<lombok.version>1.16.18</lombok.version>
|
<lombok.version>1.16.18</lombok.version>
|
||||||
|
|||||||
@ -283,7 +283,7 @@ function Contact($compile, $templateCache) {
|
|||||||
"Austria": "[0-9]{4}",
|
"Austria": "[0-9]{4}",
|
||||||
"Belgium": "[0-9]{4}",
|
"Belgium": "[0-9]{4}",
|
||||||
"Brazil": "[0-9]{5}[\\-]?[0-9]{3}",
|
"Brazil": "[0-9]{5}[\\-]?[0-9]{3}",
|
||||||
"Canada": "[A-Za-z][0-9][A-Za-z] [0-9][A-Za-z][0-9]",
|
"Canada": "^(?!.*[DFIOQU])[A-VXY][0-9][A-Z][ -]?[0-9][A-Z][0-9]$",
|
||||||
"Denmark": "[0-9]{3,4}",
|
"Denmark": "[0-9]{3,4}",
|
||||||
"Faroe Islands": "[0-9]{3,4}",
|
"Faroe Islands": "[0-9]{3,4}",
|
||||||
"Netherlands": "[1-9][0-9]{3}\\s?[a-zA-Z]{2}",
|
"Netherlands": "[1-9][0-9]{3}\\s?[a-zA-Z]{2}",
|
||||||
|
|||||||
@ -1295,7 +1295,8 @@
|
|||||||
"metadata-required": "Metadata entries can't be empty.",
|
"metadata-required": "Metadata entries can't be empty.",
|
||||||
"output": "Output",
|
"output": "Output",
|
||||||
"test": "Test",
|
"test": "Test",
|
||||||
"help": "Help"
|
"help": "Help",
|
||||||
|
"reset-debug-mode": "Reset debug mode in all nodes"
|
||||||
},
|
},
|
||||||
"tenant": {
|
"tenant": {
|
||||||
"tenant": "Tenant",
|
"tenant": "Tenant",
|
||||||
|
|||||||
@ -1288,7 +1288,8 @@
|
|||||||
"metadata-required": "Метаданные объекта не могут быть пустыми.",
|
"metadata-required": "Метаданные объекта не могут быть пустыми.",
|
||||||
"output": "Выход",
|
"output": "Выход",
|
||||||
"test": "Протестировать",
|
"test": "Протестировать",
|
||||||
"help": "Помощь"
|
"help": "Помощь",
|
||||||
|
"reset-debug-mode": "Сбросить режим отладки во всех правилах"
|
||||||
},
|
},
|
||||||
"tenant": {
|
"tenant": {
|
||||||
"tenant": "Владелец",
|
"tenant": "Владелец",
|
||||||
|
|||||||
@ -108,6 +108,9 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
|
|||||||
vm.objectsSelected = objectsSelected;
|
vm.objectsSelected = objectsSelected;
|
||||||
vm.deleteSelected = deleteSelected;
|
vm.deleteSelected = deleteSelected;
|
||||||
|
|
||||||
|
vm.isDebugModeEnabled = isDebugModeEnabled;
|
||||||
|
vm.resetDebugModeInAllNodes = resetDebugModeInAllNodes;
|
||||||
|
|
||||||
vm.triggerResize = triggerResize;
|
vm.triggerResize = triggerResize;
|
||||||
|
|
||||||
vm.openRuleChainContextMenu = openRuleChainContextMenu;
|
vm.openRuleChainContextMenu = openRuleChainContextMenu;
|
||||||
@ -1342,6 +1345,19 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
|
|||||||
vm.modelservice.deleteSelected();
|
vm.modelservice.deleteSelected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isDebugModeEnabled() {
|
||||||
|
var res = $filter('filter')(vm.ruleChainModel.nodes, {debugMode: true});
|
||||||
|
return (res && res.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetDebugModeInAllNodes() {
|
||||||
|
vm.ruleChainModel.nodes.forEach((node) => {
|
||||||
|
if (node.component.type != types.ruleNodeType.INPUT.value && node.component.type != types.ruleNodeType.RULE_CHAIN.value) {
|
||||||
|
node.debugMode = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function triggerResize() {
|
function triggerResize() {
|
||||||
var w = angular.element($window);
|
var w = angular.element($window);
|
||||||
w.triggerHandler('resize');
|
w.triggerHandler('resize');
|
||||||
|
|||||||
@ -223,6 +223,15 @@
|
|||||||
</md-tooltip>
|
</md-tooltip>
|
||||||
<ng-md-icon icon="delete"></ng-md-icon>
|
<ng-md-icon icon="delete"></ng-md-icon>
|
||||||
</md-button>
|
</md-button>
|
||||||
|
<md-button ng-disabled="$root.loading || !vm.isDebugModeEnabled()"
|
||||||
|
class="tb-btn-footer md-accent md-hue-2 md-fab"
|
||||||
|
aria-label="{{ 'rulenode.reset-debug-mode' | translate }}"
|
||||||
|
ng-click="vm.resetDebugModeInAllNodes()">
|
||||||
|
<md-tooltip md-direction="top">
|
||||||
|
{{ 'rulenode.reset-debug-mode' | translate }}
|
||||||
|
</md-tooltip>
|
||||||
|
<ng-md-icon icon="bug_report"></ng-md-icon>
|
||||||
|
</md-button>
|
||||||
<md-button ng-disabled="$root.loading || vm.isInvalid || (!vm.isDirty && !vm.isImport)"
|
<md-button ng-disabled="$root.loading || vm.isInvalid || (!vm.isDirty && !vm.isImport)"
|
||||||
class="tb-btn-footer md-accent md-hue-2 md-fab"
|
class="tb-btn-footer md-accent md-hue-2 md-fab"
|
||||||
aria-label="{{ 'action.apply' | translate }}"
|
aria-label="{{ 'action.apply' | translate }}"
|
||||||
|
|||||||
@ -137,9 +137,11 @@ export default class TbFlot {
|
|||||||
});
|
});
|
||||||
content += dateDiv.prop('outerHTML');
|
content += dateDiv.prop('outerHTML');
|
||||||
if (tbFlot.ctx.tooltipIndividual) {
|
if (tbFlot.ctx.tooltipIndividual) {
|
||||||
var seriesHoverInfo = hoverInfo.seriesHover[seriesIndex];
|
var found = hoverInfo.seriesHover.filter((seriesHover) => {
|
||||||
if (seriesHoverInfo) {
|
return seriesHover.index === seriesIndex;
|
||||||
content += seriesInfoDivFromInfo(seriesHoverInfo, seriesIndex);
|
});
|
||||||
|
if (found && found.length) {
|
||||||
|
content += seriesInfoDivFromInfo(found[0], seriesIndex);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
var seriesDiv = $('<div></div>');
|
var seriesDiv = $('<div></div>');
|
||||||
@ -161,7 +163,7 @@ export default class TbFlot {
|
|||||||
if (i == hoverInfo.seriesHover.length) {
|
if (i == hoverInfo.seriesHover.length) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
seriesHoverInfo = hoverInfo.seriesHover[i];
|
var seriesHoverInfo = hoverInfo.seriesHover[i];
|
||||||
columnContent += seriesInfoDivFromInfo(seriesHoverInfo, seriesIndex);
|
columnContent += seriesInfoDivFromInfo(seriesHoverInfo, seriesIndex);
|
||||||
}
|
}
|
||||||
columnDiv.html(columnContent);
|
columnDiv.html(columnContent);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user