fixed bug with customer assignment to edge

This commit is contained in:
Bohdan Smetaniuk 2020-04-29 20:05:29 +03:00
parent 7d10134f77
commit c1c725542a
10 changed files with 354 additions and 109 deletions

View File

@ -31,6 +31,7 @@ import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeInfo;
import org.thingsboard.server.common.data.edge.EdgeSearchQuery;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.CustomerId;
@ -246,6 +247,29 @@ public class EdgeController extends BaseController {
}
}
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/tenant/edgeInfos", params = {"pageSize", "page"}, method = RequestMethod.GET)
@ResponseBody
public PageData<EdgeInfo> getTenantEdgeInfos(
@RequestParam int pageSize,
@RequestParam int page,
@RequestParam(required = false) String type,
@RequestParam(required = false) String textSearch,
@RequestParam(required = false) String sortProperty,
@RequestParam(required = false) String sortOrder) throws ThingsboardException {
try {
TenantId tenantId = getCurrentUser().getTenantId();
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
if (type != null && type.trim().length() > 0) {
return checkNotNull(edgeService.findEdgeInfosByTenantIdAndType(tenantId, type, pageLink));
} else {
return checkNotNull(edgeService.findEdgeInfosByTenantId(tenantId, pageLink));
}
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/tenant/edges", params = {"edgeName"}, method = RequestMethod.GET)
@ResponseBody

View File

@ -20,6 +20,7 @@ import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.Event;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeInfo;
import org.thingsboard.server.common.data.edge.EdgeSearchQuery;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EdgeId;
@ -56,6 +57,10 @@ public interface EdgeService {
PageData<Edge> findEdgesByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink);
PageData<EdgeInfo> findEdgeInfosByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink);
PageData<EdgeInfo> findEdgeInfosByTenantId(TenantId tenantId, PageLink pageLink);
ListenableFuture<List<Edge>> findEdgesByTenantIdAndIdsAsync(TenantId tenantId, List<EdgeId> edgeIds);
void deleteEdgesByTenantId(TenantId tenantId);

View File

@ -0,0 +1,40 @@
/**
* Copyright © 2016-2020 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.
*/
package org.thingsboard.server.common.data.edge;
import lombok.Data;
import org.thingsboard.server.common.data.id.EdgeId;
@Data
public class EdgeInfo extends Edge {
private String customerTitle;
private boolean customerIsPublic;
public EdgeInfo() {
super();
}
public EdgeInfo(EdgeId edgeId) {
super(edgeId);
}
public EdgeInfo(Edge edge, String customerTitle, boolean customerIsPublic) {
super(edge);
this.customerTitle = customerTitle;
this.customerIsPublic = customerIsPublic;
}
}

View File

@ -42,6 +42,7 @@ import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeInfo;
import org.thingsboard.server.common.data.edge.EdgeQueueEntityType;
import org.thingsboard.server.common.data.edge.EdgeQueueEntry;
import org.thingsboard.server.common.data.edge.EdgeSearchQuery;
@ -246,6 +247,24 @@ public class BaseEdgeService extends AbstractEntityService implements EdgeServic
return edgeDao.findEdgesByTenantIdAndType(tenantId.getId(), type, pageLink);
}
@Override
public PageData<EdgeInfo> findEdgeInfosByTenantIdAndType(TenantId tenantId, String type, PageLink pageLink) {
log.trace("Executing findEdgeInfosByTenantIdAndType, tenantId [{}], type [{}], pageLink [{}]", tenantId, type, pageLink);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validateString(type, "Incorrect type " + type);
validatePageLink(pageLink);
return edgeDao.findEdgeInfosByTenantIdAndType(tenantId.getId(), type, pageLink);
}
@Override
public PageData<EdgeInfo> findEdgeInfosByTenantId(TenantId tenantId, PageLink pageLink) {
log.trace("Executing findEdgeInfosByTenantId, tenantId [{}], pageLink [{}]", tenantId, pageLink);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
validatePageLink(pageLink);
return edgeDao.findEdgeInfosByTenantId(tenantId.getId(), pageLink);
}
@Override
public ListenableFuture<List<Edge>> findEdgesByTenantIdAndIdsAsync(TenantId tenantId, List<EdgeId> edgeIds) {
log.trace("Executing findEdgesByTenantIdAndIdsAsync, tenantId [{}], edgeIds [{}]", tenantId, edgeIds);

View File

@ -18,6 +18,7 @@ package org.thingsboard.server.dao.edge;
import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeInfo;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
@ -125,4 +126,8 @@ public interface EdgeDao extends Dao<Edge> {
*/
Optional<Edge> findByRoutingKey(UUID tenantId, String routingKey);
PageData<EdgeInfo> findEdgeInfosByTenantIdAndType(UUID tenantId, String type, PageLink pageLink);
PageData<EdgeInfo> findEdgeInfosByTenantId(UUID tenantId, PageLink pageLink);
}

View File

@ -0,0 +1,157 @@
/**
* Copyright © 2016-2020 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.
*/
package org.thingsboard.server.dao.model.sql;
import com.datastax.driver.core.utils.UUIDs;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.UUIDConverter;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseSqlEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
import org.thingsboard.server.dao.util.mapping.JsonStringType;
import javax.persistence.Column;
import javax.persistence.MappedSuperclass;
import static org.thingsboard.server.dao.model.ModelConstants.*;
@Data
@EqualsAndHashCode(callSuper = true)
@TypeDef(name = "json", typeClass = JsonStringType.class)
@MappedSuperclass
public abstract class AbstractEdgeEntity<T extends Edge> extends BaseSqlEntity<T> implements SearchTextEntity<T> {
@Column(name = EDGE_TENANT_ID_PROPERTY)
private String tenantId;
@Column(name = EDGE_CUSTOMER_ID_PROPERTY)
private String customerId;
@Column(name = EDGE_ROOT_RULE_CHAIN_ID_PROPERTY)
private String rootRuleChainId;
@Column(name = EDGE_TYPE_PROPERTY)
private String type;
@Column(name = EDGE_NAME_PROPERTY)
private String name;
@Column(name = EDGE_LABEL_PROPERTY)
private String label;
@Column(name = SEARCH_TEXT_PROPERTY)
private String searchText;
@Column(name = EDGE_ROUTING_KEY_PROPERTY)
private String routingKey;
@Column(name = EDGE_SECRET_PROPERTY)
private String secret;
@Type(type = "json")
@Column(name = ModelConstants.EDGE_CONFIGURATION_PROPERTY)
private JsonNode configuration;
@Type(type = "json")
@Column(name = ModelConstants.EDGE_ADDITIONAL_INFO_PROPERTY)
private JsonNode additionalInfo;
public AbstractEdgeEntity() {
super();
}
public AbstractEdgeEntity(Edge edge) {
if (edge.getId() != null) {
this.setId(edge.getId().getId());
}
if (edge.getTenantId() != null) {
this.tenantId = UUIDConverter.fromTimeUUID(edge.getTenantId().getId());
}
if (edge.getCustomerId() != null) {
this.customerId = UUIDConverter.fromTimeUUID(edge.getCustomerId().getId());
}
if (edge.getRootRuleChainId() != null) {
this.rootRuleChainId = UUIDConverter.fromTimeUUID(edge.getRootRuleChainId().getId());
}
this.type = edge.getType();
this.name = edge.getName();
this.label = edge.getLabel();
this.routingKey = edge.getRoutingKey();
this.secret = edge.getSecret();
this.configuration = edge.getConfiguration();
this.additionalInfo = edge.getAdditionalInfo();
}
public AbstractEdgeEntity(EdgeEntity edgeEntity) {
this.setId(edgeEntity.getId());
this.tenantId = edgeEntity.getTenantId();
this.customerId = edgeEntity.getCustomerId();
this.rootRuleChainId = edgeEntity.getRootRuleChainId();
this.type = edgeEntity.getType();
this.name = edgeEntity.getName();
this.label = edgeEntity.getLabel();
this.searchText = edgeEntity.getSearchText();
this.routingKey = edgeEntity.getRoutingKey();
this.secret = edgeEntity.getSecret();
this.configuration = edgeEntity.getConfiguration();
this.additionalInfo = edgeEntity.getAdditionalInfo();
}
public String getSearchText() {
return searchText;
}
@Override
public String getSearchTextSource() {
return name;
}
@Override
public void setSearchText(String searchText) {
this.searchText = searchText;
}
protected Edge toEdge() {
Edge edge = new Edge(new EdgeId(UUIDConverter.fromString(id)));
edge.setCreatedTime(UUIDs.unixTimestamp(UUIDConverter.fromString(id)));
if (tenantId != null) {
edge.setTenantId(new TenantId(UUIDConverter.fromString(tenantId)));
}
if (customerId != null) {
edge.setCustomerId(new CustomerId(UUIDConverter.fromString(customerId)));
}
if (rootRuleChainId != null) {
edge.setRootRuleChainId(new RuleChainId(UUIDConverter.fromString(rootRuleChainId)));
}
edge.setType(type);
edge.setName(name);
edge.setLabel(label);
edge.setRoutingKey(routingKey);
edge.setSecret(secret);
edge.setConfiguration(configuration);
edge.setAdditionalInfo(additionalInfo);
return edge;
}
}

View File

@ -15,140 +15,34 @@
*/
package org.thingsboard.server.dao.model.sql;
import com.datastax.driver.core.utils.UUIDs;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import org.thingsboard.server.common.data.UUIDConverter;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EdgeId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.dao.model.BaseSqlEntity;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
import org.thingsboard.server.dao.util.mapping.JsonStringType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_COLUMN_FAMILY_NAME;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_CUSTOMER_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_LABEL_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_NAME_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_ROOT_RULE_CHAIN_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_ROUTING_KEY_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_SECRET_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_TENANT_ID_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.EDGE_TYPE_PROPERTY;
import static org.thingsboard.server.dao.model.ModelConstants.SEARCH_TEXT_PROPERTY;
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@TypeDef(name = "json", typeClass = JsonStringType.class)
@Table(name = EDGE_COLUMN_FAMILY_NAME)
public class EdgeEntity extends BaseSqlEntity<Edge> implements SearchTextEntity<Edge> {
@Column(name = EDGE_TENANT_ID_PROPERTY)
private String tenantId;
@Column(name = EDGE_CUSTOMER_ID_PROPERTY)
private String customerId;
@Column(name = EDGE_ROOT_RULE_CHAIN_ID_PROPERTY)
private String rootRuleChainId;
@Column(name = EDGE_TYPE_PROPERTY)
private String type;
@Column(name = EDGE_NAME_PROPERTY)
private String name;
@Column(name = EDGE_LABEL_PROPERTY)
private String label;
@Column(name = SEARCH_TEXT_PROPERTY)
private String searchText;
@Column(name = EDGE_ROUTING_KEY_PROPERTY)
private String routingKey;
@Column(name = EDGE_SECRET_PROPERTY)
private String secret;
@Type(type = "json")
@Column(name = ModelConstants.EDGE_CONFIGURATION_PROPERTY)
private JsonNode configuration;
@Type(type = "json")
@Column(name = ModelConstants.EDGE_ADDITIONAL_INFO_PROPERTY)
private JsonNode additionalInfo;
public class EdgeEntity extends AbstractEdgeEntity<Edge> {
public EdgeEntity() {
super();
}
public EdgeEntity(Edge edge) {
if (edge.getId() != null) {
this.setId(edge.getId().getId());
}
if (edge.getTenantId() != null) {
this.tenantId = UUIDConverter.fromTimeUUID(edge.getTenantId().getId());
}
if (edge.getCustomerId() != null) {
this.customerId = UUIDConverter.fromTimeUUID(edge.getCustomerId().getId());
}
if (edge.getRootRuleChainId() != null) {
this.rootRuleChainId = UUIDConverter.fromTimeUUID(edge.getRootRuleChainId().getId());
}
this.type = edge.getType();
this.name = edge.getName();
this.label = edge.getLabel();
this.routingKey = edge.getRoutingKey();
this.secret = edge.getSecret();
this.configuration = edge.getConfiguration();
this.additionalInfo = edge.getAdditionalInfo();
}
public String getSearchText() {
return searchText;
}
@Override
public String getSearchTextSource() {
return name;
}
@Override
public void setSearchText(String searchText) {
this.searchText = searchText;
super(edge);
}
@Override
public Edge toData() {
Edge edge = new Edge(new EdgeId(UUIDConverter.fromString(id)));
edge.setCreatedTime(UUIDs.unixTimestamp(UUIDConverter.fromString(id)));
if (tenantId != null) {
edge.setTenantId(new TenantId(UUIDConverter.fromString(tenantId)));
}
if (customerId != null) {
edge.setCustomerId(new CustomerId(UUIDConverter.fromString(customerId)));
}
if (rootRuleChainId != null) {
edge.setRootRuleChainId(new RuleChainId(UUIDConverter.fromString(rootRuleChainId)));
}
edge.setType(type);
edge.setName(name);
edge.setLabel(label);
edge.setRoutingKey(routingKey);
edge.setSecret(secret);
edge.setConfiguration(configuration);
edge.setAdditionalInfo(additionalInfo);
return edge;
return super.toEdge();
}
}

View File

@ -0,0 +1,59 @@
/**
* Copyright © 2016-2020 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.
*/
package org.thingsboard.server.dao.model.sql;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.thingsboard.server.common.data.edge.EdgeInfo;
import java.util.HashMap;
import java.util.Map;
@Data
@EqualsAndHashCode(callSuper = true)
public class EdgeInfoEntity extends AbstractEdgeEntity<EdgeInfo> {
public static final Map<String,String> edgeInfoColumnMap = new HashMap<>();
static {
edgeInfoColumnMap.put("customerTitle", "c.title");
}
private String customerTitle;
private boolean customerIsPublic;
public EdgeInfoEntity() {
super();
}
public EdgeInfoEntity(EdgeEntity edgeEntity,
String customerTitle,
Object customerAdditionalInfo) {
super(edgeEntity);
this.customerTitle = customerTitle;
if (customerAdditionalInfo != null && ((JsonNode)customerAdditionalInfo).has("isPublic")) {
this.customerIsPublic = ((JsonNode)customerAdditionalInfo).get("isPublic").asBoolean();
} else {
this.customerIsPublic = false;
}
}
@Override
public EdgeInfo toData() {
return new EdgeInfo(super.toEdge(), customerTitle, customerIsPublic);
}
}

View File

@ -21,6 +21,7 @@ import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import org.thingsboard.server.dao.model.sql.EdgeEntity;
import org.thingsboard.server.dao.model.sql.EdgeInfoEntity;
import org.thingsboard.server.dao.util.SqlDao;
import java.util.List;
@ -42,6 +43,15 @@ public interface EdgeRepository extends CrudRepository<EdgeEntity, String> {
@Param("textSearch") String textSearch,
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.tenantId = :tenantId " +
"AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
Page<EdgeInfoEntity> findEdgeInfosByTenantId(@Param("tenantId") String tenantId,
@Param("textSearch") String textSearch,
Pageable pageable);
@Query("SELECT d FROM EdgeEntity d WHERE d.tenantId = :tenantId " +
"AND d.type = :type " +
"AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
@ -50,6 +60,17 @@ public interface EdgeRepository extends CrudRepository<EdgeEntity, String> {
@Param("textSearch") String textSearch,
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.tenantId = :tenantId " +
"AND d.type = :type " +
"AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
Page<EdgeInfoEntity> findEdgeInfosByTenantIdAndType(@Param("tenantId") String tenantId,
@Param("type") String type,
@Param("textSearch") String textSearch,
Pageable pageable);
@Query("SELECT d FROM EdgeEntity d WHERE d.tenantId = :tenantId " +
"AND d.customerId = :customerId " +
"AND d.type = :type " +

View File

@ -23,12 +23,14 @@ import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.UUIDConverter;
import org.thingsboard.server.common.data.edge.Edge;
import org.thingsboard.server.common.data.edge.EdgeInfo;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.edge.EdgeDao;
import org.thingsboard.server.dao.model.sql.EdgeEntity;
import org.thingsboard.server.dao.model.sql.EdgeInfoEntity;
import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
import org.thingsboard.server.dao.util.SqlDao;
@ -121,6 +123,25 @@ public class JpaEdgeDao extends JpaAbstractSearchTextDao<EdgeEntity, Edge> imple
return service.submit(() -> convertTenantEdgeTypesToDto(tenantId, edgeRepository.findTenantEdgeTypes(fromTimeUUID(tenantId))));
}
@Override
public PageData<EdgeInfo> findEdgeInfosByTenantIdAndType(UUID tenantId, String type, PageLink pageLink) {
return DaoUtil.toPageData(
edgeRepository.findEdgeInfosByTenantIdAndType(
fromTimeUUID(tenantId),
type,
Objects.toString(pageLink.getTextSearch(), ""),
DaoUtil.toPageable(pageLink, EdgeInfoEntity.edgeInfoColumnMap)));
}
@Override
public PageData<EdgeInfo> findEdgeInfosByTenantId(UUID tenantId, PageLink pageLink) {
return DaoUtil.toPageData(
edgeRepository.findEdgeInfosByTenantId(
fromTimeUUID(tenantId),
Objects.toString(pageLink.getTextSearch(), ""),
DaoUtil.toPageable(pageLink, EdgeInfoEntity.edgeInfoColumnMap)));
}
@Override
public Optional<Edge> findByRoutingKey(UUID tenantId, String routingKey) {
Edge edge = DaoUtil.getData(edgeRepository.findByRoutingKey(routingKey));