Merge branch 'master' of github.com:thingsboard/thingsboard into new-nodes

This commit is contained in:
nordmif 2019-03-27 14:04:31 +02:00
commit 34b1df6b73
9 changed files with 69 additions and 25 deletions

View File

@ -52,6 +52,8 @@ import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import static org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent.Type.CHILD_REMOVED;
@ -96,11 +98,13 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi
@Lazy
private ClusterRoutingService routingService;
private ExecutorService reconnectExecutorService;
private CuratorFramework client;
private PathChildrenCache cache;
private String nodePath;
private volatile boolean stopped = false;
private volatile boolean stopped = true;
@PostConstruct
public void init() {
@ -110,9 +114,15 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi
Assert.notNull(zkConnectionTimeout, MiscUtils.missingProperty("zk.connection_timeout_ms"));
Assert.notNull(zkSessionTimeout, MiscUtils.missingProperty("zk.session_timeout_ms"));
reconnectExecutorService = Executors.newSingleThreadExecutor();
log.info("Initializing discovery service using ZK connect string: {}", zkUrl);
zkNodesDir = zkDir + "/nodes";
initZkClient();
}
private void initZkClient() {
try {
client = CuratorFrameworkFactory.newClient(zkUrl, zkSessionTimeout, zkConnectionTimeout, new RetryForever(zkRetryInterval));
client.start();
@ -120,6 +130,8 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi
cache = new PathChildrenCache(client, zkNodesDir, true);
cache.getListenable().addListener(this);
cache.start();
stopped = false;
log.info("ZK client connected");
} catch (Exception e) {
log.error("Failed to connect to ZK: {}", e.getMessage(), e);
CloseableUtils.closeQuietly(cache);
@ -128,12 +140,20 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi
}
}
@PreDestroy
public void destroy() {
private void destroyZkClient() {
stopped = true;
try {
unpublishCurrentServer();
} catch (Exception e) {}
CloseableUtils.closeQuietly(cache);
CloseableUtils.closeQuietly(client);
log.info("ZK client disconnected");
}
@PreDestroy
public void destroy() {
destroyZkClient();
reconnectExecutorService.shutdownNow();
log.info("Stopped discovery service");
}
@ -180,20 +200,21 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi
return (client, newState) -> {
log.info("[{}:{}] ZK state changed: {}", self.getHost(), self.getPort(), newState);
if (newState == ConnectionState.LOST) {
reconnect();
reconnectExecutorService.submit(this::reconnect);
}
};
}
private boolean reconnectInProgress = false;
private volatile boolean reconnectInProgress = false;
private synchronized void reconnect() {
if (!reconnectInProgress) {
reconnectInProgress = true;
try {
client.blockUntilConnected();
destroyZkClient();
initZkClient();
publishCurrentServer();
} catch (InterruptedException e) {
} catch (Exception e) {
log.error("Failed to reconnect to ZK: {}", e.getMessage(), e);
} finally {
reconnectInProgress = false;

View File

@ -273,23 +273,17 @@ updates:
spring.mvc.cors:
mappings:
# Intercept path
"/api/auth/**":
"[/api/**]":
#Comma-separated list of origins to allow. '*' allows all origins. When not set,CORS support is disabled.
allowed-origins: "*"
#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.
allowed-headers: "*"
#How long, in seconds, the response from a pre-flight request can be cached by clients.
max-age: "1800"
#Set whether credentials are supported. When not set, credentials are not supported.
allow-credentials: "true"
"/api/v1/**":
allowed-origins: "*"
allowed-methods: "*"
allowed-headers: "*"
max-age: "1800"
allow-credentials: "true"
# spring serve gzip compressed static resources
spring.resources.chain:

View File

@ -50,7 +50,7 @@
<commons-validator.version>1.5.0</commons-validator.version>
<commons-io.version>2.5</commons-io.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>
<scala.version>2.11</scala.version>
<akka.version>2.4.2</akka.version>
@ -59,7 +59,7 @@
<velocity.version>1.7</velocity.version>
<velocity-tools.version>2.0</velocity-tools.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>
<grpc.version>1.16.1</grpc.version>
<lombok.version>1.16.18</lombok.version>

View File

@ -283,7 +283,7 @@ function Contact($compile, $templateCache) {
"Austria": "[0-9]{4}",
"Belgium": "[0-9]{4}",
"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}",
"Faroe Islands": "[0-9]{3,4}",
"Netherlands": "[1-9][0-9]{3}\\s?[a-zA-Z]{2}",

View File

@ -1295,7 +1295,8 @@
"metadata-required": "Metadata entries can't be empty.",
"output": "Output",
"test": "Test",
"help": "Help"
"help": "Help",
"reset-debug-mode": "Reset debug mode in all nodes"
},
"tenant": {
"tenant": "Tenant",

View File

@ -1288,7 +1288,8 @@
"metadata-required": "Метаданные объекта не могут быть пустыми.",
"output": "Выход",
"test": "Протестировать",
"help": "Помощь"
"help": "Помощь",
"reset-debug-mode": "Сбросить режим отладки во всех правилах"
},
"tenant": {
"tenant": "Владелец",

View File

@ -108,6 +108,9 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
vm.objectsSelected = objectsSelected;
vm.deleteSelected = deleteSelected;
vm.isDebugModeEnabled = isDebugModeEnabled;
vm.resetDebugModeInAllNodes = resetDebugModeInAllNodes;
vm.triggerResize = triggerResize;
vm.openRuleChainContextMenu = openRuleChainContextMenu;
@ -1342,6 +1345,19 @@ export function RuleChainController($state, $scope, $compile, $q, $mdUtil, $time
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() {
var w = angular.element($window);
w.triggerHandler('resize');

View File

@ -223,6 +223,15 @@
</md-tooltip>
<ng-md-icon icon="delete"></ng-md-icon>
</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)"
class="tb-btn-footer md-accent md-hue-2 md-fab"
aria-label="{{ 'action.apply' | translate }}"

View File

@ -137,9 +137,11 @@ export default class TbFlot {
});
content += dateDiv.prop('outerHTML');
if (tbFlot.ctx.tooltipIndividual) {
var seriesHoverInfo = hoverInfo.seriesHover[seriesIndex];
if (seriesHoverInfo) {
content += seriesInfoDivFromInfo(seriesHoverInfo, seriesIndex);
var found = hoverInfo.seriesHover.filter((seriesHover) => {
return seriesHover.index === seriesIndex;
});
if (found && found.length) {
content += seriesInfoDivFromInfo(found[0], seriesIndex);
}
} else {
var seriesDiv = $('<div></div>');
@ -161,7 +163,7 @@ export default class TbFlot {
if (i == hoverInfo.seriesHover.length) {
break;
}
seriesHoverInfo = hoverInfo.seriesHover[i];
var seriesHoverInfo = hoverInfo.seriesHover[i];
columnContent += seriesInfoDivFromInfo(seriesHoverInfo, seriesIndex);
}
columnDiv.html(columnContent);