Commit 77ad519a1007f161d79454b49d52f0aad563c3c9

Authored by VoBa
Committed by GitHub
2 parents 005b802c 1ab1a8e0

Merge pull request #67 from deaflynx/develop/3.3-edge

Develop/3.3 edge Fix rule chain type, customerIsPublic for edges. Added EdgeInfo
... ... @@ -50,6 +50,7 @@ import org.thingsboard.server.common.data.asset.Asset;
50 50 import org.thingsboard.server.common.data.asset.AssetInfo;
51 51 import org.thingsboard.server.common.data.audit.ActionType;
52 52 import org.thingsboard.server.common.data.edge.Edge;
  53 +import org.thingsboard.server.common.data.edge.EdgeInfo;
53 54 import org.thingsboard.server.common.data.edge.EdgeEventActionType;
54 55 import org.thingsboard.server.common.data.edge.EdgeEventType;
55 56 import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
... ... @@ -643,6 +644,18 @@ public abstract class BaseController {
643 644 }
644 645 }
645 646
  647 + EdgeInfo checkEdgeInfoId(EdgeId edgeId, Operation operation) throws ThingsboardException {
  648 + try {
  649 + validateId(edgeId, "Incorrect edgeId " + edgeId);
  650 + EdgeInfo edge = edgeService.findEdgeInfoById(getCurrentUser().getTenantId(), edgeId);
  651 + checkNotNull(edge);
  652 + accessControlService.checkPermission(getCurrentUser(), Resource.EDGE, operation, edgeId, edge);
  653 + return edge;
  654 + } catch (Exception e) {
  655 + throw handleException(e, false);
  656 + }
  657 + }
  658 +
646 659 DashboardInfo checkDashboardInfoId(DashboardId dashboardId, Operation operation) throws ThingsboardException {
647 660 try {
648 661 validateId(dashboardId, "Incorrect dashboardId " + dashboardId);
... ...
... ... @@ -84,6 +84,19 @@ public class EdgeController extends BaseController {
84 84 }
85 85 }
86 86
  87 + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
  88 + @RequestMapping(value = "/edge/info/{edgeId}", method = RequestMethod.GET)
  89 + @ResponseBody
  90 + public EdgeInfo getEdgeInfoById(@PathVariable(EDGE_ID) String strEdgeId) throws ThingsboardException {
  91 + checkParameter(EDGE_ID, strEdgeId);
  92 + try {
  93 + EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
  94 + return checkEdgeInfoId(edgeId, Operation.READ);
  95 + } catch (Exception e) {
  96 + throw handleException(e);
  97 + }
  98 + }
  99 +
87 100 @PreAuthorize("hasAuthority('TENANT_ADMIN')")
88 101 @RequestMapping(value = "/edge", method = RequestMethod.POST)
89 102 @ResponseBody
... ...
... ... @@ -36,6 +36,8 @@ public interface EdgeService {
36 36
37 37 Edge findEdgeById(TenantId tenantId, EdgeId edgeId);
38 38
  39 + EdgeInfo findEdgeInfoById(TenantId tenantId, EdgeId edgeId);
  40 +
39 41 ListenableFuture<Edge> findEdgeByIdAsync(TenantId tenantId, EdgeId edgeId);
40 42
41 43 Edge findEdgeByTenantIdAndName(TenantId tenantId, String name);
... ...
... ... @@ -43,6 +43,15 @@ public interface EdgeDao extends Dao<Edge> {
43 43 Edge save(TenantId tenantId, Edge edge);
44 44
45 45 /**
  46 + * Find edge info by id.
  47 + *
  48 + * @param tenantId the tenant id
  49 + * @param edgeId the edge id
  50 + * @return the edge info object
  51 + */
  52 + EdgeInfo findEdgeInfoById(TenantId tenantId, UUID edgeId);
  53 +
  54 + /**
46 55 * Find edges by tenantId and page link.
47 56 *
48 57 * @param tenantId the tenantId
... ...
... ... @@ -144,6 +144,13 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
144 144 }
145 145
146 146 @Override
  147 + public EdgeInfo findEdgeInfoById(TenantId tenantId, EdgeId edgeId) {
  148 + log.trace("Executing findEdgeInfoById [{}]", edgeId);
  149 + validateId(edgeId, INCORRECT_EDGE_ID + edgeId);
  150 + return edgeDao.findEdgeInfoById(tenantId, edgeId.getId());
  151 + }
  152 +
  153 + @Override
147 154 public ListenableFuture<Edge> findEdgeByIdAsync(TenantId tenantId, EdgeId edgeId) {
148 155 log.trace("Executing findEdgeById [{}]", edgeId);
149 156 validateId(edgeId, INCORRECT_EDGE_ID + edgeId);
... ...
... ... @@ -36,6 +36,12 @@ public interface EdgeRepository extends PagingAndSortingRepository<EdgeEntity, U
36 36 @Param("textSearch") String textSearch,
37 37 Pageable pageable);
38 38
  39 + @Query("SELECT new org.thingsboard.server.dao.model.sql.EdgeInfoEntity(d, c.title, c.additionalInfo) " +
  40 + "FROM EdgeEntity d " +
  41 + "LEFT JOIN CustomerEntity c on c.id = d.customerId " +
  42 + "WHERE d.id = :edgeId")
  43 + EdgeInfoEntity findEdgeInfoById(@Param("edgeId") UUID edgeId);
  44 +
39 45 @Query("SELECT d FROM EdgeEntity d WHERE d.tenantId = :tenantId " +
40 46 "AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
41 47 Page<EdgeEntity> findByTenantId(@Param("tenantId") UUID tenantId,
... ...
... ... @@ -68,6 +68,11 @@ public class JpaEdgeDao extends JpaAbstractSearchTextDao<EdgeEntity, Edge> imple
68 68 }
69 69
70 70 @Override
  71 + public EdgeInfo findEdgeInfoById(TenantId tenantId, UUID edgeId) {
  72 + return DaoUtil.getData(edgeRepository.findEdgeInfoById(edgeId));
  73 + }
  74 +
  75 + @Override
71 76 public PageData<Edge> findEdgesByTenantId(UUID tenantId, PageLink pageLink) {
72 77 return DaoUtil.toPageData(
73 78 edgeRepository.findByTenantId(
... ...
... ... @@ -38,8 +38,12 @@ export class EdgeService {
38 38 defaultHttpOptionsFromConfig(config));
39 39 }
40 40
41   - public getEdge(edgeId: string, config?: RequestConfig): Observable<EdgeInfo> {
42   - return this.http.get<EdgeInfo>(`/api/edge/${edgeId}`, defaultHttpOptionsFromConfig(config));
  41 + public getEdge(edgeId: string, config?: RequestConfig): Observable<Edge> {
  42 + return this.http.get<Edge>(`/api/edge/${edgeId}`, defaultHttpOptionsFromConfig(config));
  43 + }
  44 +
  45 + public getEdgeInfo(edgeId: string, config?: RequestConfig): Observable<EdgeInfo> {
  46 + return this.http.get<EdgeInfo>(`/api/edge/info/${edgeId}`, defaultHttpOptionsFromConfig(config));
43 47 }
44 48
45 49 public saveEdge(edge: Edge, config?: RequestConfig): Observable<Edge> {
... ... @@ -72,7 +76,7 @@ export class EdgeService {
72 76 }
73 77
74 78 public makeEdgePublic(edgeId: string, config?: RequestConfig): Observable<Edge> {
75   - return this.http.post<Edge>(`/api/customer/public/edge/${edgeId}`,
  79 + return this.http.post<Edge>(`/api/customer/public/edge/${edgeId}`, null,
76 80 defaultHttpOptionsFromConfig(config));
77 81 }
78 82
... ...
... ... @@ -324,9 +324,8 @@ export class RuleChainService {
324 324 return this.http.get<Array<RuleChain>>(`/api/ruleChain/defaultEdgeRuleChains`, defaultHttpOptionsFromConfig(config));
325 325 }
326 326
327   - public setEdgeRootRuleChain(edgeId: string, ruleChainId: string, config?: RequestConfig): Observable<Edge> { //TODO deaflynx EdgeInfo vs. Edge check usage
328   - return this.http.post<Edge>(`/api/edge/${edgeId}/${ruleChainId}/root`,
329   - defaultHttpOptionsFromConfig(config));
  327 + public setEdgeRootRuleChain(edgeId: string, ruleChainId: string, config?: RequestConfig): Observable<Edge> {
  328 + return this.http.post<Edge>(`/api/edge/${edgeId}/${ruleChainId}/root`, defaultHttpOptionsFromConfig(config));
330 329 }
331 330
332 331 }
... ...
... ... @@ -52,7 +52,13 @@ import { NULL_UUID } from '@shared/models/id/has-uuid';
52 52 import { WidgetsBundle } from '@shared/models/widgets-bundle.model';
53 53 import { ImportEntitiesResultInfo, ImportEntityData } from '@shared/models/entity.models';
54 54 import { RequestConfig } from '@core/http/http-utils';
55   -import { RuleChain, RuleChainImport, RuleChainMetaData } from '@shared/models/rule-chain.models';
  55 +import {
  56 + RuleChain,
  57 + RuleChainImport,
  58 + RuleChainMetaData,
  59 + RuleChainType,
  60 + ruleChainType
  61 +} from '@shared/models/rule-chain.models';
56 62 import { RuleChainService } from '@core/http/rule-chain.service';
57 63 import * as JSZip from 'jszip';
58 64 import { FiltersInfo } from '@shared/models/query/query.models';
... ... @@ -397,7 +403,7 @@ export class ImportExportService {
397 403 );
398 404 }
399 405
400   - public importRuleChain(): Observable<RuleChainImport> {
  406 + public importRuleChain(expectedRuleChainType: RuleChainType): Observable<RuleChainImport> {
401 407 return this.openImportDialog('rulechain.import', 'rulechain.rulechain-file').pipe(
402 408 mergeMap((ruleChainImport: RuleChainImport) => {
403 409 if (!this.validateImportedRuleChain(ruleChainImport)) {
... ... @@ -405,6 +411,11 @@ export class ImportExportService {
405 411 {message: this.translate.instant('rulechain.invalid-rulechain-file-error'),
406 412 type: 'error'}));
407 413 throw new Error('Invalid rule chain file');
  414 + } else if (ruleChainImport.ruleChain.type !== expectedRuleChainType) {
  415 + this.store.dispatch(new ActionNotificationShow(
  416 + {message: this.translate.instant('rulechain.invalid-rulechain-type-error', { expectedRuleChainType: expectedRuleChainType }),
  417 + type: 'error'}));
  418 + throw new Error('Invalid rule chain type');
408 419 } else {
409 420 return this.ruleChainService.resolveRuleChainMetadata(ruleChainImport.metadata).pipe(
410 421 map((resolvedMetadata) => {
... ... @@ -458,6 +469,9 @@ export class ImportExportService {
458 469 || isUndefined(ruleChainImport.ruleChain.name)) {
459 470 return false;
460 471 }
  472 + if (isUndefined(ruleChainImport.ruleChain.type)) {
  473 + ruleChainImport.ruleChain.type = ruleChainType.core;
  474 + }
461 475 return true;
462 476 }
463 477
... ...
... ... @@ -27,9 +27,9 @@ import { RuleChainsTableConfigResolver } from "@home/pages/rulechain/rulechains-
27 27 import { DashboardPageComponent } from "@home/pages/dashboard/dashboard-page.component";
28 28 import { dashboardBreadcumbLabelFunction, DashboardResolver } from "@home/pages/dashboard/dashboard-routing.module";
29 29 import { BreadCrumbConfig } from "@shared/components/breadcrumb";
30   -import {RuleChainPageComponent} from "@home/pages/rulechain/rulechain-page.component";
31   -import {ConfirmOnExitGuard} from "@core/guards/confirm-on-exit.guard";
32   -import {ruleChainType} from "@shared/models/rule-chain.models";
  30 +import { RuleChainPageComponent } from "@home/pages/rulechain/rulechain-page.component";
  31 +import { ConfirmOnExitGuard } from "@core/guards/confirm-on-exit.guard";
  32 +import { ruleChainType } from "@shared/models/rule-chain.models";
33 33 import {
34 34 importRuleChainBreadcumbLabelFunction,
35 35 ResolvedRuleChainMetaDataResolver,
... ...
... ... @@ -86,13 +86,13 @@ export class EdgesTableConfigResolver implements Resolve<EntityTableConfig<EdgeI
86 86 this.config.deleteEntitiesTitle = count => this.translate.instant('edge.delete-edges-title', {count});
87 87 this.config.deleteEntitiesContent = () => this.translate.instant('edge.delete-edges-text');
88 88
89   - this.config.loadEntity = id => this.edgeService.getEdge(id.id);
  89 + this.config.loadEntity = id => this.edgeService.getEdgeInfo(id.id);
90 90 this.config.saveEntity = edge => {
91 91 return this.edgeService.saveEdge(edge).pipe(
92 92 tap(() => {
93 93 this.broadcast.broadcast('edgeSaved');
94 94 }),
95   - mergeMap((savedEdge) => this.edgeService.getEdge(savedEdge.id.id)
  95 + mergeMap((savedEdge) => this.edgeService.getEdgeInfo(savedEdge.id.id)
96 96 ));
97 97 };
98 98 this.config.onEntityAction = action => this.onEdgeAction(action);
... ...
... ... @@ -14,39 +14,40 @@
14 14 /// limitations under the License.
15 15 ///
16 16
17   -import { Injectable } from '@angular/core';
  17 +import {Injectable} from '@angular/core';
18 18
19   -import {ActivatedRouteSnapshot, Resolve, Route, Router} from '@angular/router';
  19 +import {ActivatedRouteSnapshot, Resolve, Router} from '@angular/router';
20 20 import {
21 21 CellActionDescriptor,
22 22 checkBoxCell,
23   - DateEntityTableColumn, EntityColumn,
  23 + DateEntityTableColumn,
  24 + EntityColumn,
24 25 EntityTableColumn,
25 26 EntityTableConfig,
26   - GroupActionDescriptor, HeaderActionDescriptor
  27 + GroupActionDescriptor,
  28 + HeaderActionDescriptor
27 29 } from '@home/models/entity/entities-table-config.models';
28   -import { TranslateService } from '@ngx-translate/core';
29   -import { DatePipe } from '@angular/common';
30   -import { EntityType, entityTypeResources, entityTypeTranslations } from '@shared/models/entity-type.models';
31   -import { EntityAction } from '@home/models/entity/entity-component.models';
32   -import { RuleChain, ruleChainType } from '@shared/models/rule-chain.models';
33   -import { RuleChainService } from '@core/http/rule-chain.service';
34   -import { RuleChainComponent } from '@modules/home/pages/rulechain/rulechain.component';
35   -import { DialogService } from '@core/services/dialog.service';
36   -import { RuleChainTabsComponent } from '@home/pages/rulechain/rulechain-tabs.component';
37   -import { ImportExportService } from '@home/components/import-export/import-export.service';
38   -import { ItemBufferService } from '@core/services/item-buffer.service';
39   -import { EdgeService } from "@core/http/edge.service";
40   -import {map, mergeMap} from "rxjs/operators";
41   -import { forkJoin, Observable } from "rxjs";
  30 +import {TranslateService} from '@ngx-translate/core';
  31 +import {DatePipe} from '@angular/common';
  32 +import {EntityType, entityTypeResources, entityTypeTranslations} from '@shared/models/entity-type.models';
  33 +import {EntityAction} from '@home/models/entity/entity-component.models';
  34 +import {RuleChain, ruleChainType} from '@shared/models/rule-chain.models';
  35 +import {RuleChainService} from '@core/http/rule-chain.service';
  36 +import {RuleChainComponent} from '@modules/home/pages/rulechain/rulechain.component';
  37 +import {DialogService} from '@core/services/dialog.service';
  38 +import {RuleChainTabsComponent} from '@home/pages/rulechain/rulechain-tabs.component';
  39 +import {ImportExportService} from '@home/components/import-export/import-export.service';
  40 +import {ItemBufferService} from '@core/services/item-buffer.service';
  41 +import {EdgeService} from "@core/http/edge.service";
  42 +import {forkJoin, Observable} from "rxjs";
42 43 import {
43 44 AddEntitiesToEdgeDialogComponent,
44 45 AddEntitiesToEdgeDialogData
45 46 } from "@home/dialogs/add-entities-to-edge-dialog.component";
46   -import { MatDialog } from "@angular/material/dialog";
47   -import { isDefined, isUndefined } from "@core/utils";
48   -import { PageLink } from "@shared/models/page/page-link";
49   -import { Edge } from "@shared/models/edge.models";
  47 +import {MatDialog} from "@angular/material/dialog";
  48 +import {isUndefined} from "@core/utils";
  49 +import {PageLink} from "@shared/models/page/page-link";
  50 +import {Edge} from "@shared/models/edge.models";
50 51
51 52 @Injectable()
52 53 export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig<RuleChain>> {
... ... @@ -267,7 +268,8 @@ export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig<
267 268 if ($event) {
268 269 $event.stopPropagation();
269 270 }
270   - this.importExport.importRuleChain().subscribe((ruleChainImport) => {
  271 + const expectedRuleChainType = this.config.componentsData.ruleChainScope === 'tenant' ? ruleChainType.core : ruleChainType.edge;
  272 + this.importExport.importRuleChain(expectedRuleChainType).subscribe((ruleChainImport) => {
271 273 if (ruleChainImport) {
272 274 this.itembuffer.storeRuleChainImport(ruleChainImport);
273 275 this.router.navigateByUrl(`${this.router.routerState.snapshot.url}/ruleChain/import`);
... ... @@ -488,17 +490,17 @@ export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig<
488 490
489 491 isNonRootRuleChain(ruleChain: RuleChain) {
490 492 if (this.config.componentsData.ruleChainScope === 'edge') {
491   - return (isDefined(this.config.componentsData.edge.rootRuleChainId) && this.config.componentsData.edge.rootRuleChainId != null && this.config.componentsData.edge.rootRuleChainId.id != ruleChain.id.id);
  493 + return this.config.componentsData.edge.rootRuleChainId && true && this.config.componentsData.edge.rootRuleChainId.id != ruleChain.id.id;
492 494 }
493   - return (isDefined(ruleChain)) && !ruleChain.root;
  495 + return !ruleChain.root;
494 496 }
495 497
496 498 isDefaultEdgeRuleChain(ruleChain) {
497   - return (isDefined(ruleChain)) && !ruleChain.root && this.config.componentsData.defaultEdgeRuleChainIds.includes(ruleChain.id.id);
  499 + return !ruleChain.root && this.config.componentsData.defaultEdgeRuleChainIds.includes(ruleChain.id.id);
498 500 }
499 501
500 502 isNonDefaultEdgeRuleChain(ruleChain) {
501   - return (isDefined(ruleChain)) && !ruleChain.root && !this.config.componentsData.defaultEdgeRuleChainIds.includes(ruleChain.id.id);
  503 + return !ruleChain.root && !this.config.componentsData.defaultEdgeRuleChainIds.includes(ruleChain.id.id);
502 504 }
503 505
504 506 fetchRuleChains(pageLink: PageLink) {
... ...