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 e0190bb388..515c635e68 100644 --- a/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java +++ b/application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java @@ -15,6 +15,7 @@ */ 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; @@ -28,7 +29,6 @@ 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,6 +150,8 @@ public class ActorSystemContext { } }; + protected final ObjectMapper mapper = new ObjectMapper(); + private final ConcurrentMap debugPerTenantLimits = new ConcurrentHashMap<>(); public ConcurrentMap getDebugPerTenantLimits() { @@ -644,7 +646,7 @@ public class ActorSystemContext { .dataType(tbMsg.getDataType().name()) .relationType(relationType) .data(tbMsg.getData()) - .metadata(JacksonUtil.toString(tbMsg.getMetaData().getData())); + .metadata(mapper.writeValueAsString(tbMsg.getMetaData().getData())); if (error != null) { event.error(toString(error)); @@ -654,7 +656,7 @@ public class ActorSystemContext { ListenableFuture future = eventService.saveAsync(event.build()); Futures.addCallback(future, RULE_NODE_DEBUG_EVENT_ERROR_CALLBACK, MoreExecutors.directExecutor()); - } catch (IllegalArgumentException ex) { + } catch (IOException 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 934f309480..b8c890b75e 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 = JacksonUtil.newObjectNode(); + ObjectNode body = mapper.createObjectNode(); 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 8b76924d96..59d633540e 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,6 +16,7 @@ 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; @@ -120,6 +121,8 @@ 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; @@ -419,8 +422,8 @@ class DefaultTbContext implements TbContext { public TbMsg entityActionMsg(E entity, I id, RuleNodeId ruleNodeId, String action, K profile) { try { - return entityActionMsg(id, getActionMetaData(ruleNodeId), JacksonUtil.toString(JacksonUtil.valueToTree(entity)), action, profile); - } catch (IllegalArgumentException e) { + return entityActionMsg(id, getActionMetaData(ruleNodeId), mapper.writeValueAsString(mapper.valueToTree(entity)), action, profile); + } catch (JsonProcessingException | 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 395b8a24d0..e0c11102bf 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,6 +15,7 @@ */ 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; @@ -25,6 +26,8 @@ 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 ed0892f772..34fbecb4b5 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,6 +31,8 @@ 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); } @@ -61,7 +63,7 @@ public class StatsActor extends ContextAwareActor { } private JsonNode toBodyJson(String serviceId, long messagesProcessed, long errorsOccurred) { - return JacksonUtil.newObjectNode().put("server", serviceId).put("messagesProcessed", messagesProcessed).put("errorsOccurred", errorsOccurred); + return mapper.createObjectNode().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/ThingsboardSecurityConfiguration.java b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java index a418dc268b..9405d2da84 100644 --- a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java +++ b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java @@ -15,6 +15,7 @@ */ 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; @@ -115,18 +116,20 @@ 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); + RestLoginProcessingFilter filter = new RestLoginProcessingFilter(FORM_BASED_LOGIN_ENTRY_POINT, successHandler, failureHandler, objectMapper); filter.setAuthenticationManager(this.authenticationManager); return filter; } @Bean protected RestPublicLoginProcessingFilter buildRestPublicLoginProcessingFilter() throws Exception { - RestPublicLoginProcessingFilter filter = new RestPublicLoginProcessingFilter(PUBLIC_LOGIN_ENTRY_POINT, successHandler, failureHandler); + RestPublicLoginProcessingFilter filter = new RestPublicLoginProcessingFilter(PUBLIC_LOGIN_ENTRY_POINT, successHandler, failureHandler, objectMapper); filter.setAuthenticationManager(this.authenticationManager); return filter; } @@ -144,7 +147,7 @@ public class ThingsboardSecurityConfiguration { @Bean protected RefreshTokenProcessingFilter buildRefreshTokenProcessingFilter() throws Exception { - RefreshTokenProcessingFilter filter = new RefreshTokenProcessingFilter(TOKEN_REFRESH_ENTRY_POINT, successHandler, failureHandler); + RefreshTokenProcessingFilter filter = new RefreshTokenProcessingFilter(TOKEN_REFRESH_ENTRY_POINT, successHandler, failureHandler, objectMapper); filter.setAuthenticationManager(this.authenticationManager); return filter; } 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 68a987a0bc..5104fe9d32 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -15,6 +15,7 @@ */ 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; @@ -184,6 +185,8 @@ 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 dd904add2e..8156c72a41 100644 --- a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java +++ b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java @@ -16,6 +16,7 @@ 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; @@ -30,7 +31,6 @@ 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,7 +100,8 @@ public class CustomerController extends BaseController { checkParameter(CUSTOMER_ID, strCustomerId); CustomerId customerId = new CustomerId(toUUID(strCustomerId)); Customer customer = checkCustomerId(customerId, Operation.READ); - ObjectNode infoObject = JacksonUtil.newObjectNode(); + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode infoObject = objectMapper.createObjectNode(); infoObject.put("title", customer.getTitle()); infoObject.put(IS_PUBLIC, customer.isPublic()); return infoObject; 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 8949cd95dd..ae1dec43fe 100644 --- a/application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java +++ b/application/src/main/java/org/thingsboard/server/controller/Lwm2mController.java @@ -15,6 +15,7 @@ */ 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; @@ -27,7 +28,6 @@ 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,8 +72,9 @@ public class Lwm2mController extends BaseController { @RequestMapping(value = "/lwm2m/device-credentials", method = RequestMethod.POST) @ResponseBody public Device saveDeviceWithCredentials(@RequestBody Map, Object> deviceWithDeviceCredentials) throws ThingsboardException { - Device device = checkNotNull(JacksonUtil.convertValue(deviceWithDeviceCredentials.get(Device.class), Device.class)); - DeviceCredentials credentials = checkNotNull(JacksonUtil.convertValue(deviceWithDeviceCredentials.get(DeviceCredentials.class), DeviceCredentials.class)); + 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)); 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 ce6a98500d..81cf8be9fa 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RuleChainController.java @@ -18,6 +18,7 @@ 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; @@ -36,7 +37,6 @@ 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,6 +115,7 @@ 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. " + @@ -376,11 +377,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 = JacksonUtil.treeToValue(argNamesJson, String[].class); + String[] argNames = objectMapper.treeToValue(argNamesJson, String[].class); String data = inputParams.get("msg").asText(); JsonNode metadataJson = inputParams.get("metadata"); - Map metadata = JacksonUtil.convertValue(metadataJson, new TypeReference>() { + Map metadata = objectMapper.convertValue(metadataJson, new TypeReference>() { }); String msgType = inputParams.get("msgType").asText(); String output = ""; @@ -412,11 +413,11 @@ public class RuleChainController extends BaseController { break; case "switch": Set states = engine.executeSwitchAsync(inMsg).get(TIMEOUT, TimeUnit.SECONDS); - output = JacksonUtil.toString(states); + output = objectMapper.writeValueAsString(states); break; case "json": JsonNode json = engine.executeJsonAsync(inMsg).get(TIMEOUT, TimeUnit.SECONDS); - output = JacksonUtil.toString(json); + output = objectMapper.writeValueAsString(json); break; case "string": output = engine.executeToStringAsync(inMsg).get(TIMEOUT, TimeUnit.SECONDS); @@ -432,7 +433,7 @@ public class RuleChainController extends BaseController { engine.destroy(); } } - ObjectNode result = JacksonUtil.newObjectNode(); + ObjectNode result = objectMapper.createObjectNode(); result.put("output", output); result.put("error", errorText); return result; @@ -472,13 +473,13 @@ public class RuleChainController extends BaseController { private String msgToOutput(TbMsg msg) throws Exception { JsonNode resultNode = convertMsgToOut(msg); - return JacksonUtil.toString(resultNode); + return objectMapper.writeValueAsString(resultNode); } private String msgToOutput(List msgs) throws Exception { JsonNode resultNode; if (msgs.size() > 1) { - resultNode = JacksonUtil.OBJECT_MAPPER.createArrayNode(); + resultNode = objectMapper.createArrayNode(); for (TbMsg msg : msgs) { JsonNode convertedData = convertMsgToOut(msg); ((ArrayNode) resultNode).add(convertedData); @@ -486,16 +487,16 @@ public class RuleChainController extends BaseController { } else { resultNode = convertMsgToOut(msgs.get(0)); } - return JacksonUtil.toString(resultNode); + return objectMapper.writeValueAsString(resultNode); } private JsonNode convertMsgToOut(TbMsg msg) throws Exception { - ObjectNode msgData = JacksonUtil.newObjectNode(); + ObjectNode msgData = objectMapper.createObjectNode(); if (!StringUtils.isEmpty(msg.getData())) { - msgData.set("msg", JacksonUtil.valueToTree(msg.getData())); + msgData.set("msg", objectMapper.readTree(msg.getData())); } Map metadata = msg.getMetaData().getData(); - msgData.set("metadata", JacksonUtil.valueToTree(metadata)); + msgData.set("metadata", objectMapper.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 3633cbbdeb..e586f079ca 100644 --- a/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java +++ b/application/src/main/java/org/thingsboard/server/controller/SystemInfoController.java @@ -16,6 +16,7 @@ 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; @@ -141,7 +142,8 @@ public class SystemInfoController extends BaseController { } private JsonNode buildInfoObject() { - ObjectNode infoObject = JacksonUtil.newObjectNode(); + ObjectMapper objectMapper = new ObjectMapper(); + ObjectNode infoObject = objectMapper.createObjectNode(); if (buildProperties != null) { infoObject.put("version", buildProperties.getVersion()); infoObject.put("artifact", buildProperties.getArtifact()); 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 ed641c2d4f..5f22786907 100644 --- a/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java +++ b/application/src/main/java/org/thingsboard/server/exception/ThingsboardErrorResponseHandler.java @@ -15,6 +15,7 @@ */ 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; @@ -35,7 +36,6 @@ 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,6 +90,9 @@ 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, @@ -98,7 +101,7 @@ public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHand if (!response.isCommitted()) { response.setContentType(MediaType.APPLICATION_JSON_VALUE); response.setStatus(HttpStatus.FORBIDDEN.value()); - JacksonUtil.writeValue(response.getWriter(), + mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of("You don't have permission to perform this operation!", ThingsboardErrorCode.PERMISSION_DENIED, HttpStatus.FORBIDDEN)); } @@ -126,7 +129,7 @@ public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHand handleAuthenticationException((AuthenticationException) exception, response); } else { response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); - JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of(exception.getMessage(), + mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of(exception.getMessage(), ThingsboardErrorCode.GENERAL, HttpStatus.INTERNAL_SERVER_ERROR)); } } catch (IOException e) { @@ -151,26 +154,26 @@ public class ThingsboardErrorResponseHandler extends ResponseEntityExceptionHand ThingsboardErrorCode errorCode = thingsboardException.getErrorCode(); HttpStatus status = errorCodeToStatus(errorCode); response.setStatus(status.value()); - JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of(thingsboardException.getMessage(), errorCode, status)); + mapper.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() + "!"; - JacksonUtil.writeValue(response.getWriter(), + mapper.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()); - JacksonUtil.writeValue(response.getWriter(), - JacksonUtil.fromBytes(((HttpClientErrorException) subscriptionException.getCause()).getResponseBodyAsByteArray(), Object.class)); + mapper.writeValue(response.getWriter(), + (new ObjectMapper()).readValue(((HttpClientErrorException) subscriptionException.getCause()).getResponseBodyAsByteArray(), Object.class)); } private void handleAccessDeniedException(HttpServletResponse response) throws IOException { response.setStatus(HttpStatus.FORBIDDEN.value()); - JacksonUtil.writeValue(response.getWriter(), + mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of("You don't have permission to perform this operation!", ThingsboardErrorCode.PERMISSION_DENIED, HttpStatus.FORBIDDEN)); @@ -179,21 +182,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) { - JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of("Invalid username or password", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); + mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of("Invalid username or password", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); } else if (authenticationException instanceof DisabledException) { - JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of("User account is not active", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); + mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of("User account is not active", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); } else if (authenticationException instanceof LockedException) { - JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of("User account is locked due to security policy", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); + mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of("User account is locked due to security policy", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); } else if (authenticationException instanceof JwtExpiredTokenException) { - JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of("Token has expired", ThingsboardErrorCode.JWT_TOKEN_EXPIRED, HttpStatus.UNAUTHORIZED)); + mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of("Token has expired", ThingsboardErrorCode.JWT_TOKEN_EXPIRED, HttpStatus.UNAUTHORIZED)); } else if (authenticationException instanceof AuthMethodNotSupportedException) { - JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of(authenticationException.getMessage(), ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); + mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of(authenticationException.getMessage(), ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); } else if (authenticationException instanceof UserPasswordExpiredException) { UserPasswordExpiredException expiredException = (UserPasswordExpiredException) authenticationException; String resetToken = expiredException.getResetToken(); - JacksonUtil.writeValue(response.getWriter(), ThingsboardCredentialsExpiredResponse.of(expiredException.getMessage(), resetToken)); + mapper.writeValue(response.getWriter(), ThingsboardCredentialsExpiredResponse.of(expiredException.getMessage(), resetToken)); } else { - JacksonUtil.writeValue(response.getWriter(), ThingsboardErrorResponse.of("Authentication failed", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); + mapper.writeValue(response.getWriter(), ThingsboardErrorResponse.of("Authentication failed", ThingsboardErrorCode.AUTHENTICATION, HttpStatus.UNAUTHORIZED)); } } 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 623b95b40e..05e78e4060 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,6 +15,7 @@ */ 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; @@ -57,6 +58,8 @@ 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; @@ -186,18 +189,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", JacksonUtil.toString(comment)); + metaData.putValue("comment", json.writeValueAsString(comment)); } ObjectNode entityNode; if (entity != null) { - entityNode = JacksonUtil.OBJECT_MAPPER.valueToTree(entity); + entityNode = json.valueToTree(entity); if (entityId.getEntityType() == EntityType.DASHBOARD) { entityNode.put("configuration", ""); } metaData.putValue("entityName", entity.getName()); metaData.putValue("entityType", entityId.getEntityType().toString()); } else { - entityNode = JacksonUtil.newObjectNode(); + entityNode = json.createObjectNode(); if (actionType == ActionType.ATTRIBUTES_UPDATED) { String scope = extractParameter(String.class, 0, additionalInfo); @SuppressWarnings("unchecked") @@ -231,7 +234,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 = JacksonUtil.OBJECT_MAPPER.valueToTree(extractParameter(EntityRelation.class, 0, additionalInfo)); + entityNode = json.valueToTree(extractParameter(EntityRelation.class, 0, additionalInfo)); } } @@ -255,7 +258,7 @@ public class EntityActionService { .user(user) .build()); } - TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, customerId, metaData, TbMsgDataType.JSON, JacksonUtil.toString(entityNode)); + TbMsg tbMsg = TbMsg.newMsg(msgType, entityId, customerId, metaData, TbMsgDataType.JSON, json.writeValueAsString(entityNode)); tbClusterService.pushMsgToRuleEngine(tenantId, entityId, tbMsg, null); } catch (Exception e) { log.warn("[{}] Failed to push entity action to rule engine: {}", entityId, actionType, e); @@ -295,7 +298,7 @@ public class EntityActionService { Map> groupedTelemetry = timeseries.stream() .collect(Collectors.groupingBy(TsKvEntry::getTs)); for (Map.Entry> entry : groupedTelemetry.entrySet()) { - ObjectNode element = JacksonUtil.newObjectNode(); + ObjectNode element = json.createObjectNode(); 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/component/AnnotationComponentDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java index 1f5e41aeed..b425694e81 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,6 +16,7 @@ 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; @@ -26,7 +27,6 @@ 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,6 +69,8 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe private Map> edgeComponentsMap = new HashMap<>(); + private ObjectMapper mapper = new ObjectMapper(); + private boolean isInstall() { return environment.acceptsProfiles(Profiles.of("install")); } @@ -155,8 +157,8 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe scannedComponent.setScope(ruleNodeAnnotation.scope()); scannedComponent.setClusteringMode(ruleNodeAnnotation.clusteringMode()); NodeDefinition nodeDefinition = prepareNodeDefinition(ruleNodeAnnotation); - ObjectNode configurationDescriptor = JacksonUtil.newObjectNode(); - JsonNode node = JacksonUtil.valueToTree(nodeDefinition); + ObjectNode configurationDescriptor = mapper.createObjectNode(); + JsonNode node = mapper.valueToTree(nodeDefinition); configurationDescriptor.set("nodeDefinition", node); scannedComponent.setConfigurationDescriptor(configurationDescriptor); scannedComponent.setClazz(clazzName); @@ -193,7 +195,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe Class configClazz = nodeAnnotation.configClazz(); NodeConfiguration config = configClazz.getDeclaredConstructor().newInstance(); NodeConfiguration defaultConfiguration = config.defaultConfiguration(); - nodeDefinition.setDefaultConfiguration(JacksonUtil.valueToTree(defaultConfiguration)); + nodeDefinition.setDefaultConfiguration(mapper.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 ebc0fd0d24..4000e5a09d 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,6 +15,7 @@ */ 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; @@ -66,6 +67,7 @@ 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/install/DatabaseHelper.java b/application/src/main/java/org/thingsboard/server/service/install/DatabaseHelper.java index 97b87c7412..70f161d2e2 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,10 +67,11 @@ 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 = - JacksonUtil.constructCollectionType(HashSet.class, ShortCustomerInfo.class); + objectMapper.getTypeFactory().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); @@ -79,14 +80,14 @@ public class DatabaseHelper { List customerIds = new ArrayList<>(); if (!StringUtils.isEmpty(assignedCustomersString)) { try { - Set assignedCustomers = JacksonUtil.fromString(assignedCustomersString, assignedCustomersType); + Set assignedCustomers = objectMapper.readValue(assignedCustomersString, assignedCustomersType); assignedCustomers.forEach((customerInfo) -> { CustomerId customerId = customerInfo.getCustomerId(); if (!customerId.isNullUid()) { customerIds.add(customerId); } }); - } catch (IllegalArgumentException e) { + } catch (IOException 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 2feb13bb21..f1183bea8b 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,6 +15,7 @@ */ 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; @@ -28,7 +29,6 @@ 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; @@ -116,6 +116,7 @@ import java.util.concurrent.Executors; @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"; @@ -250,7 +251,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { AdminSettings generalSettings = new AdminSettings(); generalSettings.setTenantId(TenantId.SYS_TENANT_ID); generalSettings.setKey("general"); - ObjectNode node = JacksonUtil.newObjectNode(); + ObjectNode node = objectMapper.createObjectNode(); node.put("baseUrl", "http://localhost:8080"); node.put("prohibitDifferentUrl", false); generalSettings.setJsonValue(node); @@ -259,7 +260,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { AdminSettings mailSettings = new AdminSettings(); mailSettings.setTenantId(TenantId.SYS_TENANT_ID); mailSettings.setKey("mail"); - node = JacksonUtil.newObjectNode(); + node = objectMapper.createObjectNode(); node.put("mailFrom", "ThingsBoard "); node.put("smtpProtocol", "smtp"); node.put("smtpHost", "localhost"); @@ -542,7 +543,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { device.setDeviceProfileId(deviceProfileId); device.setName(name); if (description != null) { - ObjectNode additionalInfo = JacksonUtil.newObjectNode(); + ObjectNode additionalInfo = objectMapper.createObjectNode(); 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 9a810aa446..5ab7324192 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,7 +20,6 @@ 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; @@ -49,6 +48,7 @@ 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 = JacksonUtil.toJsonNode(templateFilePath.toFile()); - RuleChain ruleChain = JacksonUtil.treeToValue(ruleChainJson.get("ruleChain"), RuleChain.class); - RuleChainMetaData ruleChainMetaData = JacksonUtil.treeToValue(ruleChainJson.get("metadata"), RuleChainMetaData.class); + JsonNode ruleChainJson = objectMapper.readTree(templateFilePath.toFile()); + RuleChain ruleChain = objectMapper.treeToValue(ruleChainJson.get("ruleChain"), RuleChain.class); + RuleChainMetaData ruleChainMetaData = objectMapper.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 = JacksonUtil.toJsonNode(path.toFile()); + JsonNode widgetsBundleDescriptorJson = objectMapper.readTree(path.toFile()); JsonNode widgetsBundleJson = widgetsBundleDescriptorJson.get("widgetsBundle"); - WidgetsBundle widgetsBundle = JacksonUtil.treeToValue(widgetsBundleJson, WidgetsBundle.class); + WidgetsBundle widgetsBundle = objectMapper.treeToValue(widgetsBundleJson, WidgetsBundle.class); WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); JsonNode widgetTypesArrayJson = widgetsBundleDescriptorJson.get("widgetTypes"); widgetTypesArrayJson.forEach( widgetTypeJson -> { try { - WidgetTypeDetails widgetTypeDetails = JacksonUtil.treeToValue(widgetTypeJson, WidgetTypeDetails.class); + WidgetTypeDetails widgetTypeDetails = objectMapper.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 = JacksonUtil.toJsonNode(path.toFile()); - Dashboard dashboard = JacksonUtil.treeToValue(dashboardJson, Dashboard.class); + JsonNode dashboardJson = objectMapper.readTree(path.toFile()); + Dashboard dashboard = objectMapper.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 = JacksonUtil.toJsonNode(path.toFile()); - OAuth2ClientRegistrationTemplate clientRegistrationTemplate = JacksonUtil.treeToValue(oauth2ConfigTemplateJson, OAuth2ClientRegistrationTemplate.class); + JsonNode oauth2ConfigTemplateJson = objectMapper.readTree(path.toFile()); + OAuth2ClientRegistrationTemplate clientRegistrationTemplate = objectMapper.treeToValue(oauth2ConfigTemplateJson, OAuth2ClientRegistrationTemplate.class); Optional existingClientRegistrationTemplate = oAuth2TemplateService.findClientRegistrationTemplateByProviderId(clientRegistrationTemplate.getProviderId()); if (existingClientRegistrationTemplate.isPresent()) { 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 bca7c7d81a..4302854715 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,6 +57,8 @@ 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; @@ -157,7 +159,7 @@ public class DefaultTbCoreDeviceRpcService implements TbCoreDeviceRpcService { } private void sendRpcRequestToRuleEngine(ToDeviceRpcRequest msg, SecurityUser currentUser) { - ObjectNode entityNode = JacksonUtil.newObjectNode(); + ObjectNode entityNode = json.createObjectNode(); TbMsgMetaData metaData = new TbMsgMetaData(); metaData.putValue("requestUUID", msg.getId().toString()); metaData.putValue("originServiceId", serviceId); @@ -182,9 +184,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, JacksonUtil.toString(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, json.writeValueAsString(entityNode)); clusterService.pushMsgToRuleEngine(msg.getTenantId(), msg.getDeviceId(), tbMsg, null); - } catch (IllegalArgumentException e) { + } catch (JsonProcessingException 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 66c206a7ad..5bf29acc75 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,6 +15,7 @@ */ 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; @@ -24,7 +25,6 @@ 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,12 +42,14 @@ 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) { + AuthenticationFailureHandler failureHandler, ObjectMapper mapper) { super(defaultProcessUrl); this.successHandler = successHandler; this.failureHandler = failureHandler; + this.objectMapper = mapper; } @Override @@ -62,7 +64,7 @@ public class RefreshTokenProcessingFilter extends AbstractAuthenticationProcessi RefreshTokenRequest refreshTokenRequest; try { - refreshTokenRequest = JacksonUtil.fromReader(request.getReader(), RefreshTokenRequest.class); + refreshTokenRequest = objectMapper.readValue(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/oauth2/AbstractOAuth2ClientMapper.java b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java index 429f6a1e8c..d27a4ecc83 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/oauth2/AbstractOAuth2ClientMapper.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.service.security.auth.oauth2; +import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.Getter; import lombok.extern.slf4j.Slf4j; @@ -23,7 +24,6 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.cluster.TbClusterService; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.DashboardInfo; @@ -62,6 +62,8 @@ import java.util.concurrent.locks.ReentrantLock; public abstract class AbstractOAuth2ClientMapper { private static final int DASHBOARDS_REQUEST_LIMIT = 10; + private static final ObjectMapper objectMapper = new ObjectMapper(); + @Autowired private UserService userService; @@ -128,7 +130,7 @@ public abstract class AbstractOAuth2ClientMapper { user.setFirstName(oauth2User.getFirstName()); user.setLastName(oauth2User.getLastName()); - ObjectNode additionalInfo = JacksonUtil.newObjectNode(); + ObjectNode additionalInfo = objectMapper.createObjectNode(); if (!StringUtils.isEmpty(oauth2User.getDefaultDashboardName())) { Optional 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 9cac9b87a0..bc971e6104 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,12 +16,13 @@ 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; @@ -30,6 +31,7 @@ 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") @@ -38,9 +40,19 @@ 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(); @@ -59,7 +71,7 @@ public class CustomOAuth2ClientMapper extends AbstractOAuth2ClientMapper impleme RestTemplate restTemplate = restTemplateBuilder.build(); String request; try { - request = JacksonUtil.getObjectMapperWithJavaTimeModule().writeValueAsString(token.getPrincipal()); + request = json.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 0229170781..e8fd8e4882 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,6 +15,7 @@ */ 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; @@ -22,7 +23,6 @@ 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,6 +41,7 @@ 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; @@ -64,7 +65,7 @@ public class RestAwareAuthenticationSuccessHandler implements AuthenticationSucc response.setStatus(HttpStatus.OK.value()); response.setContentType(MediaType.APPLICATION_JSON_VALUE); - JacksonUtil.writeValue(response.getWriter(), tokenPair); + mapper.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 b3ea3453b2..5e0118a6ad 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,6 +15,7 @@ */ 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; @@ -26,7 +27,6 @@ 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,12 +45,14 @@ 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) { + AuthenticationFailureHandler failureHandler, ObjectMapper mapper) { super(defaultProcessUrl); this.successHandler = successHandler; this.failureHandler = failureHandler; + this.objectMapper = mapper; } @Override @@ -65,7 +67,7 @@ public class RestLoginProcessingFilter extends AbstractAuthenticationProcessingF LoginRequest loginRequest; try { - loginRequest = JacksonUtil.fromReader(request.getReader(), LoginRequest.class); + loginRequest = objectMapper.readValue(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 23252c27ef..5bf0382aa4 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,6 +15,7 @@ */ 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; @@ -25,7 +26,6 @@ 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,12 +42,14 @@ 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) { + AuthenticationFailureHandler failureHandler, ObjectMapper mapper) { super(defaultProcessUrl); this.successHandler = successHandler; this.failureHandler = failureHandler; + this.objectMapper = mapper; } @Override @@ -62,7 +64,7 @@ public class RestPublicLoginProcessingFilter extends AbstractAuthenticationProce PublicLoginRequest loginRequest; try { - loginRequest = JacksonUtil.fromReader(request.getReader(), PublicLoginRequest.class); + loginRequest = objectMapper.readValue(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/transport/DefaultTransportApiService.java b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java index d0d996fe1f..57aa1e735e 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,6 +17,7 @@ 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; @@ -125,6 +126,8 @@ 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; @@ -345,8 +348,8 @@ public class DefaultTransportApiService implements TransportApiService { metaData.putValue("gatewayId", gatewayId.toString()); DeviceId deviceId = device.getId(); - JsonNode entityNode = JacksonUtil.valueToTree(device); - TbMsg tbMsg = TbMsg.newMsg(DataConstants.ENTITY_CREATED, deviceId, customerId, metaData, TbMsgDataType.JSON, JacksonUtil.toString(entityNode)); + ObjectNode entityNode = mapper.valueToTree(device); + TbMsg tbMsg = TbMsg.newMsg(DataConstants.ENTITY_CREATED, deviceId, customerId, metaData, TbMsgDataType.JSON, mapper.writeValueAsString(entityNode)); tbClusterService.pushMsgToRuleEngine(tenantId, deviceId, tbMsg, null); } else { JsonNode deviceAdditionalInfo = device.getAdditionalInfo(); @@ -556,7 +559,7 @@ public class DefaultTransportApiService implements TransportApiService { .setDeviceType(device.getType()) .setDeviceProfileIdMSB(device.getDeviceProfileId().getId().getMostSignificantBits()) .setDeviceProfileIdLSB(device.getDeviceProfileId().getId().getLeastSignificantBits()) - .setAdditionalInfo(JacksonUtil.toString(device.getAdditionalInfo())); + .setAdditionalInfo(mapper.writeValueAsString(device.getAdditionalInfo())); PowerSavingConfiguration psmConfiguration = null; switch (device.getDeviceData().getTransportConfiguration().getType()) { 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 ef066a73f6..612c1d6610 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,6 +15,7 @@ */ 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; @@ -25,7 +26,6 @@ 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 = JacksonUtil.newObjectNode(); + ObjectNode request = new ObjectMapper().createObjectNode(); request.put(PLATFORM_PARAM, platform); request.put(VERSION_PARAM, version); request.put(INSTANCE_ID_PARAM, instanceId.toString()); 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 49e3550a1e..afaa19db8a 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractRuleEngineControllerTest.java @@ -19,7 +19,6 @@ 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; @@ -76,8 +75,8 @@ public abstract class AbstractRuleEngineControllerTest extends AbstractControlle protected JsonNode getMetadata(EventInfo outEvent) { String metaDataStr = outEvent.getBody().get("metadata").asText(); try { - return JacksonUtil.toJsonNode(metaDataStr); - } catch (IllegalArgumentException e) { + return mapper.readTree(metaDataStr); + } catch (IOException 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 724e975792..c7580867e0 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java @@ -17,6 +17,7 @@ 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; @@ -56,7 +57,6 @@ 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,6 +150,8 @@ 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"; @@ -449,7 +451,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 JacksonUtil.newObjectNode() + return new ObjectMapper().createObjectNode() .put("activateToken", this.currentActivateToken) .put("password", password); } @@ -813,7 +815,7 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { protected T readResponse(MvcResult result, TypeReference type) throws Exception { byte[] content = result.getResponse().getContentAsByteArray(); - return JacksonUtil.OBJECT_MAPPER.readerFor(type).readValue(content); + return mapper.readerFor(type).readValue(content); } protected String getErrorMessage(ResultActions result) throws Exception { diff --git a/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java index c9eba1dbce..16a266e485 100644 --- a/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/RuleChainControllerTest.java @@ -27,7 +27,6 @@ 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; @@ -276,7 +275,7 @@ public class RuleChainControllerTest extends AbstractControllerTest { TbCreateAlarmNodeConfiguration invalidCreateAlarmNodeConfiguration = new TbCreateAlarmNodeConfiguration(); invalidCreateAlarmNodeConfiguration.setSeverity("