Browse Source

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

Develop/3.3 edge Fix rule chain type, customerIsPublic for edges. Added EdgeInfo
pull/3811/head
VoBa 6 years ago
committed by GitHub
parent
commit
77ad519a10
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 13
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  2. 13
      application/src/main/java/org/thingsboard/server/controller/EdgeController.java
  3. 2
      common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java
  4. 9
      dao/src/main/java/org/thingsboard/server/dao/edge/EdgeDao.java
  5. 7
      dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java
  6. 6
      dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeRepository.java
  7. 5
      dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaEdgeDao.java
  8. 10
      ui-ngx/src/app/core/http/edge.service.ts
  9. 5
      ui-ngx/src/app/core/http/rule-chain.service.ts
  10. 18
      ui-ngx/src/app/modules/home/components/import-export/import-export.service.ts
  11. 6
      ui-ngx/src/app/modules/home/pages/edge/edge-routing.module.ts
  12. 4
      ui-ngx/src/app/modules/home/pages/edge/edges-table-config.resolver.ts
  13. 56
      ui-ngx/src/app/modules/home/pages/rulechain/rulechains-table-config.resolver.ts

13
application/src/main/java/org/thingsboard/server/controller/BaseController.java

@ -50,6 +50,7 @@ import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.asset.AssetInfo; import org.thingsboard.server.common.data.asset.AssetInfo;
import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge; import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeInfo;
import org.thingsboard.server.common.data.edge.EdgeEventActionType; import org.thingsboard.server.common.data.edge.EdgeEventActionType;
import org.thingsboard.server.common.data.edge.EdgeEventType; import org.thingsboard.server.common.data.edge.EdgeEventType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
@ -643,6 +644,18 @@ public abstract class BaseController {
} }
} }
EdgeInfo checkEdgeInfoId(EdgeId edgeId, Operation operation) throws ThingsboardException {
try {
validateId(edgeId, "Incorrect edgeId " + edgeId);
EdgeInfo edge = edgeService.findEdgeInfoById(getCurrentUser().getTenantId(), edgeId);
checkNotNull(edge);
accessControlService.checkPermission(getCurrentUser(), Resource.EDGE, operation, edgeId, edge);
return edge;
} catch (Exception e) {
throw handleException(e, false);
}
}
DashboardInfo checkDashboardInfoId(DashboardId dashboardId, Operation operation) throws ThingsboardException { DashboardInfo checkDashboardInfoId(DashboardId dashboardId, Operation operation) throws ThingsboardException {
try { try {
validateId(dashboardId, "Incorrect dashboardId " + dashboardId); validateId(dashboardId, "Incorrect dashboardId " + dashboardId);

13
application/src/main/java/org/thingsboard/server/controller/EdgeController.java

@ -84,6 +84,19 @@ public class EdgeController extends BaseController {
} }
} }
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/edge/info/{edgeId}", method = RequestMethod.GET)
@ResponseBody
public EdgeInfo getEdgeInfoById(@PathVariable(EDGE_ID) String strEdgeId) throws ThingsboardException {
checkParameter(EDGE_ID, strEdgeId);
try {
EdgeId edgeId = new EdgeId(toUUID(strEdgeId));
return checkEdgeInfoId(edgeId, Operation.READ);
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAuthority('TENANT_ADMIN')") @PreAuthorize("hasAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/edge", method = RequestMethod.POST) @RequestMapping(value = "/edge", method = RequestMethod.POST)
@ResponseBody @ResponseBody

2
common/dao-api/src/main/java/org/thingsboard/server/dao/edge/EdgeService.java

@ -36,6 +36,8 @@ public interface EdgeService {
Edge findEdgeById(TenantId tenantId, EdgeId edgeId); Edge findEdgeById(TenantId tenantId, EdgeId edgeId);
EdgeInfo findEdgeInfoById(TenantId tenantId, EdgeId edgeId);
ListenableFuture<Edge> findEdgeByIdAsync(TenantId tenantId, EdgeId edgeId); ListenableFuture<Edge> findEdgeByIdAsync(TenantId tenantId, EdgeId edgeId);
Edge findEdgeByTenantIdAndName(TenantId tenantId, String name); Edge findEdgeByTenantIdAndName(TenantId tenantId, String name);

9
dao/src/main/java/org/thingsboard/server/dao/edge/EdgeDao.java

@ -42,6 +42,15 @@ public interface EdgeDao extends Dao<Edge> {
*/ */
Edge save(TenantId tenantId, Edge edge); Edge save(TenantId tenantId, Edge edge);
/**
* Find edge info by id.
*
* @param tenantId the tenant id
* @param edgeId the edge id
* @return the edge info object
*/
EdgeInfo findEdgeInfoById(TenantId tenantId, UUID edgeId);
/** /**
* Find edges by tenantId and page link. * Find edges by tenantId and page link.
* *

7
dao/src/main/java/org/thingsboard/server/dao/edge/EdgeServiceImpl.java

@ -143,6 +143,13 @@ public class EdgeServiceImpl extends AbstractEntityService implements EdgeServic
return edgeDao.findById(tenantId, edgeId.getId()); return edgeDao.findById(tenantId, edgeId.getId());
} }
@Override
public EdgeInfo findEdgeInfoById(TenantId tenantId, EdgeId edgeId) {
log.trace("Executing findEdgeInfoById [{}]", edgeId);
validateId(edgeId, INCORRECT_EDGE_ID + edgeId);
return edgeDao.findEdgeInfoById(tenantId, edgeId.getId());
}
@Override @Override
public ListenableFuture<Edge> findEdgeByIdAsync(TenantId tenantId, EdgeId edgeId) { public ListenableFuture<Edge> findEdgeByIdAsync(TenantId tenantId, EdgeId edgeId) {
log.trace("Executing findEdgeById [{}]", edgeId); log.trace("Executing findEdgeById [{}]", edgeId);

6
dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeRepository.java

@ -36,6 +36,12 @@ public interface EdgeRepository extends PagingAndSortingRepository<EdgeEntity, U
@Param("textSearch") String textSearch, @Param("textSearch") String textSearch,
Pageable pageable); Pageable pageable);
@Query("SELECT new org.thingsboard.server.dao.model.sql.EdgeInfoEntity(d, c.title, c.additionalInfo) " +
"FROM EdgeEntity d " +
"LEFT JOIN CustomerEntity c on c.id = d.customerId " +
"WHERE d.id = :edgeId")
EdgeInfoEntity findEdgeInfoById(@Param("edgeId") UUID edgeId);
@Query("SELECT d FROM EdgeEntity d WHERE d.tenantId = :tenantId " + @Query("SELECT d FROM EdgeEntity d WHERE d.tenantId = :tenantId " +
"AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))") "AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
Page<EdgeEntity> findByTenantId(@Param("tenantId") UUID tenantId, Page<EdgeEntity> findByTenantId(@Param("tenantId") UUID tenantId,

5
dao/src/main/java/org/thingsboard/server/dao/sql/edge/JpaEdgeDao.java

@ -67,6 +67,11 @@ public class JpaEdgeDao extends JpaAbstractSearchTextDao<EdgeEntity, Edge> imple
return edgeRepository; return edgeRepository;
} }
@Override
public EdgeInfo findEdgeInfoById(TenantId tenantId, UUID edgeId) {
return DaoUtil.getData(edgeRepository.findEdgeInfoById(edgeId));
}
@Override @Override
public PageData<Edge> findEdgesByTenantId(UUID tenantId, PageLink pageLink) { public PageData<Edge> findEdgesByTenantId(UUID tenantId, PageLink pageLink) {
return DaoUtil.toPageData( return DaoUtil.toPageData(

10
ui-ngx/src/app/core/http/edge.service.ts

@ -38,8 +38,12 @@ export class EdgeService {
defaultHttpOptionsFromConfig(config)); defaultHttpOptionsFromConfig(config));
} }
public getEdge(edgeId: string, config?: RequestConfig): Observable<EdgeInfo> { public getEdge(edgeId: string, config?: RequestConfig): Observable<Edge> {
return this.http.get<EdgeInfo>(`/api/edge/${edgeId}`, defaultHttpOptionsFromConfig(config)); return this.http.get<Edge>(`/api/edge/${edgeId}`, defaultHttpOptionsFromConfig(config));
}
public getEdgeInfo(edgeId: string, config?: RequestConfig): Observable<EdgeInfo> {
return this.http.get<EdgeInfo>(`/api/edge/info/${edgeId}`, defaultHttpOptionsFromConfig(config));
} }
public saveEdge(edge: Edge, config?: RequestConfig): Observable<Edge> { public saveEdge(edge: Edge, config?: RequestConfig): Observable<Edge> {
@ -72,7 +76,7 @@ export class EdgeService {
} }
public makeEdgePublic(edgeId: string, config?: RequestConfig): Observable<Edge> { public makeEdgePublic(edgeId: string, config?: RequestConfig): Observable<Edge> {
return this.http.post<Edge>(`/api/customer/public/edge/${edgeId}`, return this.http.post<Edge>(`/api/customer/public/edge/${edgeId}`, null,
defaultHttpOptionsFromConfig(config)); defaultHttpOptionsFromConfig(config));
} }

5
ui-ngx/src/app/core/http/rule-chain.service.ts

@ -324,9 +324,8 @@ export class RuleChainService {
return this.http.get<Array<RuleChain>>(`/api/ruleChain/defaultEdgeRuleChains`, defaultHttpOptionsFromConfig(config)); return this.http.get<Array<RuleChain>>(`/api/ruleChain/defaultEdgeRuleChains`, defaultHttpOptionsFromConfig(config));
} }
public setEdgeRootRuleChain(edgeId: string, ruleChainId: string, config?: RequestConfig): Observable<Edge> { //TODO deaflynx EdgeInfo vs. Edge check usage public setEdgeRootRuleChain(edgeId: string, ruleChainId: string, config?: RequestConfig): Observable<Edge> {
return this.http.post<Edge>(`/api/edge/${edgeId}/${ruleChainId}/root`, return this.http.post<Edge>(`/api/edge/${edgeId}/${ruleChainId}/root`, defaultHttpOptionsFromConfig(config));
defaultHttpOptionsFromConfig(config));
} }
} }

18
ui-ngx/src/app/modules/home/components/import-export/import-export.service.ts

@ -52,7 +52,13 @@ import { NULL_UUID } from '@shared/models/id/has-uuid';
import { WidgetsBundle } from '@shared/models/widgets-bundle.model'; import { WidgetsBundle } from '@shared/models/widgets-bundle.model';
import { ImportEntitiesResultInfo, ImportEntityData } from '@shared/models/entity.models'; import { ImportEntitiesResultInfo, ImportEntityData } from '@shared/models/entity.models';
import { RequestConfig } from '@core/http/http-utils'; import { RequestConfig } from '@core/http/http-utils';
import { RuleChain, RuleChainImport, RuleChainMetaData } from '@shared/models/rule-chain.models'; import {
RuleChain,
RuleChainImport,
RuleChainMetaData,
RuleChainType,
ruleChainType
} from '@shared/models/rule-chain.models';
import { RuleChainService } from '@core/http/rule-chain.service'; import { RuleChainService } from '@core/http/rule-chain.service';
import * as JSZip from 'jszip'; import * as JSZip from 'jszip';
import { FiltersInfo } from '@shared/models/query/query.models'; import { FiltersInfo } from '@shared/models/query/query.models';
@ -397,7 +403,7 @@ export class ImportExportService {
); );
} }
public importRuleChain(): Observable<RuleChainImport> { public importRuleChain(expectedRuleChainType: RuleChainType): Observable<RuleChainImport> {
return this.openImportDialog('rulechain.import', 'rulechain.rulechain-file').pipe( return this.openImportDialog('rulechain.import', 'rulechain.rulechain-file').pipe(
mergeMap((ruleChainImport: RuleChainImport) => { mergeMap((ruleChainImport: RuleChainImport) => {
if (!this.validateImportedRuleChain(ruleChainImport)) { if (!this.validateImportedRuleChain(ruleChainImport)) {
@ -405,6 +411,11 @@ export class ImportExportService {
{message: this.translate.instant('rulechain.invalid-rulechain-file-error'), {message: this.translate.instant('rulechain.invalid-rulechain-file-error'),
type: 'error'})); type: 'error'}));
throw new Error('Invalid rule chain file'); throw new Error('Invalid rule chain file');
} else if (ruleChainImport.ruleChain.type !== expectedRuleChainType) {
this.store.dispatch(new ActionNotificationShow(
{message: this.translate.instant('rulechain.invalid-rulechain-type-error', { expectedRuleChainType: expectedRuleChainType }),
type: 'error'}));
throw new Error('Invalid rule chain type');
} else { } else {
return this.ruleChainService.resolveRuleChainMetadata(ruleChainImport.metadata).pipe( return this.ruleChainService.resolveRuleChainMetadata(ruleChainImport.metadata).pipe(
map((resolvedMetadata) => { map((resolvedMetadata) => {
@ -458,6 +469,9 @@ export class ImportExportService {
|| isUndefined(ruleChainImport.ruleChain.name)) { || isUndefined(ruleChainImport.ruleChain.name)) {
return false; return false;
} }
if (isUndefined(ruleChainImport.ruleChain.type)) {
ruleChainImport.ruleChain.type = ruleChainType.core;
}
return true; return true;
} }

6
ui-ngx/src/app/modules/home/pages/edge/edge-routing.module.ts

@ -27,9 +27,9 @@ import { RuleChainsTableConfigResolver } from "@home/pages/rulechain/rulechains-
import { DashboardPageComponent } from "@home/pages/dashboard/dashboard-page.component"; import { DashboardPageComponent } from "@home/pages/dashboard/dashboard-page.component";
import { dashboardBreadcumbLabelFunction, DashboardResolver } from "@home/pages/dashboard/dashboard-routing.module"; import { dashboardBreadcumbLabelFunction, DashboardResolver } from "@home/pages/dashboard/dashboard-routing.module";
import { BreadCrumbConfig } from "@shared/components/breadcrumb"; import { BreadCrumbConfig } from "@shared/components/breadcrumb";
import {RuleChainPageComponent} from "@home/pages/rulechain/rulechain-page.component"; import { RuleChainPageComponent } from "@home/pages/rulechain/rulechain-page.component";
import {ConfirmOnExitGuard} from "@core/guards/confirm-on-exit.guard"; import { ConfirmOnExitGuard } from "@core/guards/confirm-on-exit.guard";
import {ruleChainType} from "@shared/models/rule-chain.models"; import { ruleChainType } from "@shared/models/rule-chain.models";
import { import {
importRuleChainBreadcumbLabelFunction, importRuleChainBreadcumbLabelFunction,
ResolvedRuleChainMetaDataResolver, ResolvedRuleChainMetaDataResolver,

4
ui-ngx/src/app/modules/home/pages/edge/edges-table-config.resolver.ts

@ -86,13 +86,13 @@ export class EdgesTableConfigResolver implements Resolve<EntityTableConfig<EdgeI
this.config.deleteEntitiesTitle = count => this.translate.instant('edge.delete-edges-title', {count}); this.config.deleteEntitiesTitle = count => this.translate.instant('edge.delete-edges-title', {count});
this.config.deleteEntitiesContent = () => this.translate.instant('edge.delete-edges-text'); this.config.deleteEntitiesContent = () => this.translate.instant('edge.delete-edges-text');
this.config.loadEntity = id => this.edgeService.getEdge(id.id); this.config.loadEntity = id => this.edgeService.getEdgeInfo(id.id);
this.config.saveEntity = edge => { this.config.saveEntity = edge => {
return this.edgeService.saveEdge(edge).pipe( return this.edgeService.saveEdge(edge).pipe(
tap(() => { tap(() => {
this.broadcast.broadcast('edgeSaved'); this.broadcast.broadcast('edgeSaved');
}), }),
mergeMap((savedEdge) => this.edgeService.getEdge(savedEdge.id.id) mergeMap((savedEdge) => this.edgeService.getEdgeInfo(savedEdge.id.id)
)); ));
}; };
this.config.onEntityAction = action => this.onEdgeAction(action); this.config.onEntityAction = action => this.onEdgeAction(action);

56
ui-ngx/src/app/modules/home/pages/rulechain/rulechains-table-config.resolver.ts

@ -14,39 +14,40 @@
/// limitations under the License. /// limitations under the License.
/// ///
import { Injectable } from '@angular/core'; import {Injectable} from '@angular/core';
import {ActivatedRouteSnapshot, Resolve, Route, Router} from '@angular/router'; import {ActivatedRouteSnapshot, Resolve, Router} from '@angular/router';
import { import {
CellActionDescriptor, CellActionDescriptor,
checkBoxCell, checkBoxCell,
DateEntityTableColumn, EntityColumn, DateEntityTableColumn,
EntityColumn,
EntityTableColumn, EntityTableColumn,
EntityTableConfig, EntityTableConfig,
GroupActionDescriptor, HeaderActionDescriptor GroupActionDescriptor,
HeaderActionDescriptor
} from '@home/models/entity/entities-table-config.models'; } from '@home/models/entity/entities-table-config.models';
import { TranslateService } from '@ngx-translate/core'; import {TranslateService} from '@ngx-translate/core';
import { DatePipe } from '@angular/common'; import {DatePipe} from '@angular/common';
import { EntityType, entityTypeResources, entityTypeTranslations } from '@shared/models/entity-type.models'; import {EntityType, entityTypeResources, entityTypeTranslations} from '@shared/models/entity-type.models';
import { EntityAction } from '@home/models/entity/entity-component.models'; import {EntityAction} from '@home/models/entity/entity-component.models';
import { RuleChain, ruleChainType } from '@shared/models/rule-chain.models'; import {RuleChain, ruleChainType} from '@shared/models/rule-chain.models';
import { RuleChainService } from '@core/http/rule-chain.service'; import {RuleChainService} from '@core/http/rule-chain.service';
import { RuleChainComponent } from '@modules/home/pages/rulechain/rulechain.component'; import {RuleChainComponent} from '@modules/home/pages/rulechain/rulechain.component';
import { DialogService } from '@core/services/dialog.service'; import {DialogService} from '@core/services/dialog.service';
import { RuleChainTabsComponent } from '@home/pages/rulechain/rulechain-tabs.component'; import {RuleChainTabsComponent} from '@home/pages/rulechain/rulechain-tabs.component';
import { ImportExportService } from '@home/components/import-export/import-export.service'; import {ImportExportService} from '@home/components/import-export/import-export.service';
import { ItemBufferService } from '@core/services/item-buffer.service'; import {ItemBufferService} from '@core/services/item-buffer.service';
import { EdgeService } from "@core/http/edge.service"; import {EdgeService} from "@core/http/edge.service";
import {map, mergeMap} from "rxjs/operators"; import {forkJoin, Observable} from "rxjs";
import { forkJoin, Observable } from "rxjs";
import { import {
AddEntitiesToEdgeDialogComponent, AddEntitiesToEdgeDialogComponent,
AddEntitiesToEdgeDialogData AddEntitiesToEdgeDialogData
} from "@home/dialogs/add-entities-to-edge-dialog.component"; } from "@home/dialogs/add-entities-to-edge-dialog.component";
import { MatDialog } from "@angular/material/dialog"; import {MatDialog} from "@angular/material/dialog";
import { isDefined, isUndefined } from "@core/utils"; import {isUndefined} from "@core/utils";
import { PageLink } from "@shared/models/page/page-link"; import {PageLink} from "@shared/models/page/page-link";
import { Edge } from "@shared/models/edge.models"; import {Edge} from "@shared/models/edge.models";
@Injectable() @Injectable()
export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig<RuleChain>> { export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig<RuleChain>> {
@ -267,7 +268,8 @@ export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig<
if ($event) { if ($event) {
$event.stopPropagation(); $event.stopPropagation();
} }
this.importExport.importRuleChain().subscribe((ruleChainImport) => { const expectedRuleChainType = this.config.componentsData.ruleChainScope === 'tenant' ? ruleChainType.core : ruleChainType.edge;
this.importExport.importRuleChain(expectedRuleChainType).subscribe((ruleChainImport) => {
if (ruleChainImport) { if (ruleChainImport) {
this.itembuffer.storeRuleChainImport(ruleChainImport); this.itembuffer.storeRuleChainImport(ruleChainImport);
this.router.navigateByUrl(`${this.router.routerState.snapshot.url}/ruleChain/import`); this.router.navigateByUrl(`${this.router.routerState.snapshot.url}/ruleChain/import`);
@ -488,17 +490,17 @@ export class RuleChainsTableConfigResolver implements Resolve<EntityTableConfig<
isNonRootRuleChain(ruleChain: RuleChain) { isNonRootRuleChain(ruleChain: RuleChain) {
if (this.config.componentsData.ruleChainScope === 'edge') { if (this.config.componentsData.ruleChainScope === 'edge') {
return (isDefined(this.config.componentsData.edge.rootRuleChainId) && this.config.componentsData.edge.rootRuleChainId != null && this.config.componentsData.edge.rootRuleChainId.id != ruleChain.id.id); return this.config.componentsData.edge.rootRuleChainId && true && this.config.componentsData.edge.rootRuleChainId.id != ruleChain.id.id;
} }
return (isDefined(ruleChain)) && !ruleChain.root; return !ruleChain.root;
} }
isDefaultEdgeRuleChain(ruleChain) { isDefaultEdgeRuleChain(ruleChain) {
return (isDefined(ruleChain)) && !ruleChain.root && this.config.componentsData.defaultEdgeRuleChainIds.includes(ruleChain.id.id); return !ruleChain.root && this.config.componentsData.defaultEdgeRuleChainIds.includes(ruleChain.id.id);
} }
isNonDefaultEdgeRuleChain(ruleChain) { isNonDefaultEdgeRuleChain(ruleChain) {
return (isDefined(ruleChain)) && !ruleChain.root && !this.config.componentsData.defaultEdgeRuleChainIds.includes(ruleChain.id.id); return !ruleChain.root && !this.config.componentsData.defaultEdgeRuleChainIds.includes(ruleChain.id.id);
} }
fetchRuleChains(pageLink: PageLink) { fetchRuleChains(pageLink: PageLink) {

Loading…
Cancel
Save