diff --git a/application/src/main/data/upgrade/3.5.0/schema_update.sql b/application/src/main/data/upgrade/3.5.0/schema_update.sql new file mode 100644 index 0000000000..09ce186811 --- /dev/null +++ b/application/src/main/data/upgrade/3.5.0/schema_update.sql @@ -0,0 +1,17 @@ +-- +-- Copyright © 2016-2023 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. +-- + +ALTER TABLE notification_rule ADD COLUMN IF NOT EXISTS enabled BOOLEAN NOT NULL DEFAULT true; diff --git a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java index 515c635e68..e0190bb388 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java +++ b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.actors; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; @@ -29,6 +28,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.MailService; import org.thingsboard.rule.engine.api.NotificationCenter; import org.thingsboard.rule.engine.api.SmsService; @@ -150,8 +150,6 @@ public class ActorSystemContext { } }; - protected final ObjectMapper mapper = new ObjectMapper(); - private final ConcurrentMap debugPerTenantLimits = new ConcurrentHashMap<>(); public ConcurrentMap getDebugPerTenantLimits() { @@ -646,7 +644,7 @@ public class ActorSystemContext { .dataType(tbMsg.getDataType().name()) .relationType(relationType) .data(tbMsg.getData()) - .metadata(mapper.writeValueAsString(tbMsg.getMetaData().getData())); + .metadata(JacksonUtil.toString(tbMsg.getMetaData().getData())); if (error != null) { event.error(toString(error)); @@ -656,7 +654,7 @@ public class ActorSystemContext { ListenableFuture future = eventService.saveAsync(event.build()); Futures.addCallback(future, RULE_NODE_DEBUG_EVENT_ERROR_CALLBACK, MoreExecutors.directExecutor()); - } catch (IOException ex) { + } catch (IllegalArgumentException ex) { log.warn("Failed to persist rule node debug message", ex); } } diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java index b8c890b75e..934f309480 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java @@ -815,7 +815,7 @@ public class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcesso } private ListenableFuture saveRpcRequestToEdgeQueue(ToDeviceRpcRequest msg, Integer requestId) { - ObjectNode body = mapper.createObjectNode(); + ObjectNode body = JacksonUtil.newObjectNode(); body.put("requestId", requestId); body.put("requestUUID", msg.getId().toString()); body.put("oneway", msg.isOneway()); diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java index 59d633540e..8b76924d96 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java +++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java @@ -16,7 +16,6 @@ package org.thingsboard.server.actors.ruleChain; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import io.netty.channel.EventLoopGroup; @@ -121,8 +120,6 @@ import java.util.function.Consumer; @Slf4j class DefaultTbContext implements TbContext { - public final static ObjectMapper mapper = new ObjectMapper(); - private final ActorSystemContext mainCtx; private final String ruleChainName; private final RuleNodeCtx nodeCtx; @@ -422,8 +419,8 @@ class DefaultTbContext implements TbContext { public TbMsg entityActionMsg(E entity, I id, RuleNodeId ruleNodeId, String action, K profile) { try { - return entityActionMsg(id, getActionMetaData(ruleNodeId), mapper.writeValueAsString(mapper.valueToTree(entity)), action, profile); - } catch (JsonProcessingException | IllegalArgumentException e) { + return entityActionMsg(id, getActionMetaData(ruleNodeId), JacksonUtil.toString(JacksonUtil.valueToTree(entity)), action, profile); + } catch (IllegalArgumentException e) { throw new RuntimeException("Failed to process " + id.getEntityType().name().toLowerCase() + " " + action + " msg: " + e); } } diff --git a/application/src/main/java/org/thingsboard/server/actors/shared/AbstractContextAwareMsgProcessor.java b/application/src/main/java/org/thingsboard/server/actors/shared/AbstractContextAwareMsgProcessor.java index e0c11102bf..395b8a24d0 100644 --- a/application/src/main/java/org/thingsboard/server/actors/shared/AbstractContextAwareMsgProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/shared/AbstractContextAwareMsgProcessor.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.actors.shared; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.TbActorCtx; @@ -26,8 +25,6 @@ import java.util.concurrent.ScheduledExecutorService; @Slf4j public abstract class AbstractContextAwareMsgProcessor { - protected final static ObjectMapper mapper = new ObjectMapper(); - protected final ActorSystemContext systemContext; protected AbstractContextAwareMsgProcessor(ActorSystemContext systemContext) { diff --git a/application/src/main/java/org/thingsboard/server/actors/stats/StatsActor.java b/application/src/main/java/org/thingsboard/server/actors/stats/StatsActor.java index 34fbecb4b5..ed0892f772 100644 --- a/application/src/main/java/org/thingsboard/server/actors/stats/StatsActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/stats/StatsActor.java @@ -16,8 +16,8 @@ package org.thingsboard.server.actors.stats; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.actors.TbActor; import org.thingsboard.server.actors.TbActorId; @@ -31,8 +31,6 @@ import org.thingsboard.server.common.msg.TbActorMsg; @Slf4j public class StatsActor extends ContextAwareActor { - private final ObjectMapper mapper = new ObjectMapper(); - public StatsActor(ActorSystemContext context) { super(context); } @@ -63,7 +61,7 @@ public class StatsActor extends ContextAwareActor { } private JsonNode toBodyJson(String serviceId, long messagesProcessed, long errorsOccurred) { - return mapper.createObjectNode().put("server", serviceId).put("messagesProcessed", messagesProcessed).put("errorsOccurred", errorsOccurred); + return JacksonUtil.newObjectNode().put("server", serviceId).put("messagesProcessed", messagesProcessed).put("errorsOccurred", errorsOccurred); } public static class ActorCreator extends ContextBasedCreator { diff --git a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java index 568c08ec56..4415f1a0bf 100644 --- a/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java +++ b/application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java @@ -87,6 +87,8 @@ import static springfox.documentation.builders.PathSelectors.regex; @Profile("!test") public class SwaggerConfiguration { + @Value("${swagger.enabled:true}") + private boolean enabled; @Value("${swagger.api_path_regex}") private String apiPathRegex; @Value("${swagger.security_path_regex}") @@ -116,6 +118,7 @@ public class SwaggerConfiguration { public Docket thingsboardApi() { TypeResolver typeResolver = new TypeResolver(); return new Docket(DocumentationType.OAS_30) + .enable(enabled) .groupName("thingsboard") .apiInfo(apiInfo()) .additionalModels( diff --git a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java index 9405d2da84..a418dc268b 100644 --- a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java +++ b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.config; -import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -116,20 +115,18 @@ public class ThingsboardSecurityConfiguration { @Autowired private AuthenticationManager authenticationManager; - @Autowired private ObjectMapper objectMapper; - @Autowired private RateLimitProcessingFilter rateLimitProcessingFilter; @Bean protected RestLoginProcessingFilter buildRestLoginProcessingFilter() throws Exception { - RestLoginProcessingFilter filter = new RestLoginProcessingFilter(FORM_BASED_LOGIN_ENTRY_POINT, successHandler, failureHandler, objectMapper); + RestLoginProcessingFilter filter = new RestLoginProcessingFilter(FORM_BASED_LOGIN_ENTRY_POINT, successHandler, failureHandler); filter.setAuthenticationManager(this.authenticationManager); return filter; } @Bean protected RestPublicLoginProcessingFilter buildRestPublicLoginProcessingFilter() throws Exception { - RestPublicLoginProcessingFilter filter = new RestPublicLoginProcessingFilter(PUBLIC_LOGIN_ENTRY_POINT, successHandler, failureHandler, objectMapper); + RestPublicLoginProcessingFilter filter = new RestPublicLoginProcessingFilter(PUBLIC_LOGIN_ENTRY_POINT, successHandler, failureHandler); filter.setAuthenticationManager(this.authenticationManager); return filter; } @@ -147,7 +144,7 @@ public class ThingsboardSecurityConfiguration { @Bean protected RefreshTokenProcessingFilter buildRefreshTokenProcessingFilter() throws Exception { - RefreshTokenProcessingFilter filter = new RefreshTokenProcessingFilter(TOKEN_REFRESH_ENTRY_POINT, successHandler, failureHandler, objectMapper); + RefreshTokenProcessingFilter filter = new RefreshTokenProcessingFilter(TOKEN_REFRESH_ENTRY_POINT, successHandler, failureHandler); filter.setAuthenticationManager(this.authenticationManager); return filter; } diff --git a/application/src/main/java/org/thingsboard/server/controller/AdminController.java b/application/src/main/java/org/thingsboard/server/controller/AdminController.java index dfefa9c755..5cf97a7cda 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AdminController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AdminController.java @@ -42,6 +42,7 @@ import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.FeaturesInfo; import org.thingsboard.server.common.data.SystemInfo; import org.thingsboard.server.common.data.UpdateMessage; +import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.security.model.JwtPair; @@ -52,6 +53,7 @@ import org.thingsboard.server.common.data.sync.vc.AutoCommitSettings; import org.thingsboard.server.common.data.sync.vc.RepositorySettings; import org.thingsboard.server.common.data.sync.vc.RepositorySettingsInfo; import org.thingsboard.server.common.data.sync.vc.VcUtils; +import org.thingsboard.server.dao.audit.AuditLogService; import org.thingsboard.server.dao.settings.AdminSettingsService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.auth.jwt.settings.JwtSettingsService; @@ -86,6 +88,7 @@ public class AdminController extends BaseController { private final TbAutoCommitSettingsService autoCommitSettingsService; private final UpdateService updateService; private final SystemInfoService systemInfoService; + private final AuditLogService auditLogService; @ApiOperation(value = "Get the Administration Settings object using key (getAdminSettings)", notes = "Get the Administration Settings object using specified string key. Referencing non-existing key will cause an error." + SYSTEM_AUTHORITY_PARAGRAPH) @@ -202,8 +205,15 @@ public class AdminController extends BaseController { public void sendTestSms( @ApiParam(value = "A JSON value representing the Test SMS request.") @RequestBody TestSmsRequest testSmsRequest) throws ThingsboardException { - accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); - smsService.sendTestSms(testSmsRequest); + SecurityUser user = getCurrentUser(); + accessControlService.checkPermission(user, Resource.ADMIN_SETTINGS, Operation.READ); + try { + smsService.sendTestSms(testSmsRequest); + auditLogService.logEntityAction(user.getTenantId(), user.getCustomerId(), user.getId(), user.getName(), user.getId(), user, ActionType.SMS_SENT, null, testSmsRequest.getNumberTo()); + } catch (ThingsboardException e) { + auditLogService.logEntityAction(user.getTenantId(), user.getCustomerId(), user.getId(), user.getName(), user.getId(), user, ActionType.SMS_SENT, e, testSmsRequest.getNumberTo()); + throw e; + } } @ApiOperation(value = "Get repository settings (getRepositorySettings)", diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index 5104fe9d32..68a987a0bc 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.controller; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; @@ -185,8 +184,6 @@ public abstract class BaseController { /*Swagger UI description*/ - private static final ObjectMapper json = new ObjectMapper(); - @Autowired private ThingsboardErrorResponseHandler errorResponseHandler; diff --git a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java index 8156c72a41..dd904add2e 100644 --- a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java +++ b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java @@ -16,7 +16,6 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -31,6 +30,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.CustomerId; @@ -100,8 +100,7 @@ public class CustomerController extends BaseController { checkParameter(CUSTOMER_ID, strCustomerId); CustomerId customerId = new CustomerId(toUUID(strCustomerId)); Customer customer = checkCustomerId(customerId, Operation.READ); - ObjectMapper objectMapper = new ObjectMapper(); - ObjectNode infoObject = objectMapper.createObjectNode(); + ObjectNode infoObject = JacksonUtil.newObjectNode(); infoObject.put("title", customer.getTitle()); infoObject.put(IS_PUBLIC, customer.isPublic()); return infoObject; diff --git a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java index d4e5169e7e..afc737ab88 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java @@ -528,7 +528,7 @@ public class DashboardController extends BaseController { Tenant tenant = tenantService.findTenantById(getTenantId()); JsonNode additionalInfo = tenant.getAdditionalInfo(); if (additionalInfo == null || !(additionalInfo instanceof ObjectNode)) { - additionalInfo = JacksonUtil.OBJECT_MAPPER.createObjectNode(); + additionalInfo = JacksonUtil.newObjectNode(); } if (homeDashboardInfo.getDashboardId() != null) { ((ObjectNode) additionalInfo).put(HOME_DASHBOARD_ID, homeDashboardInfo.getDashboardId().getId().toString()); diff --git a/application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java b/application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java index ae1dec43fe..8949cd95dd 100644 --- a/application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java +++ b/application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.controller; -import com.fasterxml.jackson.databind.ObjectMapper; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.extern.slf4j.Slf4j; @@ -28,6 +27,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.SaveDeviceWithCredentialsRequest; import org.thingsboard.server.common.data.device.profile.lwm2m.bootstrap.LwM2MServerSecurityConfigDefault; @@ -72,9 +72,8 @@ public class Lwm2mController extends BaseController { @RequestMapping(value = "/lwm2m/device-credentials", method = RequestMethod.POST) @ResponseBody public Device saveDeviceWithCredentials(@RequestBody Map, Object> deviceWithDeviceCredentials) throws ThingsboardException { - ObjectMapper mapper = new ObjectMapper(); - Device device = checkNotNull(mapper.convertValue(deviceWithDeviceCredentials.get(Device.class), Device.class)); - DeviceCredentials credentials = checkNotNull(mapper.convertValue(deviceWithDeviceCredentials.get(DeviceCredentials.class), DeviceCredentials.class)); + Device device = checkNotNull(JacksonUtil.convertValue(deviceWithDeviceCredentials.get(Device.class), Device.class)); + DeviceCredentials credentials = checkNotNull(JacksonUtil.convertValue(deviceWithDeviceCredentials.get(DeviceCredentials.class), DeviceCredentials.class)); return deviceController.saveDeviceWithCredentials(new SaveDeviceWithCredentialsRequest(device, credentials)); } } diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java index 81cf8be9fa..50abb3de1d 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java @@ -18,7 +18,6 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import io.swagger.annotations.ApiOperation; @@ -37,6 +36,7 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.ScriptEngine; import org.thingsboard.script.api.js.JsInvokeService; import org.thingsboard.script.api.tbel.TbelInvokeService; @@ -115,7 +115,6 @@ public class RuleChainController extends BaseController { private static final int DEFAULT_PAGE_SIZE = 1000; - private static final ObjectMapper objectMapper = new ObjectMapper(); public static final int TIMEOUT = 20; private static final String RULE_CHAIN_DESCRIPTION = "The rule chain object is lightweight and contains general information about the rule chain. " + @@ -377,11 +376,11 @@ public class RuleChainController extends BaseController { String script = inputParams.get("script").asText(); String scriptType = inputParams.get("scriptType").asText(); JsonNode argNamesJson = inputParams.get("argNames"); - String[] argNames = objectMapper.treeToValue(argNamesJson, String[].class); + String[] argNames = JacksonUtil.treeToValue(argNamesJson, String[].class); String data = inputParams.get("msg").asText(); JsonNode metadataJson = inputParams.get("metadata"); - Map metadata = objectMapper.convertValue(metadataJson, new TypeReference>() { + Map metadata = JacksonUtil.convertValue(metadataJson, new TypeReference>() { }); String msgType = inputParams.get("msgType").asText(); String output = ""; @@ -413,11 +412,11 @@ public class RuleChainController extends BaseController { break; case "switch": Set states = engine.executeSwitchAsync(inMsg).get(TIMEOUT, TimeUnit.SECONDS); - output = objectMapper.writeValueAsString(states); + output = JacksonUtil.toString(states); break; case "json": JsonNode json = engine.executeJsonAsync(inMsg).get(TIMEOUT, TimeUnit.SECONDS); - output = objectMapper.writeValueAsString(json); + output = JacksonUtil.toString(json); break; case "string": output = engine.executeToStringAsync(inMsg).get(TIMEOUT, TimeUnit.SECONDS); @@ -433,7 +432,7 @@ public class RuleChainController extends BaseController { engine.destroy(); } } - ObjectNode result = objectMapper.createObjectNode(); + ObjectNode result = JacksonUtil.newObjectNode(); result.put("output", output); result.put("error", errorText); return result; @@ -473,13 +472,13 @@ public class RuleChainController extends BaseController { private String msgToOutput(TbMsg msg) throws Exception { JsonNode resultNode = convertMsgToOut(msg); - return objectMapper.writeValueAsString(resultNode); + return JacksonUtil.toString(resultNode); } private String msgToOutput(List msgs) throws Exception { JsonNode resultNode; if (msgs.size() > 1) { - resultNode = objectMapper.createArrayNode(); + resultNode = JacksonUtil.newArrayNode(); for (TbMsg msg : msgs) { JsonNode convertedData = convertMsgToOut(msg); ((ArrayNode) resultNode).add(convertedData); @@ -487,16 +486,16 @@ public class RuleChainController extends BaseController { } else { resultNode = convertMsgToOut(msgs.get(0)); } - return objectMapper.writeValueAsString(resultNode); + return JacksonUtil.toString(resultNode); } private JsonNode convertMsgToOut(TbMsg msg) throws Exception { - ObjectNode msgData = objectMapper.createObjectNode(); + ObjectNode msgData = JacksonUtil.newObjectNode(); if (!StringUtils.isEmpty(msg.getData())) { - msgData.set("msg", objectMapper.readTree(msg.getData())); + msgData.set("msg", JacksonUtil.toJsonNode(msg.getData())); } Map metadata = msg.getMetaData().getData(); - msgData.set("metadata", objectMapper.valueToTree(metadata)); + msgData.set("metadata", JacksonUtil.valueToTree(metadata)); msgData.put("msgType", msg.getType()); return msgData; } diff --git a/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java b/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java index e586f079ca..3633cbbdeb 100644 --- a/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java +++ b/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java @@ -16,7 +16,6 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -142,8 +141,7 @@ public class SystemInfoController extends BaseController { } private JsonNode buildInfoObject() { - ObjectMapper objectMapper = new ObjectMapper(); - ObjectNode infoObject = objectMapper.createObjectNode(); + ObjectNode infoObject = JacksonUtil.newObjectNode(); if (buildProperties != null) { infoObject.put("version", buildProperties.getVersion()); infoObject.put("artifact", buildProperties.getArtifact()); diff --git a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java index 23331d95f4..737e6d54d5 100644 --- a/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java +++ b/application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java @@ -117,7 +117,7 @@ public class WidgetsBundleController extends BaseController { checkParameter("widgetsBundleId", strWidgetsBundleId); WidgetsBundleId widgetsBundleId = new WidgetsBundleId(toUUID(strWidgetsBundleId)); WidgetsBundle widgetsBundle = checkWidgetsBundleId(widgetsBundleId, Operation.DELETE); - tbWidgetsBundleService.delete(widgetsBundle); + tbWidgetsBundleService.delete(widgetsBundle, getCurrentUser()); } @ApiOperation(value = "Get Widget Bundles (getWidgetsBundles)", diff --git a/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java b/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java index 5f22786907..ed641c2d4f 100644 --- a/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java +++ b/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.exception; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; @@ -36,6 +35,7 @@ import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; import org.springframework.web.util.WebUtils; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.msg.tools.TbRateLimitsException; @@ -90,9 +90,6 @@ public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHand return errorCodeToStatusMap.getOrDefault(errorCode, HttpStatus.INTERNAL_SERVER_ERROR); } - @Autowired - private ObjectMapper mapper; - @Override @ExceptionHandler(AccessDeniedException.class) public void handle(HttpServletRequest request, HttpServletResponse response, @@ -101,7 +98,7 @@ public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHand if (!response.isCommitted()) { response.setContentType(MediaType.APPLICATION_JSON_VALUE); response.setStatus(HttpStatus.FORBIDDEN.value()); - mapper.writeValue(response.getWriter(), + JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of("You don't have permission to perform this operation!", ThingsboardErrorCode.PERMISSION_DENIED, HttpStatus.FORBIDDEN)); } @@ -129,7 +126,7 @@ public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHand handleAuthenticationException((AuthenticationException) exception, response); } else { response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); - mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of(exception.getMessage(), + JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of(exception.getMessage(), ThingsboardErrorCode.GENERAL, HttpStatus.INTERNAL_SERVER_ERROR)); } } catch (IOException e) { @@ -154,26 +151,26 @@ public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHand ThingsboardErrorCode errorCode = thingsboardException.getErrorCode(); HttpStatus status = errorCodeToStatus(errorCode); response.setStatus(status.value()); - mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of(thingsboardException.getMessage(), errorCode, status)); + JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of(thingsboardException.getMessage(), errorCode, status)); } private void handleRateLimitException(HttpServletResponse response, TbRateLimitsException exception) throws IOException { response.setStatus(HttpStatus.TOO_MANY_REQUESTS.value()); String message = "Too many requests for current " + exception.getEntityType().name().toLowerCase() + "!"; - mapper.writeValue(response.getWriter(), + JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of(message, ThingsboardErrorCode.TOO_MANY_REQUESTS, HttpStatus.TOO_MANY_REQUESTS)); } private void handleSubscriptionException(ThingsboardException subscriptionException, HttpServletResponse response) throws IOException { response.setStatus(HttpStatus.FORBIDDEN.value()); - mapper.writeValue(response.getWriter(), - (new ObjectMapper()).readValue(((HttpClientErrorException) subscriptionException.getCause()).getResponseBodyAsByteArray(), Object.class)); + JacksonUtil.writeValue(response.getWriter(), + JacksonUtil.fromBytes(((HttpClientErrorException) subscriptionException.getCause()).getResponseBodyAsByteArray(), Object.class)); } private void handleAccessDeniedException(HttpServletResponse response) throws IOException { response.setStatus(HttpStatus.FORBIDDEN.value()); - mapper.writeValue(response.getWriter(), + JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of("You don't have permission to perform this operation!", ThingsboardErrorCode.PERMISSION_DENIED, HttpStatus.FORBIDDEN)); @@ -182,21 +179,21 @@ public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHand private void handleAuthenticationException(AuthenticationException authenticationException, HttpServletResponse response) throws IOException { response.setStatus(HttpStatus.UNAUTHORIZED.value()); if (authenticationException instanceof BadCredentialsException || authenticationException instanceof UsernameNotFoundException) { - mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of("Invalid username or password", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); + JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of("Invalid username or password", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); } else if (authenticationException instanceof DisabledException) { - mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of("User account is not active", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); + JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of("User account is not active", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); } else if (authenticationException instanceof LockedException) { - mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of("User account is locked due to security policy", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); + JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of("User account is locked due to security policy", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); } else if (authenticationException instanceof JwtExpiredTokenException) { - mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of("Token has expired", ThingsboardErrorCode.JWT_TOKEN_EXPIRED, HttpStatus.UNAUTHORIZED)); + JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of("Token has expired", ThingsboardErrorCode.JWT_TOKEN_EXPIRED, HttpStatus.UNAUTHORIZED)); } else if (authenticationException instanceof AuthMethodNotSupportedException) { - mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of(authenticationException.getMessage(), ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); + JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of(authenticationException.getMessage(), ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); } else if (authenticationException instanceof UserPasswordExpiredException) { UserPasswordExpiredException expiredException = (UserPasswordExpiredException) authenticationException; String resetToken = expiredException.getResetToken(); - mapper.writeValue(response.getWriter(), ThingsboardCredentialsExpiredResponse.of(expiredException.getMessage(), resetToken)); + JacksonUtil.writeValue(response.getWriter(), ThingsboardCredentialsExpiredResponse.of(expiredException.getMessage(), resetToken)); } else { - mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of("Authentication failed", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); + JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of("Authentication failed", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); } } diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index ea13de3779..fc72c354ed 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -249,15 +249,19 @@ public class ThingsboardInstallService { case "3.4.4": log.info("Upgrading ThingsBoard from version 3.4.4 to 3.5.0 ..."); databaseEntitiesUpgradeService.upgradeDatabase("3.4.4"); - entityDatabaseSchemaService.createOrUpdateViewsAndFunctions(); - entityDatabaseSchemaService.createOrUpdateDeviceInfoView(persistToTelemetry); - log.info("Updating system data..."); - systemDataLoaderService.updateSystemWidgets(); if (!getEnv("SKIP_DEFAULT_NOTIFICATION_CONFIGS_CREATION", false)) { systemDataLoaderService.createDefaultNotificationConfigs(); } else { log.info("Skipping default notification configs creation"); } + case "3.5.0": + log.info("Upgrading ThingsBoard from version 3.5.0 to 3.5.1 ..."); + databaseEntitiesUpgradeService.upgradeDatabase("3.5.0"); + + entityDatabaseSchemaService.createOrUpdateViewsAndFunctions(); + entityDatabaseSchemaService.createOrUpdateDeviceInfoView(persistToTelemetry); + log.info("Updating system data..."); + systemDataLoaderService.updateSystemWidgets(); installScripts.loadSystemLwm2mResources(); break; //TODO update CacheCleanupService on the next version upgrade diff --git a/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java b/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java index 05e78e4060..623b95b40e 100644 --- a/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java +++ b/application/src/main/java/org/thingsboard/server/service/action/EntityActionService.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.action; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.RequiredArgsConstructor; @@ -58,8 +57,6 @@ public class EntityActionService { private final AuditLogService auditLogService; private final NotificationRuleProcessor notificationRuleProcessor; - private static final ObjectMapper json = new ObjectMapper(); - public void pushEntityActionToRuleEngine(EntityId entityId, HasName entity, TenantId tenantId, CustomerId customerId, ActionType actionType, User user, Object... additionalInfo) { String msgType = null; @@ -189,18 +186,18 @@ public class EntityActionService { metaData.putValue("unassignedEdgeName", strEdgeName); } else if (actionType == ActionType.ADDED_COMMENT || actionType == ActionType.UPDATED_COMMENT) { AlarmComment comment = extractParameter(AlarmComment.class, 0, additionalInfo); - metaData.putValue("comment", json.writeValueAsString(comment)); + metaData.putValue("comment", JacksonUtil.toString(comment)); } ObjectNode entityNode; if (entity != null) { - entityNode = json.valueToTree(entity); + entityNode = JacksonUtil.OBJECT_MAPPER.valueToTree(entity); if (entityId.getEntityType() == EntityType.DASHBOARD) { entityNode.put("configuration", ""); } metaData.putValue("entityName", entity.getName()); metaData.putValue("entityType", entityId.getEntityType().toString()); } else { - entityNode = json.createObjectNode(); + entityNode = JacksonUtil.newObjectNode(); if (actionType == ActionType.ATTRIBUTES_UPDATED) { String scope = extractParameter(String.class, 0, additionalInfo); @SuppressWarnings("unchecked") @@ -234,7 +231,7 @@ public class EntityActionService { entityNode.put("startTs", extractParameter(Long.class, 1, additionalInfo)); entityNode.put("endTs", extractParameter(Long.class, 2, additionalInfo)); } else if (ActionType.RELATION_ADD_OR_UPDATE.equals(actionType) || ActionType.RELATION_DELETED.equals(actionType)) { - entityNode = json.valueToTree(extractParameter(EntityRelation.class, 0, additionalInfo)); + entityNode = JacksonUtil.OBJECT_MAPPER.valueToTree(extractParameter(EntityRelation.class, 0, additionalInfo)); } } @@ -258,7 +255,7 @@ public class EntityActionService { .user(user) .build()); } - TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, customerId, metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode)); + TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, customerId, metaData, TbMsgDataType.JSON, JacksonUtil.toString(entityNode)); tbClusterService.pushMsgToRuleEngine(tenantId, entityId, tbMsg, null); } catch (Exception e) { log.warn("[{}] Failed to push entity action to rule engine: {}", entityId, actionType, e); @@ -298,7 +295,7 @@ public class EntityActionService { Map> groupedTelemetry = timeseries.stream() .collect(Collectors.groupingBy(TsKvEntry::getTs)); for (Map.Entry> entry : groupedTelemetry.entrySet()) { - ObjectNode element = json.createObjectNode(); + ObjectNode element = JacksonUtil.newObjectNode(); element.put("ts", entry.getKey()); ObjectNode values = element.putObject("values"); for (TsKvEntry tsKvEntry : entry.getValue()) { diff --git a/application/src/main/java/org/thingsboard/server/service/apiusage/TenantApiUsageState.java b/application/src/main/java/org/thingsboard/server/service/apiusage/TenantApiUsageState.java index fcba410bbd..2920331353 100644 --- a/application/src/main/java/org/thingsboard/server/service/apiusage/TenantApiUsageState.java +++ b/application/src/main/java/org/thingsboard/server/service/apiusage/TenantApiUsageState.java @@ -55,6 +55,10 @@ public class TenantApiUsageState extends BaseApiUsageState { return tenantProfileData.getConfiguration().getProfileThreshold(key); } + public boolean getProfileFeatureEnabled(ApiUsageRecordKey key) { + return tenantProfileData.getConfiguration().getProfileFeatureEnabled(key); + } + public long getProfileWarnThreshold(ApiUsageRecordKey key) { return tenantProfileData.getConfiguration().getWarnThreshold(key); } @@ -63,13 +67,18 @@ public class TenantApiUsageState extends BaseApiUsageState { ApiUsageStateValue featureValue = ApiUsageStateValue.ENABLED; for (ApiUsageRecordKey recordKey : ApiUsageRecordKey.getKeys(feature)) { long value = get(recordKey); - long threshold = getProfileThreshold(recordKey); - long warnThreshold = getProfileWarnThreshold(recordKey); + boolean featureEnabled = getProfileFeatureEnabled(recordKey); ApiUsageStateValue tmpValue; - if (threshold == 0 || value == 0 || value < warnThreshold) { - tmpValue = ApiUsageStateValue.ENABLED; - } else if (value < threshold) { - tmpValue = ApiUsageStateValue.WARNING; + if (featureEnabled) { + long threshold = getProfileThreshold(recordKey); + long warnThreshold = getProfileWarnThreshold(recordKey); + if (threshold == 0 || value == 0 || value < warnThreshold) { + tmpValue = ApiUsageStateValue.ENABLED; + } else if (value < threshold) { + tmpValue = ApiUsageStateValue.WARNING; + } else { + tmpValue = ApiUsageStateValue.DISABLED; + } } else { tmpValue = ApiUsageStateValue.DISABLED; } diff --git a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java index b425694e81..1f5e41aeed 100644 --- a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java +++ b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java @@ -16,7 +16,6 @@ package org.thingsboard.server.service.component; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -27,6 +26,7 @@ import org.springframework.core.env.Environment; import org.springframework.core.env.Profiles; import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.stereotype.Service; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.NodeConfiguration; import org.thingsboard.rule.engine.api.NodeDefinition; import org.thingsboard.rule.engine.api.RuleNode; @@ -69,8 +69,6 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe private Map> edgeComponentsMap = new HashMap<>(); - private ObjectMapper mapper = new ObjectMapper(); - private boolean isInstall() { return environment.acceptsProfiles(Profiles.of("install")); } @@ -157,8 +155,8 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe scannedComponent.setScope(ruleNodeAnnotation.scope()); scannedComponent.setClusteringMode(ruleNodeAnnotation.clusteringMode()); NodeDefinition nodeDefinition = prepareNodeDefinition(ruleNodeAnnotation); - ObjectNode configurationDescriptor = mapper.createObjectNode(); - JsonNode node = mapper.valueToTree(nodeDefinition); + ObjectNode configurationDescriptor = JacksonUtil.newObjectNode(); + JsonNode node = JacksonUtil.valueToTree(nodeDefinition); configurationDescriptor.set("nodeDefinition", node); scannedComponent.setConfigurationDescriptor(configurationDescriptor); scannedComponent.setClazz(clazzName); @@ -195,7 +193,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe Class configClazz = nodeAnnotation.configClazz(); NodeConfiguration config = configClazz.getDeclaredConstructor().newInstance(); NodeConfiguration defaultConfiguration = config.defaultConfiguration(); - nodeDefinition.setDefaultConfiguration(mapper.valueToTree(defaultConfiguration)); + nodeDefinition.setDefaultConfiguration(JacksonUtil.valueToTree(defaultConfiguration)); nodeDefinition.setUiResources(nodeAnnotation.uiResources()); nodeDefinition.setConfigDirective(nodeAnnotation.configDirective()); nodeDefinition.setIcon(nodeAnnotation.icon()); diff --git a/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java b/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java index 4000e5a09d..ebc0fd0d24 100644 --- a/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java +++ b/application/src/main/java/org/thingsboard/server/service/device/ClaimDevicesServiceImpl.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.device; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; @@ -67,7 +66,6 @@ public class ClaimDevicesServiceImpl implements ClaimDevicesService { private static final String CLAIM_ATTRIBUTE_NAME = "claimingAllowed"; private static final String CLAIM_DATA_ATTRIBUTE_NAME = "claimingData"; - private static final ObjectMapper mapper = new ObjectMapper(); @Autowired private TbClusterService clusterService; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java index e0bfe75793..110760acbc 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/DefaultEdgeNotificationService.java @@ -146,7 +146,7 @@ public class DefaultEdgeNotificationService implements EdgeNotificationService { public Edge setEdgeRootRuleChain(TenantId tenantId, Edge edge, RuleChainId ruleChainId) throws Exception { edge.setRootRuleChainId(ruleChainId); Edge savedEdge = edgeService.saveEdge(edge); - ObjectNode isRootBody = JacksonUtil.OBJECT_MAPPER.createObjectNode(); + ObjectNode isRootBody = JacksonUtil.newObjectNode(); isRootBody.put(EDGE_IS_ROOT_BODY_KEY, Boolean.TRUE); saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.RULE_CHAIN, EdgeEventActionType.UPDATED, ruleChainId, isRootBody).get(); return savedEdge; diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java index 5171a6037f..bda510a762 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/EdgeGrpcService.java @@ -445,7 +445,7 @@ public class EdgeGrpcService extends EdgeRpcServiceGrpc.EdgeRpcServiceImplBase i private void pushRuleEngineMessage(TenantId tenantId, EdgeId edgeId, long ts, String msgType) { try { - ObjectNode edgeState = JacksonUtil.OBJECT_MAPPER.createObjectNode(); + ObjectNode edgeState = JacksonUtil.newObjectNode(); if (msgType.equals(CONNECT_EVENT)) { edgeState.put(DefaultDeviceStateService.ACTIVITY_STATE, true); edgeState.put(DefaultDeviceStateService.LAST_CONNECT_TIME, ts); diff --git a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java index 64735b4925..2caa8fde3b 100644 --- a/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java +++ b/application/src/main/java/org/thingsboard/server/service/edge/rpc/fetch/RuleChainsEdgeEventFetcher.java @@ -45,7 +45,7 @@ public class RuleChainsEdgeEventFetcher extends BasePageableEdgeEventFetcher entityData = new HashMap<>(); - ObjectNode attributes = JacksonUtil.OBJECT_MAPPER.createObjectNode(); + ObjectNode attributes = JacksonUtil.newObjectNode(); for (AttributeKvEntry attr : ssAttributes) { if (DefaultDeviceStateService.PERSISTENT_ATTRIBUTES.contains(attr.getKey()) && !DefaultDeviceStateService.INACTIVITY_TIMEOUT.equals(attr.getKey())) { diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/DefaultWidgetsBundleService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/DefaultWidgetsBundleService.java index ffd667bfec..7cc150b746 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/DefaultWidgetsBundleService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/DefaultWidgetsBundleService.java @@ -17,9 +17,10 @@ package org.thingsboard.server.service.entitiy.widgets.bundle; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; +import org.thingsboard.server.common.data.EntityType; 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.audit.ActionType; +import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.widget.WidgetsBundle; import org.thingsboard.server.dao.widget.WidgetsBundleService; import org.thingsboard.server.queue.util.TbCoreComponent; @@ -34,17 +35,31 @@ public class DefaultWidgetsBundleService extends AbstractTbEntityService impleme @Override public WidgetsBundle save(WidgetsBundle widgetsBundle, User user) throws Exception { - WidgetsBundle savedWidgetsBundle = checkNotNull(widgetsBundleService.saveWidgetsBundle(widgetsBundle)); - autoCommit(user, savedWidgetsBundle.getId()); - notificationEntityService.notifySendMsgToEdgeService(widgetsBundle.getTenantId(), savedWidgetsBundle.getId(), - widgetsBundle.getId() == null ? EdgeEventActionType.ADDED : EdgeEventActionType.UPDATED); - return savedWidgetsBundle; + ActionType actionType = widgetsBundle.getId() == null ? ActionType.ADDED : ActionType.UPDATED; + TenantId tenantId = widgetsBundle.getTenantId(); + try { + WidgetsBundle savedWidgetsBundle = checkNotNull(widgetsBundleService.saveWidgetsBundle(widgetsBundle)); + autoCommit(user, savedWidgetsBundle.getId()); + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, savedWidgetsBundle.getId(), + savedWidgetsBundle, user, actionType, true, null); + return savedWidgetsBundle; + } catch (Exception e) { + notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.WIDGETS_BUNDLE), widgetsBundle, actionType, user, e); + throw e; + } } @Override - public void delete(WidgetsBundle widgetsBundle) throws ThingsboardException { - widgetsBundleService.deleteWidgetsBundle(widgetsBundle.getTenantId(), widgetsBundle.getId()); - notificationEntityService.notifySendMsgToEdgeService(widgetsBundle.getTenantId(), widgetsBundle.getId(), - EdgeEventActionType.DELETED); + public void delete(WidgetsBundle widgetsBundle, User user) { + TenantId tenantId = widgetsBundle.getTenantId(); + try { + widgetsBundleService.deleteWidgetsBundle(widgetsBundle.getTenantId(), widgetsBundle.getId()); + notificationEntityService.notifyCreateOrUpdateOrDelete(tenantId, null, widgetsBundle.getId(), widgetsBundle, + user, ActionType.DELETED, true, null); + } catch (Exception e) { + notificationEntityService.logEntityAction(tenantId, emptyId(EntityType.WIDGETS_BUNDLE), + ActionType.DELETED, user, e, widgetsBundle.getId()); + throw e; + } } } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/TbWidgetsBundleService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/TbWidgetsBundleService.java index 446010b61c..d60bc66d66 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/TbWidgetsBundleService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/widgets/bundle/TbWidgetsBundleService.java @@ -15,13 +15,8 @@ */ package org.thingsboard.server.service.entitiy.widgets.bundle; -import org.thingsboard.server.common.data.User; -import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.widget.WidgetsBundle; +import org.thingsboard.server.service.entitiy.SimpleTbEntityService; -public interface TbWidgetsBundleService { - - WidgetsBundle save(WidgetsBundle entity, User currentUser) throws Exception; - - void delete(WidgetsBundle entity) throws ThingsboardException; +public interface TbWidgetsBundleService extends SimpleTbEntityService { } diff --git a/application/src/main/java/org/thingsboard/server/service/install/DatabaseHelper.java b/application/src/main/java/org/thingsboard/server/service/install/DatabaseHelper.java index 70f161d2e2..97b87c7412 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/DatabaseHelper.java +++ b/application/src/main/java/org/thingsboard/server/service/install/DatabaseHelper.java @@ -16,10 +16,10 @@ package org.thingsboard.server.service.install; import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.csv.CSVFormat; import org.apache.commons.csv.CSVParser; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.ShortCustomerInfo; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.UUIDConverter; @@ -67,11 +67,10 @@ public class DatabaseHelper { public static final String ASSIGNED_CUSTOMERS = "assigned_customers"; public static final String CONFIGURATION = "configuration"; - public static final ObjectMapper objectMapper = new ObjectMapper(); public static void upgradeTo40_assignDashboards(Path dashboardsDump, DashboardService dashboardService, boolean sql) throws Exception { JavaType assignedCustomersType = - objectMapper.getTypeFactory().constructCollectionType(HashSet.class, ShortCustomerInfo.class); + JacksonUtil.constructCollectionType(HashSet.class, ShortCustomerInfo.class); try (CSVParser csvParser = new CSVParser(Files.newBufferedReader(dashboardsDump), CSV_DUMP_FORMAT.withFirstRecordAsHeader())) { csvParser.forEach(record -> { String customerIdString = record.get(CUSTOMER_ID); @@ -80,14 +79,14 @@ public class DatabaseHelper { List customerIds = new ArrayList<>(); if (!StringUtils.isEmpty(assignedCustomersString)) { try { - Set assignedCustomers = objectMapper.readValue(assignedCustomersString, assignedCustomersType); + Set assignedCustomers = JacksonUtil.fromString(assignedCustomersString, assignedCustomersType); assignedCustomers.forEach((customerInfo) -> { CustomerId customerId = customerInfo.getCustomerId(); if (!customerId.isNullUid()) { customerIds.add(customerId); } }); - } catch (IOException e) { + } catch (IllegalArgumentException e) { log.error("Unable to parse assigned customers field", e); } } diff --git a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java index 4952b486db..497627f629 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.install; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.FutureCallback; import com.google.common.util.concurrent.Futures; @@ -30,6 +29,7 @@ import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Profile; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Service; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.Customer; @@ -119,7 +119,6 @@ import java.util.concurrent.atomic.AtomicInteger; @Slf4j public class DefaultSystemDataLoaderService implements SystemDataLoaderService { - private static final ObjectMapper objectMapper = new ObjectMapper(); public static final String CUSTOMER_CRED = "customer"; public static final String DEFAULT_DEVICE_TYPE = "default"; public static final String ACTIVITY_STATE = "active"; @@ -254,7 +253,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { AdminSettings generalSettings = new AdminSettings(); generalSettings.setTenantId(TenantId.SYS_TENANT_ID); generalSettings.setKey("general"); - ObjectNode node = objectMapper.createObjectNode(); + ObjectNode node = JacksonUtil.newObjectNode(); node.put("baseUrl", "http://localhost:8080"); node.put("prohibitDifferentUrl", false); generalSettings.setJsonValue(node); @@ -263,7 +262,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { AdminSettings mailSettings = new AdminSettings(); mailSettings.setTenantId(TenantId.SYS_TENANT_ID); mailSettings.setKey("mail"); - node = objectMapper.createObjectNode(); + node = JacksonUtil.newObjectNode(); node.put("mailFrom", "ThingsBoard "); node.put("smtpProtocol", "smtp"); node.put("smtpHost", "localhost"); @@ -546,7 +545,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { device.setDeviceProfileId(deviceProfileId); device.setName(name); if (description != null) { - ObjectNode additionalInfo = objectMapper.createObjectNode(); + ObjectNode additionalInfo = JacksonUtil.newObjectNode(); additionalInfo.put("description", description); device.setAdditionalInfo(additionalInfo); } diff --git a/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java b/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java index 5ab7324192..9a810aa446 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java +++ b/application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java @@ -20,6 +20,7 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.StringUtils; @@ -48,7 +49,6 @@ import java.nio.file.Paths; import java.util.Base64; import java.util.Optional; -import static org.thingsboard.server.service.install.DatabaseHelper.objectMapper; import static org.thingsboard.server.utils.LwM2mObjectModelUtils.toLwm2mResource; /** @@ -162,9 +162,9 @@ public class InstallScripts { } public RuleChain createRuleChainFromFile(TenantId tenantId, Path templateFilePath, String newRuleChainName) throws IOException { - JsonNode ruleChainJson = objectMapper.readTree(templateFilePath.toFile()); - RuleChain ruleChain = objectMapper.treeToValue(ruleChainJson.get("ruleChain"), RuleChain.class); - RuleChainMetaData ruleChainMetaData = objectMapper.treeToValue(ruleChainJson.get("metadata"), RuleChainMetaData.class); + JsonNode ruleChainJson = JacksonUtil.toJsonNode(templateFilePath.toFile()); + RuleChain ruleChain = JacksonUtil.treeToValue(ruleChainJson.get("ruleChain"), RuleChain.class); + RuleChainMetaData ruleChainMetaData = JacksonUtil.treeToValue(ruleChainJson.get("metadata"), RuleChainMetaData.class); ruleChain.setTenantId(tenantId); if (!StringUtils.isEmpty(newRuleChainName)) { @@ -184,15 +184,15 @@ public class InstallScripts { dirStream.forEach( path -> { try { - JsonNode widgetsBundleDescriptorJson = objectMapper.readTree(path.toFile()); + JsonNode widgetsBundleDescriptorJson = JacksonUtil.toJsonNode(path.toFile()); JsonNode widgetsBundleJson = widgetsBundleDescriptorJson.get("widgetsBundle"); - WidgetsBundle widgetsBundle = objectMapper.treeToValue(widgetsBundleJson, WidgetsBundle.class); + WidgetsBundle widgetsBundle = JacksonUtil.treeToValue(widgetsBundleJson, WidgetsBundle.class); WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); JsonNode widgetTypesArrayJson = widgetsBundleDescriptorJson.get("widgetTypes"); widgetTypesArrayJson.forEach( widgetTypeJson -> { try { - WidgetTypeDetails widgetTypeDetails = objectMapper.treeToValue(widgetTypeJson, WidgetTypeDetails.class); + WidgetTypeDetails widgetTypeDetails = JacksonUtil.treeToValue(widgetTypeJson, WidgetTypeDetails.class); widgetTypeDetails.setBundleAlias(savedWidgetsBundle.getAlias()); widgetTypeService.saveWidgetType(widgetTypeDetails); } catch (Exception e) { @@ -216,8 +216,8 @@ public class InstallScripts { dirStream.forEach( path -> { try { - JsonNode dashboardJson = objectMapper.readTree(path.toFile()); - Dashboard dashboard = objectMapper.treeToValue(dashboardJson, Dashboard.class); + JsonNode dashboardJson = JacksonUtil.toJsonNode(path.toFile()); + Dashboard dashboard = JacksonUtil.treeToValue(dashboardJson, Dashboard.class); dashboard.setTenantId(tenantId); Dashboard savedDashboard = dashboardService.saveDashboard(dashboard); if (customerId != null && !customerId.isNullUid()) { @@ -249,8 +249,8 @@ public class InstallScripts { dirStream.forEach( path -> { try { - JsonNode oauth2ConfigTemplateJson = objectMapper.readTree(path.toFile()); - OAuth2ClientRegistrationTemplate clientRegistrationTemplate = objectMapper.treeToValue(oauth2ConfigTemplateJson, OAuth2ClientRegistrationTemplate.class); + JsonNode oauth2ConfigTemplateJson = JacksonUtil.toJsonNode(path.toFile()); + OAuth2ClientRegistrationTemplate clientRegistrationTemplate = JacksonUtil.treeToValue(oauth2ConfigTemplateJson, OAuth2ClientRegistrationTemplate.class); Optional existingClientRegistrationTemplate = oAuth2TemplateService.findClientRegistrationTemplateByProviderId(clientRegistrationTemplate.getProviderId()); if (existingClientRegistrationTemplate.isPresent()) { diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java index 504b058879..38b3fc60e6 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java @@ -46,6 +46,7 @@ import org.thingsboard.server.dao.tenant.TenantService; import org.thingsboard.server.dao.usagerecord.ApiUsageStateService; import org.thingsboard.server.queue.settings.TbRuleEngineQueueConfiguration; import org.thingsboard.server.service.install.sql.SqlDbHelper; +import org.thingsboard.server.service.install.update.DefaultDataUpdateService; import java.nio.charset.Charset; import java.nio.file.Files; @@ -713,6 +714,19 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService log.error("Failed updating schema!!!", e); } break; + case "3.5.0": + try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { + log.info("Updating schema ..."); + if (isOldSchema(conn, 3005000)) { + schemaUpdateFile = Paths.get(installScripts.getDataDir(), "upgrade", "3.5.0", SCHEMA_UPDATE_SQL); + loadSql(schemaUpdateFile, conn); + conn.createStatement().execute("UPDATE tb_schema_settings SET schema_version = 3005001;"); + } + log.info("Schema updated."); + } catch (Exception e) { + log.error("Failed updating schema!!!", e); + } + break; default: throw new RuntimeException("Unable to upgrade SQL database, unsupported fromVersion: " + fromVersion); } @@ -745,6 +759,10 @@ public class SqlDatabaseUpgradeService implements DatabaseEntitiesUpgradeService } protected boolean isOldSchema(Connection conn, long fromVersion) { + if (DefaultDataUpdateService.getEnv("SKIP_SCHEMA_VERSION_CHECK", false)) { + log.info("Skipped DB schema version check due to SKIP_SCHEMA_VERSION_CHECK set to true!"); + return true; + } boolean isOldSchema = true; try { Statement statement = conn.createStatement(); diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java index 8bfdc0e243..3e7f67e09b 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/DefaultNotificationRuleProcessor.java @@ -97,7 +97,7 @@ public class DefaultNotificationRuleProcessor implements NotificationRuleProcess TenantId tenantId = triggerType.isTenantLevel() ? trigger.getTenantId() : TenantId.SYS_TENANT_ID; try { - List rules = notificationRulesCache.get(tenantId, triggerType); + List rules = notificationRulesCache.getEnabled(tenantId, triggerType); for (NotificationRule rule : rules) { notificationExecutor.submit(() -> { try { diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/DefaultNotificationRulesCache.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/DefaultNotificationRulesCache.java index b0cd1bd557..a02b7bf1e4 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/DefaultNotificationRulesCache.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/DefaultNotificationRulesCache.java @@ -82,12 +82,12 @@ public class DefaultNotificationRulesCache implements NotificationRulesCache { } @Override - public List get(TenantId tenantId, NotificationRuleTriggerType triggerType) { + public List getEnabled(TenantId tenantId, NotificationRuleTriggerType triggerType) { lock.readLock().lock(); try { log.trace("Retrieving notification rules of type {} for tenant {} from cache", triggerType, tenantId); return cache.get(key(tenantId, triggerType), k -> { - List rules = notificationRuleService.findNotificationRulesByTenantIdAndTriggerType(tenantId, triggerType); + List rules = notificationRuleService.findEnabledNotificationRulesByTenantIdAndTriggerType(tenantId, triggerType); log.trace("Fetched notification rules of type {} for tenant {} (count: {})", triggerType, tenantId, rules.size()); return !rules.isEmpty() ? rules : Collections.emptyList(); }); diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/NotificationRulesCache.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/NotificationRulesCache.java index 43ea3c4cc3..2a1054b352 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/NotificationRulesCache.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/cache/NotificationRulesCache.java @@ -23,6 +23,6 @@ import java.util.List; public interface NotificationRulesCache { - List get(TenantId tenantId, NotificationRuleTriggerType triggerType); + List getEnabled(TenantId tenantId, NotificationRuleTriggerType triggerType); } diff --git a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/DeviceActivityTriggerProcessor.java b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/DeviceActivityTriggerProcessor.java index 5dee2b69b0..6e181044c7 100644 --- a/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/DeviceActivityTriggerProcessor.java +++ b/application/src/main/java/org/thingsboard/server/service/notification/rule/trigger/DeviceActivityTriggerProcessor.java @@ -20,6 +20,7 @@ import org.apache.commons.collections.CollectionUtils; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.DataConstants; import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.notification.info.DeviceActivityNotificationInfo; @@ -41,6 +42,9 @@ public class DeviceActivityTriggerProcessor implements RuleEngineMsgNotification @Override public boolean matchesFilter(RuleEngineMsgTrigger trigger, DeviceActivityNotificationRuleTriggerConfig triggerConfig) { + if (trigger.getMsg().getOriginator().getEntityType() != EntityType.DEVICE) { + return false; + } DeviceEvent event = trigger.getMsg().getType().equals(DataConstants.ACTIVITY_EVENT) ? DeviceEvent.ACTIVE : DeviceEvent.INACTIVE; if (!triggerConfig.getNotifyOn().contains(event)) { return false; diff --git a/application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbCoreDeviceRpcService.java b/application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbCoreDeviceRpcService.java index 4302854715..bca7c7d81a 100644 --- a/application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbCoreDeviceRpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/rpc/DefaultTbCoreDeviceRpcService.java @@ -16,11 +16,11 @@ package org.thingsboard.server.service.rpc; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.actors.ActorSystemContext; import org.thingsboard.server.cluster.TbClusterService; @@ -57,8 +57,6 @@ import java.util.function.Consumer; @TbCoreComponent public class DefaultTbCoreDeviceRpcService implements TbCoreDeviceRpcService { - private static final ObjectMapper json = new ObjectMapper(); - private final DeviceService deviceService; private final TbClusterService clusterService; private final TbServiceInfoProvider serviceInfoProvider; @@ -159,7 +157,7 @@ public class DefaultTbCoreDeviceRpcService implements TbCoreDeviceRpcService { } private void sendRpcRequestToRuleEngine(ToDeviceRpcRequest msg, SecurityUser currentUser) { - ObjectNode entityNode = json.createObjectNode(); + ObjectNode entityNode = JacksonUtil.newObjectNode(); TbMsgMetaData metaData = new TbMsgMetaData(); metaData.putValue("requestUUID", msg.getId().toString()); metaData.putValue("originServiceId", serviceId); @@ -184,9 +182,9 @@ public class DefaultTbCoreDeviceRpcService implements TbCoreDeviceRpcService { entityNode.put(DataConstants.ADDITIONAL_INFO, msg.getAdditionalInfo()); try { - TbMsg tbMsg = TbMsg.newMsg(DataConstants.RPC_CALL_FROM_SERVER_TO_DEVICE, msg.getDeviceId(), Optional.ofNullable(currentUser).map(User::getCustomerId).orElse(null), metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode)); + TbMsg tbMsg = TbMsg.newMsg(DataConstants.RPC_CALL_FROM_SERVER_TO_DEVICE, msg.getDeviceId(), Optional.ofNullable(currentUser).map(User::getCustomerId).orElse(null), metaData, TbMsgDataType.JSON, JacksonUtil.toString(entityNode)); clusterService.pushMsgToRuleEngine(msg.getTenantId(), msg.getDeviceId(), tbMsg, null); - } catch (JsonProcessingException e) { + } catch (IllegalArgumentException e) { throw new RuntimeException(e); } } diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java index 5bf29acc75..66c206a7ad 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.security.auth.jwt; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationServiceException; @@ -25,6 +24,7 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.service.security.auth.RefreshAuthenticationToken; import org.thingsboard.server.service.security.exception.AuthMethodNotSupportedException; @@ -42,14 +42,12 @@ public class RefreshTokenProcessingFilter extends AbstractAuthenticationProcessi private final AuthenticationSuccessHandler successHandler; private final AuthenticationFailureHandler failureHandler; - private final ObjectMapper objectMapper; public RefreshTokenProcessingFilter(String defaultProcessUrl, AuthenticationSuccessHandler successHandler, - AuthenticationFailureHandler failureHandler, ObjectMapper mapper) { + AuthenticationFailureHandler failureHandler) { super(defaultProcessUrl); this.successHandler = successHandler; this.failureHandler = failureHandler; - this.objectMapper = mapper; } @Override @@ -64,7 +62,7 @@ public class RefreshTokenProcessingFilter extends AbstractAuthenticationProcessi RefreshTokenRequest refreshTokenRequest; try { - refreshTokenRequest = objectMapper.readValue(request.getReader(), RefreshTokenRequest.class); + refreshTokenRequest = JacksonUtil.fromReader(request.getReader(), RefreshTokenRequest.class); } catch (Exception e) { throw new AuthenticationServiceException("Invalid refresh token request payload"); } diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/provider/impl/SmsTwoFaProvider.java b/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/provider/impl/SmsTwoFaProvider.java index 75e5a01441..65a197153f 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/provider/impl/SmsTwoFaProvider.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/provider/impl/SmsTwoFaProvider.java @@ -20,12 +20,14 @@ import org.springframework.stereotype.Service; import org.thingsboard.rule.engine.api.SmsService; import org.thingsboard.rule.engine.api.util.TbNodeUtils; import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardErrorCode; import org.thingsboard.server.common.data.exception.ThingsboardException; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.security.model.mfa.account.SmsTwoFaAccountConfig; import org.thingsboard.server.common.data.security.model.mfa.provider.SmsTwoFaProviderConfig; import org.thingsboard.server.common.data.security.model.mfa.provider.TwoFaProviderType; +import org.thingsboard.server.dao.audit.AuditLogService; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; @@ -36,10 +38,12 @@ import java.util.Map; public class SmsTwoFaProvider extends OtpBasedTwoFaProvider { private final SmsService smsService; + private final AuditLogService auditLogService; - public SmsTwoFaProvider(CacheManager cacheManager, SmsService smsService) { + public SmsTwoFaProvider(CacheManager cacheManager, SmsService smsService, AuditLogService auditLogService) { super(cacheManager); this.smsService = smsService; + this.auditLogService = auditLogService; } @@ -56,8 +60,13 @@ public class SmsTwoFaProvider extends OtpBasedTwoFaProvider dashboardIdOpt = diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java index bc971e6104..9cac9b87a0 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/CustomOAuth2ClientMapper.java @@ -16,13 +16,12 @@ package org.thingsboard.server.service.security.auth.oauth2; import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.oauth2.OAuth2CustomMapperConfig; import org.thingsboard.server.common.data.oauth2.OAuth2MapperConfig; @@ -31,7 +30,6 @@ import org.thingsboard.server.dao.oauth2.OAuth2User; import org.thingsboard.server.queue.util.TbCoreComponent; import org.thingsboard.server.service.security.model.SecurityUser; -import javax.annotation.PostConstruct; import javax.servlet.http.HttpServletRequest; @Service(value = "customOAuth2ClientMapper") @@ -40,19 +38,9 @@ import javax.servlet.http.HttpServletRequest; public class CustomOAuth2ClientMapper extends AbstractOAuth2ClientMapper implements OAuth2ClientMapper { private static final String PROVIDER_ACCESS_TOKEN = "provider-access-token"; - private static final ObjectMapper json = new ObjectMapper(); private RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder(); - @PostConstruct - public void init() { - // Register time module to parse Instant objects. - // com.fasterxml.jackson.databind.exc.InvalidDefinitionException: - // Java 8 date/time type `java.time.Instant` not supported by default: - // add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling - json.registerModule(new JavaTimeModule()); - } - @Override public SecurityUser getOrCreateUserByClientPrincipal(HttpServletRequest request, OAuth2AuthenticationToken token, String providerAccessToken, OAuth2Registration registration) { OAuth2MapperConfig config = registration.getMapperConfig(); @@ -71,7 +59,7 @@ public class CustomOAuth2ClientMapper extends AbstractOAuth2ClientMapper impleme RestTemplate restTemplate = restTemplateBuilder.build(); String request; try { - request = json.writeValueAsString(token.getPrincipal()); + request = JacksonUtil.getObjectMapperWithJavaTimeModule().writeValueAsString(token.getPrincipal()); } catch (JsonProcessingException e) { log.error("Can't convert principal to JSON string", e); throw new RuntimeException("Can't convert principal to JSON string", e); diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationSuccessHandler.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationSuccessHandler.java index e8fd8e4882..0229170781 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationSuccessHandler.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestAwareAuthenticationSuccessHandler.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.security.auth.rest; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -23,6 +22,7 @@ import org.springframework.security.core.Authentication; import org.springframework.security.web.WebAttributes; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; import org.springframework.stereotype.Component; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.security.model.JwtPair; import org.thingsboard.server.service.security.auth.MfaAuthenticationToken; @@ -41,7 +41,6 @@ import java.util.concurrent.TimeUnit; @Component(value = "defaultAuthenticationSuccessHandler") @RequiredArgsConstructor public class RestAwareAuthenticationSuccessHandler implements AuthenticationSuccessHandler { - private final ObjectMapper mapper; private final JwtTokenFactory tokenFactory; private final TwoFaConfigManager twoFaConfigManager; @@ -65,7 +64,7 @@ public class RestAwareAuthenticationSuccessHandler implements AuthenticationSucc response.setStatus(HttpStatus.OK.value()); response.setContentType(MediaType.APPLICATION_JSON_VALUE); - mapper.writeValue(response.getWriter(), tokenPair); + JacksonUtil.writeValue(response.getWriter(), tokenPair); clearAuthenticationAttributes(request); } diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java index 5e0118a6ad..b3ea3453b2 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.security.auth.rest; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationDetailsSource; @@ -27,6 +26,7 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.service.security.exception.AuthMethodNotSupportedException; import org.thingsboard.server.service.security.model.UserPrincipal; @@ -45,14 +45,12 @@ public class RestLoginProcessingFilter extends AbstractAuthenticationProcessingF private final AuthenticationSuccessHandler successHandler; private final AuthenticationFailureHandler failureHandler; - private final ObjectMapper objectMapper; public RestLoginProcessingFilter(String defaultProcessUrl, AuthenticationSuccessHandler successHandler, - AuthenticationFailureHandler failureHandler, ObjectMapper mapper) { + AuthenticationFailureHandler failureHandler) { super(defaultProcessUrl); this.successHandler = successHandler; this.failureHandler = failureHandler; - this.objectMapper = mapper; } @Override @@ -67,7 +65,7 @@ public class RestLoginProcessingFilter extends AbstractAuthenticationProcessingF LoginRequest loginRequest; try { - loginRequest = objectMapper.readValue(request.getReader(), LoginRequest.class); + loginRequest = JacksonUtil.fromReader(request.getReader(), LoginRequest.class); } catch (Exception e) { throw new AuthenticationServiceException("Invalid login request payload"); } diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java index 5bf0382aa4..23252c27ef 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.security.auth.rest; -import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationServiceException; @@ -26,6 +25,7 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.authentication.AuthenticationFailureHandler; import org.springframework.security.web.authentication.AuthenticationSuccessHandler; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.service.security.exception.AuthMethodNotSupportedException; import org.thingsboard.server.service.security.model.UserPrincipal; @@ -42,14 +42,12 @@ public class RestPublicLoginProcessingFilter extends AbstractAuthenticationProce private final AuthenticationSuccessHandler successHandler; private final AuthenticationFailureHandler failureHandler; - private final ObjectMapper objectMapper; public RestPublicLoginProcessingFilter(String defaultProcessUrl, AuthenticationSuccessHandler successHandler, - AuthenticationFailureHandler failureHandler, ObjectMapper mapper) { + AuthenticationFailureHandler failureHandler) { super(defaultProcessUrl); this.successHandler = successHandler; this.failureHandler = failureHandler; - this.objectMapper = mapper; } @Override @@ -64,7 +62,7 @@ public class RestPublicLoginProcessingFilter extends AbstractAuthenticationProce PublicLoginRequest loginRequest; try { - loginRequest = objectMapper.readValue(request.getReader(), PublicLoginRequest.class); + loginRequest = JacksonUtil.fromReader(request.getReader(), PublicLoginRequest.class); } catch (Exception e) { throw new AuthenticationServiceException("Invalid public login request payload"); } diff --git a/application/src/main/java/org/thingsboard/server/service/sms/DefaultSmsService.java b/application/src/main/java/org/thingsboard/server/service/sms/DefaultSmsService.java index 0c54e75432..ff1304208d 100644 --- a/application/src/main/java/org/thingsboard/server/service/sms/DefaultSmsService.java +++ b/application/src/main/java/org/thingsboard/server/service/sms/DefaultSmsService.java @@ -34,6 +34,7 @@ import org.thingsboard.server.common.data.sms.config.TestSmsRequest; import org.thingsboard.server.common.stats.TbApiUsageReportClient; import org.thingsboard.server.dao.settings.AdminSettingsService; import org.thingsboard.server.service.apiusage.TbApiUsageStateService; +import org.thingsboard.server.service.transport.DefaultTransportApiService; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; @@ -86,7 +87,7 @@ public class DefaultSmsService implements SmsService { } } - private int sendSms(String numberTo, String message) throws ThingsboardException { + protected int sendSms(String numberTo, String message) throws ThingsboardException { if (this.smsSender == null) { throw new ThingsboardException("Unable to send SMS: no SMS provider configured!", ThingsboardErrorCode.GENERAL); } @@ -130,7 +131,9 @@ public class DefaultSmsService implements SmsService { private int sendSms(SmsSender smsSender, String numberTo, String message) throws ThingsboardException { try { - return smsSender.sendSms(numberTo, message); + int sentSms = smsSender.sendSms(numberTo, message); + log.trace("Successfully sent sms to number: {}", numberTo); + return sentSms; } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java index 57aa1e735e..d0d996fe1f 100644 --- a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java +++ b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java @@ -17,7 +17,6 @@ package org.thingsboard.server.service.transport; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; @@ -126,8 +125,6 @@ import static org.thingsboard.server.service.transport.BasicCredentialsValidatio @RequiredArgsConstructor public class DefaultTransportApiService implements TransportApiService { - private static final ObjectMapper mapper = new ObjectMapper(); - private static final Pattern X509_CERTIFICATE_TRIM_CHAIN_PATTERN = Pattern.compile("-----BEGIN CERTIFICATE-----\\s*.*?\\s*-----END CERTIFICATE-----"); private final TbDeviceProfileCache deviceProfileCache; @@ -348,8 +345,8 @@ public class DefaultTransportApiService implements TransportApiService { metaData.putValue("gatewayId", gatewayId.toString()); DeviceId deviceId = device.getId(); - ObjectNode entityNode = mapper.valueToTree(device); - TbMsg tbMsg = TbMsg.newMsg(DataConstants.ENTITY_CREATED, deviceId, customerId, metaData, TbMsgDataType.JSON, mapper.writeValueAsString(entityNode)); + JsonNode entityNode = JacksonUtil.valueToTree(device); + TbMsg tbMsg = TbMsg.newMsg(DataConstants.ENTITY_CREATED, deviceId, customerId, metaData, TbMsgDataType.JSON, JacksonUtil.toString(entityNode)); tbClusterService.pushMsgToRuleEngine(tenantId, deviceId, tbMsg, null); } else { JsonNode deviceAdditionalInfo = device.getAdditionalInfo(); @@ -559,7 +556,7 @@ public class DefaultTransportApiService implements TransportApiService { .setDeviceType(device.getType()) .setDeviceProfileIdMSB(device.getDeviceProfileId().getId().getMostSignificantBits()) .setDeviceProfileIdLSB(device.getDeviceProfileId().getId().getLeastSignificantBits()) - .setAdditionalInfo(mapper.writeValueAsString(device.getAdditionalInfo())); + .setAdditionalInfo(JacksonUtil.toString(device.getAdditionalInfo())); PowerSavingConfiguration psmConfiguration = null; switch (device.getDeviceData().getTransportConfiguration().getType()) { diff --git a/application/src/main/java/org/thingsboard/server/service/ttl/AuditLogsCleanUpService.java b/application/src/main/java/org/thingsboard/server/service/ttl/AuditLogsCleanUpService.java index 6d3cbf937e..d040676c4c 100644 --- a/application/src/main/java/org/thingsboard/server/service/ttl/AuditLogsCleanUpService.java +++ b/application/src/main/java/org/thingsboard/server/service/ttl/AuditLogsCleanUpService.java @@ -26,7 +26,7 @@ import org.thingsboard.server.queue.discovery.PartitionService; import java.util.concurrent.TimeUnit; -import static org.thingsboard.server.dao.model.ModelConstants.AUDIT_LOG_COLUMN_FAMILY_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.AUDIT_LOG_TABLE_NAME; @Service @ConditionalOnExpression("${sql.ttl.audit_logs.enabled:true} && ${sql.ttl.audit_logs.ttl:0} > 0") @@ -54,7 +54,7 @@ public class AuditLogsCleanUpService extends AbstractCleanUpService { if (isSystemTenantPartitionMine()) { auditLogDao.cleanUpAuditLogs(auditLogsExpTime); } else { - partitioningRepository.cleanupPartitionsCache(AUDIT_LOG_COLUMN_FAMILY_NAME, auditLogsExpTime, TimeUnit.HOURS.toMillis(partitionSizeInHours)); + partitioningRepository.cleanupPartitionsCache(AUDIT_LOG_TABLE_NAME, auditLogsExpTime, TimeUnit.HOURS.toMillis(partitionSizeInHours)); } } diff --git a/application/src/main/java/org/thingsboard/server/service/ttl/EdgeEventsCleanUpService.java b/application/src/main/java/org/thingsboard/server/service/ttl/EdgeEventsCleanUpService.java index 941416669a..aaac7cea55 100644 --- a/application/src/main/java/org/thingsboard/server/service/ttl/EdgeEventsCleanUpService.java +++ b/application/src/main/java/org/thingsboard/server/service/ttl/EdgeEventsCleanUpService.java @@ -27,7 +27,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent; import java.util.concurrent.TimeUnit; -import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_COLUMN_FAMILY_NAME; +import static org.thingsboard.server.dao.model.ModelConstants.EDGE_EVENT_TABLE_NAME; @TbCoreComponent @Slf4j @@ -63,7 +63,7 @@ public class EdgeEventsCleanUpService extends AbstractCleanUpService { if (ttlTaskExecutionEnabled && isSystemTenantPartitionMine()) { edgeEventService.cleanupEvents(edgeEventsExpTime); } else { - partitioningRepository.cleanupPartitionsCache(EDGE_EVENT_COLUMN_FAMILY_NAME, edgeEventsExpTime, TimeUnit.HOURS.toMillis(partitionSizeInHours)); + partitioningRepository.cleanupPartitionsCache(EDGE_EVENT_TABLE_NAME, edgeEventsExpTime, TimeUnit.HOURS.toMillis(partitionSizeInHours)); } } diff --git a/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java b/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java index 612c1d6610..ef066a73f6 100644 --- a/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java @@ -15,7 +15,6 @@ */ package org.thingsboard.server.service.update; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -26,6 +25,7 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.common.util.ThingsBoardThreadFactory; import org.thingsboard.server.common.data.UpdateMessage; import org.thingsboard.server.common.msg.notification.trigger.NewPlatformVersionTrigger; @@ -130,7 +130,7 @@ public class DefaultUpdateService implements UpdateService { log.trace("Executing check update method for instanceId [{}], platform [{}] and version [{}]", instanceId, platform, version); var headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); - ObjectNode request = new ObjectMapper().createObjectNode(); + ObjectNode request = JacksonUtil.newObjectNode(); request.put(PLATFORM_PARAM, platform); request.put(VERSION_PARAM, version); request.put(INSTANCE_ID_PARAM, instanceId.toString()); diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index cc2b075cf1..f776887287 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -607,6 +607,7 @@ spring: username: "${SPRING_DATASOURCE_USERNAME:postgres}" password: "${SPRING_DATASOURCE_PASSWORD:postgres}" hikari: + leakDetectionThreshold: "${SPRING_DATASOURCE_HIKARI_LEAK_DETECTION_THRESHOLD:0}" maximumPoolSize: "${SPRING_DATASOURCE_MAXIMUM_POOL_SIZE:16}" registerMbeans: "${SPRING_DATASOURCE_HIKARI_REGISTER_MBEANS:false}" # true - enable MBean to diagnose pools state via JMX @@ -621,6 +622,7 @@ audit-log: "device": "${AUDIT_LOG_MASK_DEVICE:W}" "asset": "${AUDIT_LOG_MASK_ASSET:W}" "dashboard": "${AUDIT_LOG_MASK_DASHBOARD:W}" + "widgets_bundle": "${AUDIT_LOG_MASK_WIDGETS_BUNDLE:W}" "customer": "${AUDIT_LOG_MASK_CUSTOMER:W}" "user": "${AUDIT_LOG_MASK_USER:W}" "rule_chain": "${AUDIT_LOG_MASK_RULE_CHAIN:W}" @@ -987,6 +989,7 @@ edges: persistToTelemetry: "${EDGES_PERSIST_STATE_TO_TELEMETRY:false}" swagger: + enabled: "${SWAGGER_ENABLED:true}" api_path_regex: "${SWAGGER_API_PATH_REGEX:/api/.*}" security_path_regex: "${SWAGGER_SECURITY_PATH_REGEX:/api/.*}" non_security_path_regex: "${SWAGGER_NON_SECURITY_PATH_REGEX:/api/(?:noauth|v1)/.*}" diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java index afaa19db8a..49e3550a1e 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java @@ -19,6 +19,7 @@ import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.TestPropertySource; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.EventInfo; import org.thingsboard.server.common.data.event.EventType; import org.thingsboard.server.common.data.id.EntityId; @@ -75,8 +76,8 @@ public abstract class AbstractRuleEngineControllerTest extends AbstractControlle protected JsonNode getMetadata(EventInfo outEvent) { String metaDataStr = outEvent.getBody().get("metadata").asText(); try { - return mapper.readTree(metaDataStr); - } catch (IOException e) { + return JacksonUtil.toJsonNode(metaDataStr); + } catch (IllegalArgumentException e) { throw new RuntimeException(e); } } diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java index c7580867e0..724e975792 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java @@ -17,7 +17,6 @@ package org.thingsboard.server.controller; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListeningExecutorService; @@ -57,6 +56,7 @@ import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilde import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.context.WebApplicationContext; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.api.MailService; import org.thingsboard.server.actors.DefaultTbActorSystem; import org.thingsboard.server.actors.TbActorId; @@ -150,8 +150,6 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { public static final int TIMEOUT = 30; - protected ObjectMapper mapper = new ObjectMapper(); - protected static final String TEST_TENANT_NAME = "TEST TENANT"; protected static final String TEST_DIFFERENT_TENANT_NAME = "TEST DIFFERENT TENANT"; @@ -451,7 +449,7 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { doGet("/api/noauth/activate?activateToken={activateToken}", this.currentActivateToken) .andExpect(status().isSeeOther()) .andExpect(header().string(HttpHeaders.LOCATION, "/login/createPassword?activateToken=" + this.currentActivateToken)); - return new ObjectMapper().createObjectNode() + return JacksonUtil.newObjectNode() .put("activateToken", this.currentActivateToken) .put("password", password); } @@ -815,7 +813,7 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { protected T readResponse(MvcResult result, TypeReference type) throws Exception { byte[] content = result.getResponse().getContentAsByteArray(); - return mapper.readerFor(type).readValue(content); + return JacksonUtil.OBJECT_MAPPER.readerFor(type).readValue(content); } protected String getErrorMessage(ResultActions result) throws Exception { diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseAdminControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AdminControllerTest.java similarity index 98% rename from application/src/test/java/org/thingsboard/server/controller/BaseAdminControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/AdminControllerTest.java index e6c27aa4a8..dd15c60168 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseAdminControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AdminControllerTest.java @@ -24,6 +24,7 @@ import org.mockito.Mockito; import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.security.model.JwtSettings; +import org.thingsboard.server.dao.service.DaoSqlTest; import java.nio.charset.StandardCharsets; import java.util.Base64; @@ -39,7 +40,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @Slf4j -public abstract class BaseAdminControllerTest extends AbstractControllerTest { +@DaoSqlTest +public class AdminControllerTest extends AbstractControllerTest { final JwtSettings defaultJwtSettings = new JwtSettings(9000, 604800, "thingsboard.io", "thingsboardDefaultSigningKey"); @Test diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseAlarmCommentControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java similarity index 98% rename from application/src/test/java/org/thingsboard/server/controller/BaseAlarmCommentControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java index 98446b025d..287ae7cfe1 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseAlarmCommentControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AlarmCommentControllerTest.java @@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.dao.alarm.AlarmDao; +import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.LinkedList; import java.util.List; @@ -48,8 +49,9 @@ import static org.hamcrest.Matchers.containsString; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @Slf4j -@ContextConfiguration(classes = {BaseAlarmCommentControllerTest.Config.class}) -public abstract class BaseAlarmCommentControllerTest extends AbstractControllerTest { +@ContextConfiguration(classes = {AlarmCommentControllerTest.Config.class}) +@DaoSqlTest +public class AlarmCommentControllerTest extends AbstractControllerTest { protected Device customerDevice; protected Alarm alarm; diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AlarmControllerTest.java similarity index 99% rename from application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/AlarmControllerTest.java index 930c4881f9..05030f0091 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AlarmControllerTest.java @@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.id.AlarmId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.dao.alarm.AlarmDao; +import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.LinkedList; import java.util.List; @@ -48,8 +49,9 @@ import static org.hamcrest.Matchers.containsString; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @Slf4j -@ContextConfiguration(classes = {BaseAlarmControllerTest.Config.class}) -public abstract class BaseAlarmControllerTest extends AbstractControllerTest { +@ContextConfiguration(classes = {AlarmControllerTest.Config.class}) +@DaoSqlTest +public class AlarmControllerTest extends AbstractControllerTest { public static final String TEST_ALARM_TYPE = "Test"; diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseAssetControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AssetControllerTest.java similarity index 99% rename from application/src/test/java/org/thingsboard/server/controller/BaseAssetControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/AssetControllerTest.java index 545cc0522d..40b1707271 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseAssetControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AssetControllerTest.java @@ -46,6 +46,7 @@ import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.dao.asset.AssetDao; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.model.ModelConstants; +import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.service.stats.DefaultRuleEngineStatisticsService; import java.util.ArrayList; @@ -56,8 +57,9 @@ import static org.hamcrest.Matchers.containsString; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; -@ContextConfiguration(classes = {BaseAssetControllerTest.Config.class}) -public abstract class BaseAssetControllerTest extends AbstractControllerTest { +@ContextConfiguration(classes = {AssetControllerTest.Config.class}) +@DaoSqlTest +public class AssetControllerTest extends AbstractControllerTest { private IdComparator idComparator = new IdComparator<>(); diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseAssetProfileControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AssetProfileControllerTest.java similarity index 99% rename from application/src/test/java/org/thingsboard/server/controller/BaseAssetProfileControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/AssetProfileControllerTest.java index 2f7c51c3a2..c84b058cc7 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseAssetProfileControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AssetProfileControllerTest.java @@ -42,6 +42,7 @@ import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.dao.asset.AssetProfileDao; import org.thingsboard.server.dao.exception.DataValidationException; +import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.ArrayList; import java.util.Collections; @@ -51,8 +52,9 @@ import java.util.stream.Collectors; import static org.hamcrest.Matchers.containsString; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@ContextConfiguration(classes = {BaseAssetProfileControllerTest.Config.class}) -public abstract class BaseAssetProfileControllerTest extends AbstractControllerTest { +@ContextConfiguration(classes = {AssetProfileControllerTest.Config.class}) +@DaoSqlTest +public class AssetProfileControllerTest extends AbstractControllerTest { private IdComparator idComparator = new IdComparator<>(); private IdComparator assetProfileInfoIdComparator = new IdComparator<>(); diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseAuditLogControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest.java similarity index 98% rename from application/src/test/java/org/thingsboard/server/controller/BaseAuditLogControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest.java index 95fcd08e12..a36a33bc6f 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseAuditLogControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AuditLogControllerTest.java @@ -34,6 +34,7 @@ import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.dao.audit.AuditLogDao; import org.thingsboard.server.dao.model.ModelConstants; +import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.dao.sqlts.insert.sql.SqlPartitioningRepository; import org.thingsboard.server.service.ttl.AuditLogsCleanUpService; @@ -50,7 +51,8 @@ import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -public abstract class BaseAuditLogControllerTest extends AbstractControllerTest { +@DaoSqlTest +public class AuditLogControllerTest extends AbstractControllerTest { private Tenant savedTenant; private User tenantAdmin; diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseAuthControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AuthControllerTest.java similarity index 95% rename from application/src/test/java/org/thingsboard/server/controller/BaseAuthControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/AuthControllerTest.java index 0ffda76a14..b833e45d34 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseAuthControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AuthControllerTest.java @@ -17,6 +17,7 @@ package org.thingsboard.server.controller; import org.junit.Test; import org.thingsboard.server.common.data.security.Authority; +import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.concurrent.TimeUnit; @@ -24,7 +25,8 @@ import static org.hamcrest.Matchers.is; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -public abstract class BaseAuthControllerTest extends AbstractControllerTest { +@DaoSqlTest +public class AuthControllerTest extends AbstractControllerTest { @Test public void testGetUser() throws Exception { diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseComponentDescriptorControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/ComponentDescriptorControllerTest.java similarity index 96% rename from application/src/test/java/org/thingsboard/server/controller/BaseComponentDescriptorControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/ComponentDescriptorControllerTest.java index cb35fd5a55..cce4261e14 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseComponentDescriptorControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/ComponentDescriptorControllerTest.java @@ -28,12 +28,14 @@ import org.thingsboard.server.common.data.plugin.ComponentScope; import org.thingsboard.server.common.data.plugin.ComponentType; import org.thingsboard.server.common.data.rule.RuleChainType; import org.thingsboard.server.common.data.security.Authority; +import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.List; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -public abstract class BaseComponentDescriptorControllerTest extends AbstractControllerTest { +@DaoSqlTest +public class ComponentDescriptorControllerTest extends AbstractControllerTest { private static final int AMOUNT_OF_DEFAULT_FILTER_NODES = 4; private Tenant savedTenant; diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseCustomerControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/CustomerControllerTest.java similarity index 98% rename from application/src/test/java/org/thingsboard/server/controller/BaseCustomerControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/CustomerControllerTest.java index 53e18c6673..125e533471 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseCustomerControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/CustomerControllerTest.java @@ -44,6 +44,7 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.dao.customer.CustomerDao; import org.thingsboard.server.dao.exception.DataValidationException; +import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.ArrayList; import java.util.List; @@ -53,8 +54,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.containsString; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@ContextConfiguration(classes = {BaseCustomerControllerTest.Config.class}) -public abstract class BaseCustomerControllerTest extends AbstractControllerTest { +@ContextConfiguration(classes = {CustomerControllerTest.Config.class}) +@DaoSqlTest +public class CustomerControllerTest extends AbstractControllerTest { static final TypeReference> PAGE_DATA_CUSTOMER_TYPE_REFERENCE = new TypeReference<>() { }; diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseDashboardControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java similarity index 99% rename from application/src/test/java/org/thingsboard/server/controller/BaseDashboardControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java index ea9ad45ed3..9f8e63e3b0 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseDashboardControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/DashboardControllerTest.java @@ -43,6 +43,7 @@ import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.dao.dashboard.DashboardDao; import org.thingsboard.server.dao.exception.DataValidationException; +import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.ArrayList; import java.util.Collections; @@ -51,8 +52,9 @@ import java.util.List; import static org.hamcrest.Matchers.containsString; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@ContextConfiguration(classes = {BaseDashboardControllerTest.Config.class}) -public abstract class BaseDashboardControllerTest extends AbstractControllerTest { +@ContextConfiguration(classes = {DashboardControllerTest.Config.class}) +@DaoSqlTest +public class DashboardControllerTest extends AbstractControllerTest { private IdComparator idComparator = new IdComparator<>(); diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java similarity index 99% rename from application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java index 42bfb236df..11d11eccdd 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/DeviceControllerTest.java @@ -68,6 +68,7 @@ import org.thingsboard.server.dao.device.DeviceDao; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.exception.DeviceCredentialsValidationException; import org.thingsboard.server.dao.model.ModelConstants; +import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.service.gateway_device.GatewayNotificationsService; import java.util.ArrayList; @@ -84,8 +85,9 @@ import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE; import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE; import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; -@ContextConfiguration(classes = {BaseDeviceControllerTest.Config.class}) -public abstract class BaseDeviceControllerTest extends AbstractControllerTest { +@ContextConfiguration(classes = {DeviceControllerTest.Config.class}) +@DaoSqlTest +public class DeviceControllerTest extends AbstractControllerTest { static final TypeReference> PAGE_DATA_DEVICE_TYPE_REF = new TypeReference<>() { }; diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/DeviceProfileControllerTest.java similarity index 99% rename from application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/DeviceProfileControllerTest.java index fb4f9bd322..d2bcfe2b88 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseDeviceProfileControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/DeviceProfileControllerTest.java @@ -51,6 +51,7 @@ import org.thingsboard.server.common.data.rule.RuleChain; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.dao.device.DeviceProfileDao; import org.thingsboard.server.dao.exception.DataValidationException; +import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.ArrayList; import java.util.Collections; @@ -62,8 +63,9 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE; import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE; -@ContextConfiguration(classes = {BaseDeviceProfileControllerTest.Config.class}) -public abstract class BaseDeviceProfileControllerTest extends AbstractControllerTest { +@ContextConfiguration(classes = {DeviceProfileControllerTest.Config.class}) +@DaoSqlTest +public class DeviceProfileControllerTest extends AbstractControllerTest { private IdComparator idComparator = new IdComparator<>(); private IdComparator deviceProfileInfoIdComparator = new IdComparator<>(); diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseEdgeControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/EdgeControllerTest.java similarity index 99% rename from application/src/test/java/org/thingsboard/server/controller/BaseEdgeControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/EdgeControllerTest.java index 731b5570cc..c8a20a38f5 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseEdgeControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/EdgeControllerTest.java @@ -52,6 +52,7 @@ import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.dao.edge.EdgeDao; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.model.ModelConstants; +import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.edge.imitator.EdgeImitator; import org.thingsboard.server.gen.edge.v1.AdminSettingsUpdateMsg; import org.thingsboard.server.gen.edge.v1.AssetProfileUpdateMsg; @@ -77,8 +78,9 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; @TestPropertySource(properties = { "edges.enabled=true", }) -@ContextConfiguration(classes = {BaseEdgeControllerTest.Config.class}) -public abstract class BaseEdgeControllerTest extends AbstractControllerTest { +@ContextConfiguration(classes = {EdgeControllerTest.Config.class}) +@DaoSqlTest +public class EdgeControllerTest extends AbstractControllerTest { public static final String EDGE_HOST = "localhost"; public static final int EDGE_PORT = 7070; diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/EdgeEventControllerTest.java similarity index 98% rename from application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/EdgeEventControllerTest.java index c591bb6a16..255aa2bdf1 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseEdgeEventControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/EdgeEventControllerTest.java @@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.page.TimePageLink; import org.thingsboard.server.common.data.relation.EntityRelation; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.dao.edge.EdgeEventDao; +import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.dao.sqlts.insert.sql.SqlPartitioningRepository; import org.thingsboard.server.service.ttl.EdgeEventsCleanUpService; @@ -59,7 +60,8 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. "edges.enabled=true", }) @Slf4j -public abstract class BaseEdgeEventControllerTest extends AbstractControllerTest { +@DaoSqlTest +public class EdgeEventControllerTest extends AbstractControllerTest { private Tenant savedTenant; private User tenantAdmin; diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseEntityQueryControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/EntityQueryControllerTest.java similarity index 99% rename from application/src/test/java/org/thingsboard/server/controller/BaseEntityQueryControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/EntityQueryControllerTest.java index ed25395b3b..2aa10992ed 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseEntityQueryControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/EntityQueryControllerTest.java @@ -52,6 +52,7 @@ import org.thingsboard.server.common.data.query.KeyFilter; import org.thingsboard.server.common.data.query.NumericFilterPredicate; import org.thingsboard.server.common.data.query.TsValue; import org.thingsboard.server.common.data.security.Authority; +import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.ArrayList; import java.util.Collections; @@ -62,7 +63,8 @@ import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -public abstract class BaseEntityQueryControllerTest extends AbstractControllerTest { +@DaoSqlTest +public class EntityQueryControllerTest extends AbstractControllerTest { private Tenant savedTenant; private User tenantAdmin; diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseEntityRelationControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/EntityRelationControllerTest.java similarity index 99% rename from application/src/test/java/org/thingsboard/server/controller/BaseEntityRelationControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/EntityRelationControllerTest.java index 1c76fb254f..d686be6f27 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseEntityRelationControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/EntityRelationControllerTest.java @@ -41,6 +41,7 @@ import org.thingsboard.server.common.data.relation.RelationTypeGroup; import org.thingsboard.server.common.data.relation.RelationsSearchParameters; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.dao.relation.RelationService; +import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.Collections; import java.util.List; @@ -50,7 +51,8 @@ import static org.hamcrest.Matchers.containsString; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @Slf4j -public abstract class BaseEntityRelationControllerTest extends AbstractControllerTest { +@DaoSqlTest +public class EntityRelationControllerTest extends AbstractControllerTest { public static final String BASE_DEVICE_NAME = "Test dummy device"; diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/EntityViewControllerTest.java similarity index 99% rename from application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/EntityViewControllerTest.java index 75283b63f1..a65769f3f1 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/EntityViewControllerTest.java @@ -64,6 +64,7 @@ import org.thingsboard.server.common.data.security.DeviceCredentials; import org.thingsboard.server.dao.entityview.EntityViewDao; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.model.ModelConstants; +import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.ArrayList; import java.util.HashSet; @@ -89,8 +90,9 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; "js.evaluator=mock", }) @Slf4j -@ContextConfiguration(classes = {BaseEntityViewControllerTest.Config.class}) -public abstract class BaseEntityViewControllerTest extends AbstractControllerTest { +@ContextConfiguration(classes = {EntityViewControllerTest.Config.class}) +@DaoSqlTest +public class EntityViewControllerTest extends AbstractControllerTest { static final TypeReference> PAGE_DATA_ENTITY_VIEW_TYPE_REF = new TypeReference<>() { }; static final TypeReference> PAGE_DATA_ENTITY_VIEW_INFO_TYPE_REF = new TypeReference<>() { diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseHomePageApiTest.java b/application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java similarity index 99% rename from application/src/test/java/org/thingsboard/server/controller/BaseHomePageApiTest.java rename to application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java index b71be1c3b6..c601be7272 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseHomePageApiTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/HomePageApiTest.java @@ -57,6 +57,7 @@ import org.thingsboard.server.common.data.query.TsValue; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.common.data.tenant.profile.DefaultTenantProfileConfiguration; import org.thingsboard.server.common.stats.TbApiUsageStateClient; +import org.thingsboard.server.dao.service.DaoSqlTest; import org.thingsboard.server.dao.settings.AdminSettingsService; import org.thingsboard.server.dao.tenant.TbTenantProfileCache; import org.thingsboard.server.service.ws.telemetry.cmd.v2.EntityCountCmd; @@ -73,7 +74,8 @@ import java.util.concurrent.TimeUnit; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @Slf4j -public abstract class BaseHomePageApiTest extends AbstractControllerTest { +@DaoSqlTest +public class HomePageApiTest extends AbstractControllerTest { @Autowired private TbApiUsageStateClient apiUsageStateClient; diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseOtaPackageControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/OtaPackageControllerTest.java similarity index 99% rename from application/src/test/java/org/thingsboard/server/controller/BaseOtaPackageControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/OtaPackageControllerTest.java index 1aed95ff0c..f4472e83be 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseOtaPackageControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/OtaPackageControllerTest.java @@ -38,6 +38,7 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.dao.exception.DataValidationException; +import org.thingsboard.server.dao.service.DaoSqlTest; import java.nio.ByteBuffer; import java.util.ArrayList; @@ -48,7 +49,8 @@ import static org.hamcrest.Matchers.containsString; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE; -public abstract class BaseOtaPackageControllerTest extends AbstractControllerTest { +@DaoSqlTest +public class OtaPackageControllerTest extends AbstractControllerTest { private IdComparator idComparator = new IdComparator<>(); diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseRpcControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/RpcControllerTest.java similarity index 98% rename from application/src/test/java/org/thingsboard/server/controller/BaseRpcControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/RpcControllerTest.java index 486ba32c4e..c060a7da96 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseRpcControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/RpcControllerTest.java @@ -31,12 +31,14 @@ import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.rpc.Rpc; import org.thingsboard.server.common.data.rpc.RpcStatus; import org.thingsboard.server.common.data.security.Authority; +import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.List; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -public abstract class BaseRpcControllerTest extends AbstractControllerTest { +@DaoSqlTest +public class RpcControllerTest extends AbstractControllerTest { private Tenant savedTenant; private User tenantAdmin; diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseRuleChainControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java similarity index 97% rename from application/src/test/java/org/thingsboard/server/controller/BaseRuleChainControllerTest.java rename to application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java index ba52cea1ec..c9eba1dbce 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseRuleChainControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java @@ -27,6 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Primary; import org.springframework.test.context.ContextConfiguration; +import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.rule.engine.action.TbCreateAlarmNode; import org.thingsboard.rule.engine.action.TbCreateAlarmNodeConfiguration; import org.thingsboard.server.common.data.StringUtils; @@ -44,6 +45,7 @@ import org.thingsboard.server.common.data.rule.RuleNode; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.dao.rule.RuleChainDao; +import org.thingsboard.server.dao.service.DaoSqlTest; import java.util.ArrayList; import java.util.Collections; @@ -53,8 +55,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.containsString; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; -@ContextConfiguration(classes = {BaseRuleChainControllerTest.Config.class}) -public abstract class BaseRuleChainControllerTest extends AbstractControllerTest { +@ContextConfiguration(classes = {RuleChainControllerTest.Config.class}) +@DaoSqlTest +public class RuleChainControllerTest extends AbstractControllerTest { private IdComparator idComparator = new IdComparator<>(); @@ -273,7 +276,7 @@ public abstract class BaseRuleChainControllerTest extends AbstractControllerTest TbCreateAlarmNodeConfiguration invalidCreateAlarmNodeConfiguration = new TbCreateAlarmNodeConfiguration(); invalidCreateAlarmNodeConfiguration.setSeverity("