Move update of dashboard alias to dashboard service. Added test for backward compatibility
This commit is contained in:
parent
56e2ce9241
commit
76f11c320b
@ -748,13 +748,6 @@ public class DefaultDataUpdateService implements DataUpdateService {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
List<ObjectNode> entityAliases = dashboard.getEntityAliasesConfig();
|
|
||||||
if (entityAliases == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
for (JsonNode entityAlias : entityAliases) {
|
|
||||||
MiscUtils.updateDashboardFilterIfRequired(entityAlias);
|
|
||||||
}
|
|
||||||
dashboardService.saveDashboard(dashboard);
|
dashboardService.saveDashboard(dashboard);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.warn("Failed to update dashboard filters. Dashboard {} ", dashboard, e);
|
log.warn("Failed to update dashboard filters. Dashboard {} ", dashboard, e);
|
||||||
|
|||||||
@ -22,9 +22,6 @@ import org.thingsboard.common.util.JacksonUtil;
|
|||||||
import org.thingsboard.server.common.data.Dashboard;
|
import org.thingsboard.server.common.data.Dashboard;
|
||||||
import org.thingsboard.server.common.data.EntityType;
|
import org.thingsboard.server.common.data.EntityType;
|
||||||
import org.thingsboard.server.common.data.ShortCustomerInfo;
|
import org.thingsboard.server.common.data.ShortCustomerInfo;
|
||||||
import org.thingsboard.server.common.data.User;
|
|
||||||
import org.thingsboard.server.common.data.edge.EdgeEventActionType;
|
|
||||||
import org.thingsboard.server.common.data.exception.ThingsboardException;
|
|
||||||
import org.thingsboard.server.common.data.id.CustomerId;
|
import org.thingsboard.server.common.data.id.CustomerId;
|
||||||
import org.thingsboard.server.common.data.id.DashboardId;
|
import org.thingsboard.server.common.data.id.DashboardId;
|
||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
@ -32,7 +29,6 @@ import org.thingsboard.server.common.data.sync.ie.EntityExportData;
|
|||||||
import org.thingsboard.server.dao.dashboard.DashboardService;
|
import org.thingsboard.server.dao.dashboard.DashboardService;
|
||||||
import org.thingsboard.server.queue.util.TbCoreComponent;
|
import org.thingsboard.server.queue.util.TbCoreComponent;
|
||||||
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
import org.thingsboard.server.service.sync.vc.data.EntitiesImportCtx;
|
||||||
import org.thingsboard.server.utils.MiscUtils;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -74,9 +70,6 @@ public class DashboardImportService extends BaseEntityImportService<DashboardId,
|
|||||||
for (JsonNode widgetConfig : dashboard.getWidgetsConfig()) {
|
for (JsonNode widgetConfig : dashboard.getWidgetsConfig()) {
|
||||||
replaceIdsRecursively(ctx, idProvider, JacksonUtil.getSafely(widgetConfig, "config", "actions"), Collections.singleton("id"), HINTS);
|
replaceIdsRecursively(ctx, idProvider, JacksonUtil.getSafely(widgetConfig, "config", "actions"), Collections.singleton("id"), HINTS);
|
||||||
}
|
}
|
||||||
for (JsonNode entityAlias : dashboard.getEntityAliasesConfig()) {
|
|
||||||
MiscUtils.updateDashboardFilterIfRequired(entityAlias);
|
|
||||||
}
|
|
||||||
return dashboard;
|
return dashboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,13 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.utils;
|
package org.thingsboard.server.utils;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
|
||||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
|
||||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
|
||||||
import com.google.common.hash.HashFunction;
|
import com.google.common.hash.HashFunction;
|
||||||
import com.google.common.hash.Hashing;
|
import com.google.common.hash.Hashing;
|
||||||
import org.thingsboard.common.util.JacksonUtil;
|
|
||||||
import org.thingsboard.server.common.data.query.EntityFilterType;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
@ -111,26 +106,4 @@ public class MiscUtils {
|
|||||||
}
|
}
|
||||||
return serverPort;
|
return serverPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void updateDashboardFilterIfRequired(JsonNode entityAlias) {
|
|
||||||
JsonNode filter = entityAlias.get("filter");
|
|
||||||
updateFilterByTypeIfRequired(filter, EntityFilterType.ASSET_TYPE.getLabel());
|
|
||||||
updateFilterByTypeIfRequired(filter, EntityFilterType.DEVICE_TYPE.getLabel());
|
|
||||||
updateFilterByTypeIfRequired(filter, EntityFilterType.ENTITY_VIEW_TYPE.getLabel());
|
|
||||||
updateFilterByTypeIfRequired(filter, EntityFilterType.EDGE_TYPE.getLabel());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void updateFilterByTypeIfRequired(JsonNode filter, String filterType) {
|
|
||||||
if (filter == null || filter.get("type") == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (filterType.equals(filter.get("type").asText())) {
|
|
||||||
if (filter.get(filterType) != null) {
|
|
||||||
ArrayNode arrayNode = JacksonUtil.OBJECT_MAPPER.createArrayNode();
|
|
||||||
arrayNode.add(filter.get(filterType).asText());
|
|
||||||
((ObjectNode) filter).set(filterType + "s", arrayNode);
|
|
||||||
((ObjectNode) filter).remove(filterType);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,8 @@
|
|||||||
package org.thingsboard.server.controller;
|
package org.thingsboard.server.controller;
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import com.google.common.util.concurrent.FutureCallback;
|
import com.google.common.util.concurrent.FutureCallback;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
@ -564,6 +566,34 @@ public abstract class BaseWebsocketApiTest extends AbstractControllerTest {
|
|||||||
assertThat(update.get("data").get("attr").get(0).get(1).asText()).isEqualTo(expectedAttrValue);
|
assertThat(update.get("data").get("attr").get(0).get(1).asText()).isEqualTo(expectedAttrValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEntityCountCmd_filterTypeSingularCompatibilityTest() {
|
||||||
|
ObjectNode oldFormatDeviceTypeFilterSingular = JacksonUtil.OBJECT_MAPPER.createObjectNode();
|
||||||
|
oldFormatDeviceTypeFilterSingular.put("type", "deviceType");
|
||||||
|
oldFormatDeviceTypeFilterSingular.put("deviceType", "default");
|
||||||
|
oldFormatDeviceTypeFilterSingular.put("deviceNameFilter", "Device");
|
||||||
|
|
||||||
|
ObjectNode query = JacksonUtil.OBJECT_MAPPER.createObjectNode();
|
||||||
|
query.set("entityFilter", oldFormatDeviceTypeFilterSingular);
|
||||||
|
|
||||||
|
ObjectNode entityCountCmd = JacksonUtil.OBJECT_MAPPER.createObjectNode();
|
||||||
|
entityCountCmd.put("cmdId", 1);
|
||||||
|
entityCountCmd.set("query", query);
|
||||||
|
|
||||||
|
ArrayNode entityCountCmds = JacksonUtil.OBJECT_MAPPER.createArrayNode();
|
||||||
|
entityCountCmds.add(entityCountCmd);
|
||||||
|
|
||||||
|
ObjectNode wrapperNode = JacksonUtil.OBJECT_MAPPER.createObjectNode();
|
||||||
|
wrapperNode.set("entityCountCmds", entityCountCmds);
|
||||||
|
|
||||||
|
getWsClient().send(JacksonUtil.toString(wrapperNode));
|
||||||
|
|
||||||
|
EntityCountUpdate update = getWsClient().parseCountReply(getWsClient().waitForReply());
|
||||||
|
Assert.assertEquals(1, update.getCmdId());
|
||||||
|
Assert.assertEquals(1, update.getCount());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void sendTelemetry(Device device, List<TsKvEntry> tsData) throws InterruptedException {
|
private void sendTelemetry(Device device, List<TsKvEntry> tsData) throws InterruptedException {
|
||||||
CountDownLatch latch = new CountDownLatch(1);
|
CountDownLatch latch = new CountDownLatch(1);
|
||||||
tsService.saveAndNotify(device.getTenantId(), null, device.getId(), tsData, 0, new FutureCallback<Void>() {
|
tsService.saveAndNotify(device.getTenantId(), null, device.getId(), tsData, 0, new FutureCallback<Void>() {
|
||||||
|
|||||||
@ -29,7 +29,6 @@ public class AssetTypeFilter implements EntityFilter {
|
|||||||
@Deprecated(since = "3.5", forRemoval = true)
|
@Deprecated(since = "3.5", forRemoval = true)
|
||||||
private String assetType;
|
private String assetType;
|
||||||
|
|
||||||
@JsonIgnore
|
|
||||||
private List<String> assetTypes;
|
private List<String> assetTypes;
|
||||||
|
|
||||||
private String assetNameFilter;
|
private String assetNameFilter;
|
||||||
|
|||||||
@ -33,7 +33,6 @@ public class DeviceTypeFilter implements EntityFilter {
|
|||||||
@Deprecated(since = "3.5", forRemoval = true)
|
@Deprecated(since = "3.5", forRemoval = true)
|
||||||
private String deviceType;
|
private String deviceType;
|
||||||
|
|
||||||
@JsonIgnore
|
|
||||||
private List<String> deviceTypes;
|
private List<String> deviceTypes;
|
||||||
|
|
||||||
private String deviceNameFilter;
|
private String deviceNameFilter;
|
||||||
|
|||||||
@ -29,7 +29,6 @@ public class EdgeTypeFilter implements EntityFilter {
|
|||||||
@Deprecated(since = "3.5", forRemoval = true)
|
@Deprecated(since = "3.5", forRemoval = true)
|
||||||
private String edgeType;
|
private String edgeType;
|
||||||
|
|
||||||
@JsonIgnore
|
|
||||||
private List<String> edgeTypes;
|
private List<String> edgeTypes;
|
||||||
|
|
||||||
private String edgeNameFilter;
|
private String edgeNameFilter;
|
||||||
|
|||||||
@ -29,7 +29,6 @@ public class EntityViewTypeFilter implements EntityFilter {
|
|||||||
@Deprecated(since = "3.5", forRemoval = true)
|
@Deprecated(since = "3.5", forRemoval = true)
|
||||||
private String entityViewType;
|
private String entityViewType;
|
||||||
|
|
||||||
@JsonIgnore
|
|
||||||
private List<String> entityViewTypes;
|
private List<String> entityViewTypes;
|
||||||
|
|
||||||
private String entityViewNameFilter;
|
private String entityViewNameFilter;
|
||||||
|
|||||||
@ -15,12 +15,16 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.dao.dashboard;
|
package org.thingsboard.server.dao.dashboard;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.hibernate.exception.ConstraintViolationException;
|
import org.hibernate.exception.ConstraintViolationException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.thingsboard.common.util.JacksonUtil;
|
||||||
import org.thingsboard.server.common.data.Customer;
|
import org.thingsboard.server.common.data.Customer;
|
||||||
import org.thingsboard.server.common.data.Dashboard;
|
import org.thingsboard.server.common.data.Dashboard;
|
||||||
import org.thingsboard.server.common.data.DashboardInfo;
|
import org.thingsboard.server.common.data.DashboardInfo;
|
||||||
@ -34,6 +38,7 @@ import org.thingsboard.server.common.data.id.HasId;
|
|||||||
import org.thingsboard.server.common.data.id.TenantId;
|
import org.thingsboard.server.common.data.id.TenantId;
|
||||||
import org.thingsboard.server.common.data.page.PageData;
|
import org.thingsboard.server.common.data.page.PageData;
|
||||||
import org.thingsboard.server.common.data.page.PageLink;
|
import org.thingsboard.server.common.data.page.PageLink;
|
||||||
|
import org.thingsboard.server.common.data.query.EntityFilterType;
|
||||||
import org.thingsboard.server.common.data.relation.EntityRelation;
|
import org.thingsboard.server.common.data.relation.EntityRelation;
|
||||||
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
|
||||||
import org.thingsboard.server.dao.customer.CustomerDao;
|
import org.thingsboard.server.dao.customer.CustomerDao;
|
||||||
@ -103,6 +108,9 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
|
|||||||
log.trace("Executing saveDashboard [{}]", dashboard);
|
log.trace("Executing saveDashboard [{}]", dashboard);
|
||||||
dashboardValidator.validate(dashboard, DashboardInfo::getTenantId);
|
dashboardValidator.validate(dashboard, DashboardInfo::getTenantId);
|
||||||
try {
|
try {
|
||||||
|
for (JsonNode entityAlias : dashboard.getEntityAliasesConfig()) {
|
||||||
|
updateDashboardFilterIfRequired(entityAlias);
|
||||||
|
}
|
||||||
return dashboardDao.save(dashboard.getTenantId(), dashboard);
|
return dashboardDao.save(dashboard.getTenantId(), dashboard);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
checkConstraintViolation(e, "dashboard_external_id_unq_key", "Dashboard with such external id already exists!");
|
checkConstraintViolation(e, "dashboard_external_id_unq_key", "Dashboard with such external id already exists!");
|
||||||
@ -110,6 +118,30 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void updateDashboardFilterIfRequired(JsonNode entityAlias) {
|
||||||
|
JsonNode filter = entityAlias.get("filter");
|
||||||
|
if (filter == null || filter.get("type") == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
updateFilterByTypeIfRequired(filter, EntityFilterType.ASSET_TYPE.getLabel());
|
||||||
|
updateFilterByTypeIfRequired(filter, EntityFilterType.DEVICE_TYPE.getLabel());
|
||||||
|
updateFilterByTypeIfRequired(filter, EntityFilterType.ENTITY_VIEW_TYPE.getLabel());
|
||||||
|
updateFilterByTypeIfRequired(filter, EntityFilterType.EDGE_TYPE.getLabel());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateFilterByTypeIfRequired(JsonNode filter, String FILTER_TYPE_SINGULAR_LABEL) {
|
||||||
|
if (filter.get(FILTER_TYPE_SINGULAR_LABEL) == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (FILTER_TYPE_SINGULAR_LABEL.equals(filter.get("type").asText())) {
|
||||||
|
ArrayNode filterTypes = JacksonUtil.OBJECT_MAPPER.createArrayNode();
|
||||||
|
filterTypes.add(filter.get(FILTER_TYPE_SINGULAR_LABEL).asText());
|
||||||
|
final String FILTER_TYPES_PLURAL_LABEL = String.format("%ss", FILTER_TYPE_SINGULAR_LABEL);
|
||||||
|
((ObjectNode) filter).set(FILTER_TYPES_PLURAL_LABEL, filterTypes);
|
||||||
|
((ObjectNode) filter).remove(FILTER_TYPE_SINGULAR_LABEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dashboard assignDashboardToCustomer(TenantId tenantId, DashboardId dashboardId, CustomerId customerId) {
|
public Dashboard assignDashboardToCustomer(TenantId tenantId, DashboardId dashboardId, CustomerId customerId) {
|
||||||
Dashboard dashboard = findDashboardById(tenantId, dashboardId);
|
Dashboard dashboard = findDashboardById(tenantId, dashboardId);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user