From 1c09299b7a695d91f010d3d918cbdf643989284e Mon Sep 17 00:00:00 2001 From: mp-loki Date: Sun, 8 Apr 2018 19:10:53 -0400 Subject: [PATCH 1/8] OPC-UA Extension fix for security type "None" --- .../app/extension/extensions-forms/extension-form-opc.tpl.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/app/extension/extensions-forms/extension-form-opc.tpl.html b/ui/src/app/extension/extensions-forms/extension-form-opc.tpl.html index 5a7c00ba3b..59d8a7e0b4 100644 --- a/ui/src/app/extension/extensions-forms/extension-form-opc.tpl.html +++ b/ui/src/app/extension/extensions-forms/extension-form-opc.tpl.html @@ -194,7 +194,7 @@ - + {{ 'extension.opc-keystore' | translate }} From cfcd71adb3d362627d4ef1a16d6ffc6517cc0265 Mon Sep 17 00:00:00 2001 From: DK Date: Wed, 11 Apr 2018 15:32:13 +0500 Subject: [PATCH 2/8] Implemented GUI configuration for MODBUS gateway extension. --- ui/src/app/common/types.constant.js | 23 +- .../extension/extension-dialog.controller.js | 2 +- .../app/extension/extension-dialog.tpl.html | 1 + .../extension-form-modbus.directive.js | 131 +++ .../extension-form-modbus.tpl.html | 818 ++++++++++++++++++ ui/src/app/extension/index.js | 3 + ui/src/app/locale/locale.constant.js | 30 + 7 files changed, 1006 insertions(+), 2 deletions(-) create mode 100644 ui/src/app/extension/extensions-forms/extension-form-modbus.directive.js create mode 100644 ui/src/app/extension/extensions-forms/extension-form-modbus.tpl.html diff --git a/ui/src/app/common/types.constant.js b/ui/src/app/common/types.constant.js index ef6ffde28a..66ed196854 100644 --- a/ui/src/app/common/types.constant.js +++ b/ui/src/app/common/types.constant.js @@ -384,7 +384,8 @@ export default angular.module('thingsboard.types', []) extensionType: { http: "HTTP", mqtt: "MQTT", - opc: "OPC UA" + opc: "OPC UA", + modbus: "MODBUS" }, extensionValueType: { string: 'value.string', @@ -428,6 +429,26 @@ export default angular.module('thingsboard.types', []) PKCS12: "PKCS12", JKS: "JKS" }, + extensionModbusFunctionCodes: { + 1: "Read Coils (1)", + 2: "Read Discrete Inputs (2)", + 3: "Read Multiple Holding Registers (3)", + 4: "Read Input Registers (4)" + }, + extensionModbusTransports: { + tcp: "TCP", + udp: "UDP", + rtu: "RTU" + }, + extensionModbusRtuParities: { + none: "none", + even: "even", + odd: "odd" + }, + extensionModbusRtuEncodings: { + ascii: "ascii", + rtu: "rtu" + }, latestTelemetry: { value: "LATEST_TELEMETRY", name: "attribute.scope-latest-telemetry", diff --git a/ui/src/app/extension/extension-dialog.controller.js b/ui/src/app/extension/extension-dialog.controller.js index 2b0eded0ae..4b8221a4a2 100644 --- a/ui/src/app/extension/extension-dialog.controller.js +++ b/ui/src/app/extension/extension-dialog.controller.js @@ -49,7 +49,7 @@ export default function ExtensionDialogController($scope, $mdDialog, $translate, "brokers": [] }; } - if (vm.extension.type === "OPC UA") { + if (vm.extension.type === "OPC UA" || vm.extension.type === "MODBUS") { vm.extension.configuration = { "servers": [] }; diff --git a/ui/src/app/extension/extension-dialog.tpl.html b/ui/src/app/extension/extension-dialog.tpl.html index 4e200d5bad..fcf78407e6 100644 --- a/ui/src/app/extension/extension-dialog.tpl.html +++ b/ui/src/app/extension/extension-dialog.tpl.html @@ -62,6 +62,7 @@
+
diff --git a/ui/src/app/extension/extensions-forms/extension-form-modbus.directive.js b/ui/src/app/extension/extensions-forms/extension-form-modbus.directive.js new file mode 100644 index 0000000000..aec5625eb7 --- /dev/null +++ b/ui/src/app/extension/extensions-forms/extension-form-modbus.directive.js @@ -0,0 +1,131 @@ +/* + * Copyright © 2016-2018 The Thingsboard Authors + * + * 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. + */ +import 'brace/ext/language_tools'; +import 'brace/mode/json'; +import 'brace/theme/github'; + +import './extension-form.scss'; + +/* eslint-disable angular/log */ + +import extensionFormModbusTemplate from './extension-form-modbus.tpl.html'; + +/* eslint-enable import/no-unresolved, import/default */ + +/*@ngInject*/ +export default function ExtensionFormModbusDirective($compile, $templateCache, $translate, types) { + + + var linker = function(scope, element) { + + + function Server() { + this.transport = { + "type": "tcp", + "host": "localhost", + "port": 502, + "timeout": 3000 + }; + this.devices = [] + } + + function Device() { + this.unitId = 1; + this.deviceName = ""; + this.attributesPollPeriod = 1000; + this.timeseriesPollPeriod = 1000; + this.attributes = []; + this.timeseries = []; + } + + function Tag(globalPollPeriod) { + this.tag = ""; + this.type = "long"; + this.pollPeriod = globalPollPeriod; + this.functionCode = 3; + this.address = 0; + this.registerCount = 1; + this.bit = 0; + this.byteOrder = "BIG"; + } + + + var template = $templateCache.get(extensionFormModbusTemplate); + element.html(template); + + scope.types = types; + scope.theForm = scope.$parent.theForm; + + + if (!scope.configuration.servers.length) { + scope.configuration.servers.push(new Server()); + } + + scope.addServer = function(serversList) { + serversList.push(new Server()); + scope.theForm.$setDirty(); + }; + + scope.addDevice = function(deviceList) { + deviceList.push(new Device()); + scope.theForm.$setDirty(); + }; + + scope.addNewAttribute = function(device) { + device.attributes.push(new Tag(device.attributesPollPeriod)); + scope.theForm.$setDirty(); + }; + + scope.addNewTimeseries = function(device) { + device.timeseries.push(new Tag(device.timeseriesPollPeriod)); + scope.theForm.$setDirty(); + }; + + scope.removeItem = (item, itemList) => { + var index = itemList.indexOf(item); + if (index > -1) { + itemList.splice(index, 1); + } + scope.theForm.$setDirty(); + }; + + + $compile(element.contents())(scope); + + + scope.collapseValidation = function(index, id) { + var invalidState = angular.element('#'+id+':has(.ng-invalid)'); + if(invalidState.length) { + invalidState.addClass('inner-invalid'); + } + }; + + scope.expandValidation = function (index, id) { + var invalidState = angular.element('#'+id); + invalidState.removeClass('inner-invalid'); + }; + + }; + + return { + restrict: "A", + link: linker, + scope: { + configuration: "=", + isAdd: "=" + } + } +} \ No newline at end of file diff --git a/ui/src/app/extension/extensions-forms/extension-form-modbus.tpl.html b/ui/src/app/extension/extensions-forms/extension-form-modbus.tpl.html new file mode 100644 index 0000000000..122aeaf23e --- /dev/null +++ b/ui/src/app/extension/extensions-forms/extension-form-modbus.tpl.html @@ -0,0 +1,818 @@ + + + + + extension.configuration + + + + + + + + {{ 'extension.modbus-server' | translate }} + + + +
+ extension.modbus-add-server-prompt +
+ +
+
    +
  1. + + + + {{ 'action.remove' | translate }} + + + + + + +
    + + + + + + +
    +
    extension.field-required
    +
    +
    + +
    + +
    + + + +
    +
    extension.field-required
    +
    +
    + + + + +
    +
    extension.field-required
    +
    extension.port-range
    +
    extension.port-range
    +
    +
    + + + + +
    +
    extension.field-required
    +
    +
    +
    + +
    + + + +
    +
    extension.field-required
    +
    +
    + + + + +
    +
    extension.field-required
    +
    extension.port-range
    +
    extension.port-range
    +
    +
    + + + + +
    +
    extension.field-required
    +
    +
    +
    + +
    + +
    + + + +
    +
    extension.field-required
    +
    +
    + + + + +
    +
    extension.field-required
    +
    +
    +
    + +
    + + + + + +
    +
    extension.field-required
    +
    +
    + + + + + + {{parityValue}} + + +
    +
    extension.field-required
    +
    +
    + +
    + +
    + + + +
    +
    extension.field-required
    +
    +
    + + + + +
    +
    extension.field-required
    +
    extension.modbus-databits-range
    +
    extension.modbus-databits-range
    +
    +
    + + + + +
    +
    extension.field-required
    +
    extension.modbus-stopbits-range
    +
    extension.modbus-stopbits-range
    +
    +
    +
    +
    + + + + + {{ 'extension.mapping' | translate }} + + +
    +
      +
    1. + + + + {{ 'action.remove' | translate }} + + + + + +
      + + + +
      +
      extension.field-required
      +
      +
      + + + + + +
      +
      extension.field-required
      +
      extension.modbus-unit-id-range
      +
      extension.modbus-unit-id-range
      +
      +
      +
      + +
      + + + + +
      +
      extension.field-required
      +
      extension.modbus-poll-period-range
      +
      +
      + + + + + +
      +
      extension.field-required
      +
      extension.modbus-poll-period-range
      +
      +
      + +
      + + + + + + {{ 'extension.attributes' | translate }} + + +
      +
        +
      1. + + + + {{ 'action.remove' | translate }} + + + + + +
        + + + +
        +
        extension.field-required
        +
        +
        + + + + + + {{attrTypeValue | translate}} + + +
        +
        extension.field-required
        +
        +
        + + + + + +
        +
        extension.modbus-poll-period-range
        +
        +
        +
        + +
        + + + + + {{functionName}} + + +
        +
        extension.field-required
        +
        +
        + + + + + +
        +
        extension.field-required
        +
        extension.modbus-register-address-range
        +
        extension.modbus-register-address-range
        +
        +
        + +
        + +
        + + + + +
        +
        extension.modbus-register-count-range
        +
        +
        + + + + + +
        +
        extension.field-required
        +
        extension.modbus-register-bit-index-range
        +
        extension.modbus-register-bit-index-range
        +
        +
        +
        + +
        + + + +
        +
        extension.field-required
        +
        +
        + +
        + + +
        +
        +
      2. +
      +
      +
      + + add + extension.add-attribute + +
      +
      +
      +
      + + + + + {{ 'extension.timeseries' | translate }} + + +
      +
        +
      1. + + + + {{ 'action.remove' | translate }} + + + + + +
        + + + +
        +
        extension.field-required
        +
        +
        + + + + + + {{attrTypeValue | translate}} + + +
        +
        extension.field-required
        +
        +
        + + + + + +
        +
        extension.modbus-poll-period-range
        +
        +
        +
        + +
        + + + + + {{functionName}} + + +
        +
        extension.field-required
        +
        +
        + + + + + +
        +
        extension.field-required
        +
        extension.modbus-register-address-range
        +
        extension.modbus-register-address-range
        +
        +
        +
        + +
        + + + + +
        +
        extension.modbus-register-count-range
        +
        +
        + + + + + +
        +
        extension.field-required
        +
        extension.modbus-register-bit-index-range
        +
        extension.modbus-register-bit-index-range
        +
        +
        +
        + +
        + + + +
        +
        extension.field-required
        +
        +
        + +
        +
        +
        +
      2. +
      +
      +
      + + add + extension.add-timeseries + +
      +
      +
      +
      + + +
      +
      +
    2. +
    +
    +
    + + add + extension.add-device + +
    +
    +
    +
    + +
    +
    +
  2. +
+ +
+ + add + extension.modbus-add-server + +
+ +
+
+
+
+ +
+
\ No newline at end of file diff --git a/ui/src/app/extension/index.js b/ui/src/app/extension/index.js index f04880cb97..8e293482f4 100644 --- a/ui/src/app/extension/index.js +++ b/ui/src/app/extension/index.js @@ -17,6 +17,8 @@ import ExtensionTableDirective from './extension-table.directive'; import ExtensionFormHttpDirective from './extensions-forms/extension-form-http.directive'; import ExtensionFormMqttDirective from './extensions-forms/extension-form-mqtt.directive' import ExtensionFormOpcDirective from './extensions-forms/extension-form-opc.directive'; +import ExtensionFormModbusDirective from './extensions-forms/extension-form-modbus.directive'; + import {ParseToNull} from './extension-dialog.controller'; export default angular.module('thingsboard.extension', []) @@ -24,5 +26,6 @@ export default angular.module('thingsboard.extension', []) .directive('tbExtensionFormHttp', ExtensionFormHttpDirective) .directive('tbExtensionFormMqtt', ExtensionFormMqttDirective) .directive('tbExtensionFormOpc', ExtensionFormOpcDirective) + .directive('tbExtensionFormModbus', ExtensionFormModbusDirective) .directive('parseToNull', ParseToNull) .name; \ No newline at end of file diff --git a/ui/src/app/locale/locale.constant.js b/ui/src/app/locale/locale.constant.js index 252884dfc7..0f0a1dfd3a 100644 --- a/ui/src/app/locale/locale.constant.js +++ b/ui/src/app/locale/locale.constant.js @@ -866,8 +866,10 @@ export default angular.module('thingsboard.locale', []) "response-timeout": "Response timeout in milliseconds", "topic-expression": "Topic expression", "client-scope": "Client scope", + "add-device": "Add device", "opc-server": "Servers", "opc-add-server": "Add server", + "opc-add-server-prompt": "Please add server", "opc-application-name": "Application name", "opc-application-uri": "Application uri", "opc-scan-period-in-seconds": "Scan period in seconds", @@ -882,6 +884,34 @@ export default angular.module('thingsboard.locale', []) "opc-keystore-key-password":"Key password", "opc-device-node-pattern":"Device node pattern", "opc-device-name-pattern":"Device name pattern", + "modbus-server": "Servers/slaves", + "modbus-add-server": "Add server/slave", + "modbus-add-server-prompt": "Please add server/slave", + "modbus-transport": "Transport", + "modbus-port-name": "Serial port name", + "modbus-encoding": "Encoding", + "modbus-parity": "Parity", + "modbus-baudrate": "Baud rate", + "modbus-databits": "Data bits", + "modbus-stopbits": "Stop bits", + "modbus-databits-range": "Data bits should be in a range from 7 to 8.", + "modbus-stopbits-range": "Stop bits should be in a range from 1 to 2.", + "modbus-unit-id": "Unit ID", + "modbus-unit-id-range": "Unit ID should be in a range from 1 to 247.", + "modbus-device-name":"Device name", + "modbus-poll-period": "Poll period (ms)", + "modbus-attributes-poll-period": "Attributes poll period (ms)", + "modbus-timeseries-poll-period": "Timeseries poll period (ms)", + "modbus-poll-period-range": "Poll period should be positive value.", + "modbus-tag": "Tag", + "modbus-function": "Function", + "modbus-register-address": "Register address", + "modbus-register-address-range": "Register address should be in a range from 0 to 65535.", + "modbus-register-bit-index": "Bit index", + "modbus-register-bit-index-range": "Bit index should be in a range from 0 to 15.", + "modbus-register-count": "Register count", + "modbus-register-count-range": "Register count should be a positive value.", + "modbus-byte-order": "Byte order", "sync": { "status": "Status", From d375f90a00968661bd253d064384e962de088988 Mon Sep 17 00:00:00 2001 From: DK Date: Sun, 22 Apr 2018 20:02:19 +0500 Subject: [PATCH 3/8] Fixed serialization of Modbus transport configuration. Removed code duplicates. --- .../extension-form-modbus.directive.js | 9 ++++ .../extension-form-modbus.tpl.html | 48 +------------------ 2 files changed, 11 insertions(+), 46 deletions(-) diff --git a/ui/src/app/extension/extensions-forms/extension-form-modbus.directive.js b/ui/src/app/extension/extensions-forms/extension-form-modbus.directive.js index aec5625eb7..2dfc961d02 100644 --- a/ui/src/app/extension/extensions-forms/extension-form-modbus.directive.js +++ b/ui/src/app/extension/extensions-forms/extension-form-modbus.directive.js @@ -102,7 +102,16 @@ export default function ExtensionFormModbusDirective($compile, $templateCache, $ scope.theForm.$setDirty(); }; + scope.onTransportChanged = function(server) { + var type = server.transport.type; + server.transport = {}; + server.transport.type = type; + server.transport.timeout = 3000; + + scope.theForm.$setDirty(); + }; + $compile(element.contents())(scope); diff --git a/ui/src/app/extension/extensions-forms/extension-form-modbus.tpl.html b/ui/src/app/extension/extensions-forms/extension-form-modbus.tpl.html index 122aeaf23e..989d3f07db 100644 --- a/ui/src/app/extension/extensions-forms/extension-form-modbus.tpl.html +++ b/ui/src/app/extension/extensions-forms/extension-form-modbus.tpl.html @@ -58,6 +58,7 @@ - -
- - - -
-
extension.field-required
-
-
- - - - -
-
extension.field-required
-
extension.port-range
-
extension.port-range
-
-
- - - - -
-
extension.field-required
-
-
-
-
+
From fa03f651b3c2b539122b4a6b99d5360b8b7e7fbf Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Wed, 25 Apr 2018 17:21:23 +0300 Subject: [PATCH 4/8] Added redis k8s --- docker/k8s/redis.yaml | 93 +++++++++++++++++++++++++++++++++++++++++++ docker/k8s/tb.yaml | 12 ++++++ 2 files changed, 105 insertions(+) create mode 100644 docker/k8s/redis.yaml diff --git a/docker/k8s/redis.yaml b/docker/k8s/redis.yaml new file mode 100644 index 0000000000..3af810e1e3 --- /dev/null +++ b/docker/k8s/redis.yaml @@ -0,0 +1,93 @@ +# +# Copyright © 2016-2018 The Thingsboard Authors +# +# 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. +# + +--- +apiVersion: v1 +kind: Service +metadata: + labels: + name: redis-service + name: redis-service +spec: + ports: + - name: redis-service + protocol: TCP + port: 6379 + targetPort: 6379 + selector: + app: redis +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: redis-conf +data: + redis.conf: | + appendonly yes + protected-mode no + bind 0.0.0.0 + port 6379 + dir /var/lib/redis +--- +apiVersion: apps/v1beta1 +kind: StatefulSet +metadata: + name: redis +spec: + serviceName: redis-service + replicas: 1 + template: + metadata: + labels: + app: redis + spec: + terminationGracePeriodSeconds: 10 + containers: + - name: redis + image: redis:4.0.9 + command: + - redis-server + args: + - /etc/redis/redis.conf + resources: + requests: + cpu: 100m + memory: 100Mi + ports: + - containerPort: 6379 + name: redis + volumeMounts: + - name: redis-data + mountPath: /var/lib/redis + - name: redis-conf + mountPath: /etc/redis + volumes: + - name: redis-conf + configMap: + name: redis-conf + items: + - key: redis.conf + path: redis.conf + volumeClaimTemplates: + - metadata: + name: redis-data + annotations: + volume.beta.kubernetes.io/storage-class: fast + spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 1Gi \ No newline at end of file diff --git a/docker/k8s/tb.yaml b/docker/k8s/tb.yaml index 74b6702d3d..1d94cb11ac 100644 --- a/docker/k8s/tb.yaml +++ b/docker/k8s/tb.yaml @@ -54,6 +54,8 @@ data: cassandra.host: "cassandra-headless" cassandra.port: "9042" database.type: "cassandra" + cache.type: "redis" + redis.host: "redis-service" --- apiVersion: apps/v1beta1 kind: StatefulSet @@ -127,6 +129,16 @@ spec: valueFrom: fieldRef: fieldPath: status.podIP + - name: CACHE_TYPE + valueFrom: + configMapKeyRef: + name: tb-config + key: cache.type + - name: REDIS_HOST + valueFrom: + configMapKeyRef: + name: tb-config + key: redis.host command: - sh - -c From 06f79f1fc06c50c158e4c3eb69699a90ab4b6d60 Mon Sep 17 00:00:00 2001 From: Sergey Tarnavskiy Date: Fri, 4 May 2018 13:29:04 +0300 Subject: [PATCH 5/8] solved issue with tick-decimals option --- ui/src/app/widget/lib/flot-widget.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/src/app/widget/lib/flot-widget.js b/ui/src/app/widget/lib/flot-widget.js index 282fd4f79b..4d5f65e8a7 100644 --- a/ui/src/app/widget/lib/flot-widget.js +++ b/ui/src/app/widget/lib/flot-widget.js @@ -252,7 +252,7 @@ export default class TbFlot { if (this.tickUnits) { formatted += ' ' + this.tickUnits; } - + return formatted; }; @@ -1098,7 +1098,7 @@ export default class TbFlot { "axisTickDecimals": { "title": "Axis tick number of digits after floating point", "type": "number", - "default": 0 + "default": null }, "axisTickSize": { "title": "Axis step size between ticks", From eba98b80e65fd734cc29b5333af431bd56d350d6 Mon Sep 17 00:00:00 2001 From: Dima Landiak Date: Mon, 7 May 2018 18:40:49 +0300 Subject: [PATCH 6/8] relation cache fixes --- .../dao/relation/BaseRelationService.java | 94 ++++++++++--------- 1 file changed, 51 insertions(+), 43 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java index 370d770188..e9f808aee1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java @@ -170,12 +170,12 @@ public class BaseRelationService implements RelationService { Cache cache = cacheManager.getCache(RELATIONS_CACHE); log.trace("Executing deleteEntityRelations [{}]", entity); validate(entity); - List>> inboundRelationsListTo = new ArrayList<>(); + List>> inboundRelationsList = new ArrayList<>(); for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) { - inboundRelationsListTo.add(relationDao.findAllByTo(entity, typeGroup)); + inboundRelationsList.add(relationDao.findAllByTo(entity, typeGroup)); } - ListenableFuture>> inboundRelationsTo = Futures.allAsList(inboundRelationsListTo); - ListenableFuture> inboundDeletions = Futures.transform(inboundRelationsTo, (List> relations) -> + ListenableFuture>> inboundRelations = Futures.allAsList(inboundRelationsList); + ListenableFuture> inboundDeletions = Futures.transform(inboundRelations, (List> relations) -> getBooleans(relations, cache, true)); ListenableFuture inboundFuture = Futures.transform(inboundDeletions, getListToBooleanFunction()); @@ -186,12 +186,12 @@ public class BaseRelationService implements RelationService { log.error("Error deleting entity inbound relations", e); } - List>> inboundRelationsListFrom = new ArrayList<>(); + List>> outboundRelationsList = new ArrayList<>(); for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) { - inboundRelationsListFrom.add(relationDao.findAllByFrom(entity, typeGroup)); + outboundRelationsList.add(relationDao.findAllByFrom(entity, typeGroup)); } - ListenableFuture>> inboundRelationsFrom = Futures.allAsList(inboundRelationsListFrom); - Futures.transform(inboundRelationsFrom, (Function>, List>) relations -> + ListenableFuture>> outboundRelations = Futures.allAsList(outboundRelationsList); + Futures.transform(outboundRelations, (Function>, List>) relations -> getBooleans(relations, cache, false)); boolean outboundDeleteResult = relationDao.deleteOutboundRelations(entity); @@ -201,9 +201,7 @@ public class BaseRelationService implements RelationService { private List getBooleans(List> relations, Cache cache, boolean isRemove) { List results = new ArrayList<>(); for (List relationList : relations) { - relationList.stream().forEach(relation -> { - checkFromDeleteSync(cache, results, relation, isRemove); - }); + relationList.stream().forEach(relation -> checkFromDeleteSync(cache, results, relation, isRemove)); } return results; } @@ -211,10 +209,8 @@ public class BaseRelationService implements RelationService { private void checkFromDeleteSync(Cache cache, List results, EntityRelation relation, boolean isRemove) { if (isRemove) { results.add(relationDao.deleteRelation(relation)); - cacheEviction(relation, relation.getTo(), cache); - } else { - cacheEviction(relation, relation.getFrom(), cache); } + cacheEviction(relation, cache); } @Override @@ -222,12 +218,12 @@ public class BaseRelationService implements RelationService { Cache cache = cacheManager.getCache(RELATIONS_CACHE); log.trace("Executing deleteEntityRelationsAsync [{}]", entity); validate(entity); - List>> inboundRelationsListTo = new ArrayList<>(); + List>> inboundRelationsList = new ArrayList<>(); for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) { - inboundRelationsListTo.add(relationDao.findAllByTo(entity, typeGroup)); + inboundRelationsList.add(relationDao.findAllByTo(entity, typeGroup)); } - ListenableFuture>> inboundRelationsTo = Futures.allAsList(inboundRelationsListTo); - ListenableFuture> inboundDeletions = Futures.transform(inboundRelationsTo, + ListenableFuture>> inboundRelations = Futures.allAsList(inboundRelationsList); + ListenableFuture> inboundDeletions = Futures.transform(inboundRelations, (AsyncFunction>, List>) relations -> { List> results = getListenableFutures(relations, cache, true); return Futures.allAsList(results); @@ -235,12 +231,12 @@ public class BaseRelationService implements RelationService { ListenableFuture inboundFuture = Futures.transform(inboundDeletions, getListToBooleanFunction()); - List>> inboundRelationsListFrom = new ArrayList<>(); + List>> outboundRelationsList = new ArrayList<>(); for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) { - inboundRelationsListFrom.add(relationDao.findAllByTo(entity, typeGroup)); + outboundRelationsList.add(relationDao.findAllByFrom(entity, typeGroup)); } - ListenableFuture>> inboundRelationsFrom = Futures.allAsList(inboundRelationsListFrom); - Futures.transform(inboundRelationsFrom, (AsyncFunction>, List>) relations -> { + ListenableFuture>> outboundRelations = Futures.allAsList(outboundRelationsList); + Futures.transform(outboundRelations, (AsyncFunction>, List>) relations -> { List> results = getListenableFutures(relations, cache, false); return Futures.allAsList(results); }); @@ -252,9 +248,7 @@ public class BaseRelationService implements RelationService { private List> getListenableFutures(List> relations, Cache cache, boolean isRemove) { List> results = new ArrayList<>(); for (List relationList : relations) { - relationList.stream().forEach(relation -> { - checkFromDeleteAsync(cache, results, relation, isRemove); - }); + relationList.stream().forEach(relation -> checkFromDeleteAsync(cache, results, relation, isRemove)); } return results; } @@ -262,25 +256,39 @@ public class BaseRelationService implements RelationService { private void checkFromDeleteAsync(Cache cache, List> results, EntityRelation relation, boolean isRemove) { if (isRemove) { results.add(relationDao.deleteRelationAsync(relation)); - cacheEviction(relation, relation.getTo(), cache); - } else { - cacheEviction(relation, relation.getFrom(), cache); } - } - - private void cacheEviction(EntityRelation relation, EntityId entityId, Cache cache) { - cache.evict(entityId); - - List toAndType = new ArrayList<>(); - toAndType.add(entityId); - toAndType.add(relation.getType()); - cache.evict(toAndType); - - List fromToAndType = new ArrayList<>(); - fromToAndType.add(relation.getFrom()); - fromToAndType.add(relation.getTo()); - fromToAndType.add(relation.getType()); - cache.evict(fromToAndType); + cacheEviction(relation, cache); + } + + private void cacheEviction(EntityRelation relation, Cache cache) { + List toAndGroup = new ArrayList<>(); + toAndGroup.add(relation.getTo()); + toAndGroup.add(relation.getTypeGroup()); + cache.evict(toAndGroup); + + List toTypeAndGroup = new ArrayList<>(); + toTypeAndGroup.add(relation.getTo()); + toTypeAndGroup.add(relation.getType()); + toTypeAndGroup.add(relation.getTypeGroup()); + cache.evict(toTypeAndGroup); + + List fromAndGroup = new ArrayList<>(); + fromAndGroup.add(relation.getFrom()); + fromAndGroup.add(relation.getTypeGroup()); + cache.evict(fromAndGroup); + + List fromTypeAndGroup = new ArrayList<>(); + fromTypeAndGroup.add(relation.getFrom()); + fromTypeAndGroup.add(relation.getType()); + fromTypeAndGroup.add(relation.getTypeGroup()); + cache.evict(fromTypeAndGroup); + + List fromToTypeAndGroup = new ArrayList<>(); + fromToTypeAndGroup.add(relation.getFrom()); + fromToTypeAndGroup.add(relation.getTo()); + fromToTypeAndGroup.add(relation.getType()); + fromToTypeAndGroup.add(relation.getTypeGroup()); + cache.evict(fromToTypeAndGroup); } @Cacheable(cacheNames = RELATIONS_CACHE, key = "{#from, #typeGroup}") From b835d665c3b14a95c66b3fd350a7aea4f3befc6a Mon Sep 17 00:00:00 2001 From: Andrew Shvayka Date: Fri, 11 May 2018 19:43:14 +0300 Subject: [PATCH 7/8] Few performance tuning parameters --- application/src/main/resources/thingsboard.yml | 1 + .../server/dao/cassandra/AbstractCassandraCluster.java | 8 ++++++-- .../transport/mqtt/MqttTransportServerInitializer.java | 8 ++++---- .../server/transport/mqtt/MqttTransportService.java | 5 +++-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index c47fc28fbd..6a45f42808 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -87,6 +87,7 @@ mqtt: leak_detector_level: "${NETTY_LEASK_DETECTOR_LVL:DISABLED}" boss_group_thread_count: "${NETTY_BOSS_GROUP_THREADS:1}" worker_group_thread_count: "${NETTY_WORKER_GROUP_THREADS:12}" + max_payload_size: "${NETTY_MAX_PAYLOAD_SIZE:65536}" # MQTT SSL configuration ssl: # Enable/disable SSL support diff --git a/dao/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java b/dao/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java index 2e56416351..ca94822301 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java +++ b/dao/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java @@ -60,6 +60,10 @@ public abstract class AbstractCassandraCluster { private long initTimeout; @Value("${cassandra.init_retry_interval_ms}") private long initRetryInterval; + @Value("${cassandra.max_requests_per_connection_local:128}") + private int max_requests_local; + @Value("${cassandra.max_requests_per_connection_remote:128}") + private int max_requests_remote; @Autowired private CassandraSocketOptions socketOpts; @@ -90,8 +94,8 @@ public abstract class AbstractCassandraCluster { .withClusterName(clusterName) .withSocketOptions(socketOpts.getOpts()) .withPoolingOptions(new PoolingOptions() - .setMaxRequestsPerConnection(HostDistance.LOCAL, 32768) - .setMaxRequestsPerConnection(HostDistance.REMOTE, 32768)); + .setMaxRequestsPerConnection(HostDistance.LOCAL, max_requests_local) + .setMaxRequestsPerConnection(HostDistance.REMOTE, max_requests_remote)); this.clusterBuilder.withQueryOptions(queryOpts.getOpts()); this.clusterBuilder.withCompression(StringUtils.isEmpty(compression) ? Compression.NONE : Compression.valueOf(compression.toUpperCase())); if (ssl) { diff --git a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportServerInitializer.java b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportServerInitializer.java index 976d8bacad..432966eeff 100644 --- a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportServerInitializer.java +++ b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportServerInitializer.java @@ -33,8 +33,6 @@ import org.thingsboard.server.transport.mqtt.adaptors.MqttTransportAdaptor; */ public class MqttTransportServerInitializer extends ChannelInitializer { - private static final int MAX_PAYLOAD_SIZE = 64 * 1024 * 1024; - private final SessionMsgProcessor processor; private final DeviceService deviceService; private final DeviceAuthService authService; @@ -42,10 +40,11 @@ public class MqttTransportServerInitializer extends ChannelInitializer Date: Tue, 15 May 2018 22:26:51 +0800 Subject: [PATCH 8/8] fixed missed semicolon! --- ui/src/app/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/app/app.js b/ui/src/app/app.js index 0b6a141ba3..c328a5a496 100644 --- a/ui/src/app/app.js +++ b/ui/src/app/app.js @@ -79,7 +79,7 @@ import 'font-awesome/css/font-awesome.min.css'; import 'angular-material/angular-material.min.css'; import 'angular-material-icons/angular-material-icons.css'; import 'angular-gridster/dist/angular-gridster.min.css'; -import 'v-accordion/dist/v-accordion.min.css' +import 'v-accordion/dist/v-accordion.min.css'; import 'md-color-picker/dist/mdColorPicker.min.css'; import 'mdPickers/dist/mdPickers.min.css'; import 'angular-hotkeys/build/hotkeys.min.css';