Commit 692f575661dc6d8a1b31fdfd891c7370bf56e02e

Authored by Igor Kulikov
2 parents 70ca190f 2897ea44

Merge with master

... ... @@ -56,7 +56,9 @@ public class TbRuleEngineProcessingStrategyFactory {
56 56 private final boolean retryTimeout;
57 57 private final int maxRetries;
58 58 private final double maxAllowedFailurePercentage;
59   - private final long pauseBetweenRetries;
  59 + private final long maxPauseBetweenRetries;
  60 +
  61 + private long pauseBetweenRetries;
60 62
61 63 private int initialTotalCount;
62 64 private int retryCount;
... ... @@ -69,6 +71,7 @@ public class TbRuleEngineProcessingStrategyFactory {
69 71 this.maxRetries = configuration.getRetries();
70 72 this.maxAllowedFailurePercentage = configuration.getFailurePercentage();
71 73 this.pauseBetweenRetries = configuration.getPauseBetweenRetries();
  74 + this.maxPauseBetweenRetries = configuration.getMaxPauseBetweenRetries();
72 75 }
73 76
74 77 @Override
... ... @@ -108,6 +111,9 @@ public class TbRuleEngineProcessingStrategyFactory {
108 111 } catch (InterruptedException e) {
109 112 throw new RuntimeException(e);
110 113 }
  114 + if (maxPauseBetweenRetries > pauseBetweenRetries) {
  115 + pauseBetweenRetries = Math.min(maxPauseBetweenRetries, pauseBetweenRetries * 2);
  116 + }
111 117 }
112 118 return new TbRuleEngineProcessingDecision(false, toReprocess);
113 119 }
... ...
... ... @@ -765,6 +765,7 @@ queue:
765 765 retries: "${TB_QUEUE_RE_MAIN_PROCESSING_STRATEGY_RETRIES:3}" # Number of retries, 0 is unlimited
766 766 failure-percentage: "${TB_QUEUE_RE_MAIN_PROCESSING_STRATEGY_FAILURE_PERCENTAGE:0}" # Skip retry if failures or timeouts are less then X percentage of messages;
767 767 pause-between-retries: "${TB_QUEUE_RE_MAIN_PROCESSING_STRATEGY_RETRY_PAUSE:3}"# Time in seconds to wait in consumer thread before retries;
  768 + max-pause-between-retries: "${TB_QUEUE_RE_MAIN_PROCESSING_STRATEGY_MAX_RETRY_PAUSE:3}"# Max allowed time in seconds for pause between retries.
768 769 - name: "${TB_QUEUE_RE_HP_QUEUE_NAME:HighPriority}"
769 770 topic: "${TB_QUEUE_RE_HP_TOPIC:tb_rule_engine.hp}"
770 771 poll-interval: "${TB_QUEUE_RE_HP_POLL_INTERVAL_MS:25}"
... ... @@ -780,6 +781,7 @@ queue:
780 781 retries: "${TB_QUEUE_RE_HP_PROCESSING_STRATEGY_RETRIES:0}" # Number of retries, 0 is unlimited
781 782 failure-percentage: "${TB_QUEUE_RE_HP_PROCESSING_STRATEGY_FAILURE_PERCENTAGE:0}" # Skip retry if failures or timeouts are less then X percentage of messages;
782 783 pause-between-retries: "${TB_QUEUE_RE_HP_PROCESSING_STRATEGY_RETRY_PAUSE:5}"# Time in seconds to wait in consumer thread before retries;
  784 + max-pause-between-retries: "${TB_QUEUE_RE_HP_PROCESSING_STRATEGY_MAX_RETRY_PAUSE:5}"# Max allowed time in seconds for pause between retries.
783 785 - name: "${TB_QUEUE_RE_SQ_QUEUE_NAME:SequentialByOriginator}"
784 786 topic: "${TB_QUEUE_RE_SQ_TOPIC:tb_rule_engine.sq}"
785 787 poll-interval: "${TB_QUEUE_RE_SQ_POLL_INTERVAL_MS:25}"
... ... @@ -795,6 +797,7 @@ queue:
795 797 retries: "${TB_QUEUE_RE_SQ_PROCESSING_STRATEGY_RETRIES:3}" # Number of retries, 0 is unlimited
796 798 failure-percentage: "${TB_QUEUE_RE_SQ_PROCESSING_STRATEGY_FAILURE_PERCENTAGE:0}" # Skip retry if failures or timeouts are less then X percentage of messages;
797 799 pause-between-retries: "${TB_QUEUE_RE_SQ_PROCESSING_STRATEGY_RETRY_PAUSE:5}"# Time in seconds to wait in consumer thread before retries;
  800 + max-pause-between-retries: "${TB_QUEUE_RE_SQ_PROCESSING_STRATEGY_MAX_RETRY_PAUSE:5}"# Max allowed time in seconds for pause between retries.
798 801 transport:
799 802 # For high priority notifications that require minimum latency and processing time
800 803 notifications_topic: "${TB_QUEUE_TRANSPORT_NOTIFICATIONS_TOPIC:tb_transport.notifications}"
... ...
... ... @@ -24,5 +24,6 @@ public class TbRuleEngineQueueAckStrategyConfiguration {
24 24 private int retries;
25 25 private double failurePercentage;
26 26 private long pauseBetweenRetries;
  27 + private long maxPauseBetweenRetries;
27 28
28 29 }
... ...
... ... @@ -54,7 +54,7 @@
54 54 "jstree": "^3.3.10",
55 55 "jstree-bootstrap-theme": "^1.0.1",
56 56 "jszip": "^3.5.0",
57   - "leaflet": "^1.6.0",
  57 + "leaflet": "^1.7.1",
58 58 "leaflet-editable": "^1.2.0",
59 59 "leaflet-polylinedecorator": "^1.6.0",
60 60 "leaflet-providers": "^1.10.2",
... ...
... ... @@ -1277,7 +1277,7 @@ export class WidgetSubscription implements IWidgetSubscription {
1277 1277 const index = startIndex + dataIndex * dataKeysCount + dataKeyIndex;
1278 1278 let update = true;
1279 1279 let currentData: DataSetHolder;
1280   - if (this.displayLegend && this.legendData.keys[index].dataKey.hidden) {
  1280 + if (this.displayLegend && this.legendData.keys.find(key => key.dataIndex === index).dataKey.hidden) {
1281 1281 currentData = this.hiddenData[index];
1282 1282 } else {
1283 1283 currentData = this.data[index];
... ...
... ... @@ -14,9 +14,11 @@
14 14 /// limitations under the License.
15 15 ///
16 16
  17 +import { HasUUID } from '@shared/models/id/has-uuid';
  18 +
17 19 export declare type MenuSectionType = 'link' | 'toggle';
18 20
19   -export class MenuSection {
  21 +export interface MenuSection extends HasUUID{
20 22 name: string;
21 23 type: MenuSectionType;
22 24 path: string;
... ... @@ -26,12 +28,12 @@ export class MenuSection {
26 28 pages?: Array<MenuSection>;
27 29 }
28 30
29   -export class HomeSection {
  31 +export interface HomeSection {
30 32 name: string;
31 33 places: Array<HomeSectionPlace>;
32 34 }
33 35
34   -export class HomeSectionPlace {
  36 +export interface HomeSectionPlace {
35 37 name: string;
36 38 icon: string;
37 39 isMdiIcon?: boolean;
... ...
... ... @@ -24,6 +24,7 @@ import { HomeSection, MenuSection } from '@core/services/menu.models';
24 24 import { BehaviorSubject, Observable, Subject } from 'rxjs';
25 25 import { Authority } from '@shared/models/authority.enum';
26 26 import { AuthUser } from '@shared/models/user.model';
  27 +import { guid } from '@core/utils';
27 28
28 29 @Injectable({
29 30 providedIn: 'root'
... ... @@ -74,18 +75,21 @@ export class MenuService {
74 75 const sections: Array<MenuSection> = [];
75 76 sections.push(
76 77 {
  78 + id: guid(),
77 79 name: 'home.home',
78 80 type: 'link',
79 81 path: '/home',
80 82 icon: 'home'
81 83 },
82 84 {
  85 + id: guid(),
83 86 name: 'tenant.tenants',
84 87 type: 'link',
85 88 path: '/tenants',
86 89 icon: 'supervisor_account'
87 90 },
88 91 {
  92 + id: guid(),
89 93 name: 'tenant-profile.tenant-profiles',
90 94 type: 'link',
91 95 path: '/tenantProfiles',
... ... @@ -93,12 +97,14 @@ export class MenuService {
93 97 isMdiIcon: true
94 98 },
95 99 {
  100 + id: guid(),
96 101 name: 'widget.widget-library',
97 102 type: 'link',
98 103 path: '/widgets-bundles',
99 104 icon: 'now_widgets'
100 105 },
101 106 {
  107 + id: guid(),
102 108 name: 'admin.system-settings',
103 109 type: 'toggle',
104 110 path: '/settings',
... ... @@ -106,18 +112,21 @@ export class MenuService {
106 112 icon: 'settings',
107 113 pages: [
108 114 {
  115 + id: guid(),
109 116 name: 'admin.general',
110 117 type: 'link',
111 118 path: '/settings/general',
112 119 icon: 'settings_applications'
113 120 },
114 121 {
  122 + id: guid(),
115 123 name: 'admin.outgoing-mail',
116 124 type: 'link',
117 125 path: '/settings/outgoing-mail',
118 126 icon: 'mail'
119 127 },
120 128 {
  129 + id: guid(),
121 130 name: 'admin.security-settings',
122 131 type: 'link',
123 132 path: '/settings/security-settings',
... ... @@ -186,36 +195,42 @@ export class MenuService {
186 195 const sections: Array<MenuSection> = [];
187 196 sections.push(
188 197 {
  198 + id: guid(),
189 199 name: 'home.home',
190 200 type: 'link',
191 201 path: '/home',
192 202 icon: 'home'
193 203 },
194 204 {
  205 + id: guid(),
195 206 name: 'rulechain.rulechains',
196 207 type: 'link',
197 208 path: '/ruleChains',
198 209 icon: 'settings_ethernet'
199 210 },
200 211 {
  212 + id: guid(),
201 213 name: 'customer.customers',
202 214 type: 'link',
203 215 path: '/customers',
204 216 icon: 'supervisor_account'
205 217 },
206 218 {
  219 + id: guid(),
207 220 name: 'asset.assets',
208 221 type: 'link',
209 222 path: '/assets',
210 223 icon: 'domain'
211 224 },
212 225 {
  226 + id: guid(),
213 227 name: 'device.devices',
214 228 type: 'link',
215 229 path: '/devices',
216 230 icon: 'devices_other'
217 231 },
218 232 {
  233 + id: guid(),
219 234 name: 'device-profile.device-profiles',
220 235 type: 'link',
221 236 path: '/deviceProfiles',
... ... @@ -223,24 +238,28 @@ export class MenuService {
223 238 isMdiIcon: true
224 239 },
225 240 {
  241 + id: guid(),
226 242 name: 'entity-view.entity-views',
227 243 type: 'link',
228 244 path: '/entityViews',
229 245 icon: 'view_quilt'
230 246 },
231 247 {
  248 + id: guid(),
232 249 name: 'widget.widget-library',
233 250 type: 'link',
234 251 path: '/widgets-bundles',
235 252 icon: 'now_widgets'
236 253 },
237 254 {
  255 + id: guid(),
238 256 name: 'dashboard.dashboards',
239 257 type: 'link',
240 258 path: '/dashboards',
241 259 icon: 'dashboards'
242 260 },
243 261 {
  262 + id: guid(),
244 263 name: 'audit-log.audit-logs',
245 264 type: 'link',
246 265 path: '/auditLogs',
... ... @@ -342,30 +361,35 @@ export class MenuService {
342 361 const sections: Array<MenuSection> = [];
343 362 sections.push(
344 363 {
  364 + id: guid(),
345 365 name: 'home.home',
346 366 type: 'link',
347 367 path: '/home',
348 368 icon: 'home'
349 369 },
350 370 {
  371 + id: guid(),
351 372 name: 'asset.assets',
352 373 type: 'link',
353 374 path: '/assets',
354 375 icon: 'domain'
355 376 },
356 377 {
  378 + id: guid(),
357 379 name: 'device.devices',
358 380 type: 'link',
359 381 path: '/devices',
360 382 icon: 'devices_other'
361 383 },
362 384 {
  385 + id: guid(),
363 386 name: 'entity-view.entity-views',
364 387 type: 'link',
365 388 path: '/entityViews',
366 389 icon: 'view_quilt'
367 390 },
368 391 {
  392 + id: guid(),
369 393 name: 'dashboard.dashboards',
370 394 type: 'link',
371 395 path: '/dashboards',
... ...
... ... @@ -86,8 +86,7 @@ export default abstract class LeafletMap {
86 86
87 87 public initSettings(options: MapSettings) {
88 88 this.options.tinyColor = tinycolor(this.options.color || defaultSettings.color);
89   - const { disableScrollZooming,
90   - useClusterMarkers,
  89 + const { useClusterMarkers,
91 90 zoomOnClick,
92 91 showCoverageOnHover,
93 92 removeOutsideVisibleBounds,
... ... @@ -95,9 +94,6 @@ export default abstract class LeafletMap {
95 94 chunkedLoading,
96 95 maxClusterRadius,
97 96 maxZoom }: MapSettings = options;
98   - if (disableScrollZooming) {
99   - this.map.scrollWheelZoom.disable();
100   - }
101 97 if (useClusterMarkers) {
102 98 const clusteringSettings: MarkerClusterGroupOptions = {
103 99 zoomToBoundsOnClick: zoomOnClick,
... ... @@ -307,8 +303,11 @@ export default abstract class LeafletMap {
307 303 } else {
308 304 this.bounds = new L.LatLngBounds(null, null);
309 305 }
  306 + if (this.options.disableScrollZooming) {
  307 + this.map.scrollWheelZoom.disable();
  308 + }
310 309 if (this.options.draggableMarker) {
311   - this.addMarkerControl();
  310 + this.addMarkerControl();
312 311 }
313 312 if (this.options.editablePolygon) {
314 313 this.addPolygonControl();
... ... @@ -623,10 +622,10 @@ export default abstract class LeafletMap {
623 622
624 623 // Polyline
625 624
626   - updatePolylines(polyData: FormattedData[][], updateBounds = true, data?: FormattedData) {
  625 + updatePolylines(polyData: FormattedData[][], updateBounds = true, activePolyline?: FormattedData) {
627 626 const keys: string[] = [];
628 627 polyData.forEach((dataSource: FormattedData[]) => {
629   - data = data || dataSource[0];
  628 + const data = activePolyline || dataSource[0];
630 629 if (dataSource.length && data.entityName === dataSource[0].entityName) {
631 630 if (this.polylines.get(data.entityName)) {
632 631 this.updatePolyline(data, dataSource, this.options, updateBounds);
... ...
... ... @@ -24,7 +24,7 @@
24 24 [ngClass]="{'tb-toggled' : sectionActive()}"></span>
25 25 </a>
26 26 <ul id="docs-menu-{{section.name | nospace}}" class="tb-menu-toggle-list" [ngStyle]="{height: sectionHeight()}">
27   - <li *ngFor="let page of section.pages">
  27 + <li *ngFor="let page of section.pages; trackBy: trackBySectionPages">
28 28 <tb-menu-link [section]="page"></tb-menu-link>
29 29 </li>
30 30 </ul>
... ...
... ... @@ -44,4 +44,8 @@ export class MenuToggleComponent implements OnInit {
44 44 return '0px';
45 45 }
46 46 }
  47 +
  48 + trackBySectionPages(index: number, section: MenuSection){
  49 + return section.id;
  50 + }
47 51 }
... ...
... ... @@ -16,7 +16,7 @@
16 16
17 17 -->
18 18 <ul fxFlex fxLayout="column" fxLayoutAlign="start stretch" class="tb-side-menu">
19   - <li *ngFor="let section of menuSections$| async" [ngSwitch]="section.type === 'link'">
  19 + <li *ngFor="let section of menuSections$ | async; trackBy: trackByMenuSection" [ngSwitch]="section.type === 'link'">
20 20 <tb-menu-link *ngSwitchCase="true" [section]="section"></tb-menu-link>
21 21 <tb-menu-toggle *ngSwitchCase="false" [section]="section"></tb-menu-toggle>
22 22 </li>
... ...
... ... @@ -16,6 +16,7 @@
16 16
17 17 import { Component, OnInit } from '@angular/core';
18 18 import { MenuService } from '@core/services/menu.service';
  19 +import { MenuSection } from '@core/services/menu.models';
19 20
20 21 @Component({
21 22 selector: 'tb-side-menu',
... ... @@ -29,6 +30,10 @@ export class SideMenuComponent implements OnInit {
29 30 constructor(private menuService: MenuService) {
30 31 }
31 32
  33 + trackByMenuSection(index: number, section: MenuSection){
  34 + return section.id;
  35 + }
  36 +
32 37 ngOnInit() {
33 38 }
34 39
... ...
... ... @@ -19,7 +19,7 @@
19 19 <h1 fxFlex fxHide.gt-sm *ngIf="lastBreadcrumb$ | async; let breadcrumb">
20 20 {{ breadcrumb.ignoreTranslate ? (breadcrumb.labelFunction ? breadcrumb.labelFunction() : breadcrumb.label) : (breadcrumb.label | translate) }}
21 21 </h1>
22   - <span fxHide.lt-md fxLayout="row" *ngFor="let breadcrumb of breadcrumbs$ | async; last as isLast;" [ngSwitch]="isLast">
  22 + <span fxHide.lt-md fxLayout="row" *ngFor="let breadcrumb of breadcrumbs$ | async; trackBy: trackByBreadcrumbs; last as isLast;" [ngSwitch]="isLast">
23 23 <a *ngSwitchCase="false" [routerLink]="breadcrumb.link" [queryParams]="breadcrumb.queryParams">
24 24 <mat-icon *ngIf="breadcrumb.isMdiIcon" [svgIcon]="breadcrumb.icon">
25 25 </mat-icon>
... ...
... ... @@ -20,6 +20,7 @@ import { BreadCrumb, BreadCrumbConfig } from './breadcrumb';
20 20 import { ActivatedRoute, ActivatedRouteSnapshot, NavigationEnd, Router } from '@angular/router';
21 21 import { distinctUntilChanged, filter, map } from 'rxjs/operators';
22 22 import { TranslateService } from '@ngx-translate/core';
  23 +import { guid } from '@core/utils';
23 24
24 25 @Component({
25 26 selector: 'tb-breadcrumb',
... ... @@ -94,6 +95,7 @@ export class BreadcrumbComponent implements OnInit, OnDestroy {
94 95 const isMdiIcon = icon.startsWith('mdi:');
95 96 const link = [ route.pathFromRoot.map(v => v.url.map(segment => segment.toString()).join('/')).join('/') ];
96 97 const breadcrumb = {
  98 + id: guid(),
97 99 label,
98 100 labelFunction,
99 101 ignoreTranslate,
... ... @@ -110,4 +112,8 @@ export class BreadcrumbComponent implements OnInit, OnDestroy {
110 112 }
111 113 return newBreadcrumbs;
112 114 }
  115 +
  116 + trackByBreadcrumbs(index: number, breadcrumb: BreadCrumb){
  117 + return breadcrumb.id;
  118 + }
113 119 }
... ...
... ... @@ -16,8 +16,9 @@
16 16
17 17 import { ActivatedRouteSnapshot, Params } from '@angular/router';
18 18 import { TranslateService } from '@ngx-translate/core';
  19 +import { HasUUID } from '@shared/models/id/has-uuid';
19 20
20   -export interface BreadCrumb {
  21 +export interface BreadCrumb extends HasUUID{
21 22 label: string;
22 23 labelFunction?: () => string;
23 24 ignoreTranslate: boolean;
... ...
... ... @@ -5770,10 +5770,10 @@ leaflet.markercluster@^1.4.1:
5770 5770 resolved "https://registry.yarnpkg.com/leaflet.markercluster/-/leaflet.markercluster-1.4.1.tgz#b53f2c4f2ca7306ddab1dbb6f1861d5e8aa6c5e5"
5771 5771 integrity sha512-ZSEpE/EFApR0bJ1w/dUGwTSUvWlpalKqIzkaYdYB7jaftQA/Y2Jav+eT4CMtEYFj+ZK4mswP13Q2acnPBnhGOw==
5772 5772
5773   -leaflet@^1.6.0:
5774   - version "1.6.0"
5775   - resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.6.0.tgz#aecbb044b949ec29469eeb31c77a88e2f448f308"
5776   - integrity sha512-CPkhyqWUKZKFJ6K8umN5/D2wrJ2+/8UIpXppY7QDnUZW5bZL5+SEI2J7GBpwh4LIupOKqbNSQXgqmrEJopHVNQ==
  5773 +leaflet@^1.7.1:
  5774 + version "1.7.1"
  5775 + resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.7.1.tgz#10d684916edfe1bf41d688a3b97127c0322a2a19"
  5776 + integrity sha512-/xwPEBidtg69Q3HlqPdU3DnrXQOvQU/CCHA1tcDQVzOwm91YMYaILjNp7L4Eaw5Z4sOYdbBz6koWyibppd8Zqw==
5777 5777
5778 5778 less-loader@6.1.0:
5779 5779 version "6.1.0"
... ...