diff --git a/application/pom.xml b/application/pom.xml
index 62fd69d4f4..bbdf3a0bcd 100644
--- a/application/pom.xml
+++ b/application/pom.xml
@@ -275,7 +275,7 @@
org.mockito
- mockito-all
+ mockito-coretest
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 c608c4a8a8..51100a8377 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
@@ -475,11 +475,6 @@ class DefaultTbContext implements TbContext {
return mainCtx.getCassandraBufferedRateExecutor().submit(task);
}
- @Override
- public RedisTemplate getRedisTemplate() {
- return mainCtx.getRedisTemplate();
- }
-
@Override
public PageData findRuleNodeStates(PageLink pageLink) {
if (log.isDebugEnabled()) {
diff --git a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java
index 9e307df8c0..d0dbc66963 100644
--- a/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java
+++ b/application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java
@@ -147,7 +147,7 @@ public class RuleNodeActorMessageProcessor extends ComponentMsgProcessor componentClazz = Class.forName(ruleNode.getType());
- tbNode = (TbNode) (componentClazz.newInstance());
+ tbNode = (TbNode) (componentClazz.getDeclaredConstructor().newInstance());
tbNode.init(defaultCtx, new TbNodeConfiguration(ruleNode.getConfiguration()));
}
return tbNode;
diff --git a/application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java b/application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java
index 0fcaf90525..bbcb7d656a 100644
--- a/application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java
+++ b/application/src/main/java/org/thingsboard/server/config/CustomOAuth2AuthorizationRequestResolver.java
@@ -91,6 +91,7 @@ public class CustomOAuth2AuthorizationRequestResolver implements OAuth2Authoriza
return action;
}
+ @SuppressWarnings("deprecation")
private OAuth2AuthorizationRequest resolve(HttpServletRequest request, String registrationId, String redirectUriAction) {
if (registrationId == null) {
return null;
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 a012bd7766..b70c4e2a7c 100644
--- a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java
+++ b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java
@@ -127,7 +127,7 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt
}
protected JwtTokenAuthenticationProcessingFilter buildJwtTokenAuthenticationProcessingFilter() throws Exception {
- List pathsToSkip = new ArrayList(Arrays.asList(NON_TOKEN_BASED_AUTH_ENTRY_POINTS));
+ List pathsToSkip = new ArrayList<>(Arrays.asList(NON_TOKEN_BASED_AUTH_ENTRY_POINTS));
pathsToSkip.addAll(Arrays.asList(WS_TOKEN_BASED_AUTH_ENTRY_POINT, TOKEN_REFRESH_ENTRY_POINT, FORM_BASED_LOGIN_ENTRY_POINT,
PUBLIC_LOGIN_ENTRY_POINT, DEVICE_API_ENTRY_POINT, WEBJARS_ENTRY_POINT));
SkipPathRequestMatcher matcher = new SkipPathRequestMatcher(pathsToSkip, TOKEN_BASED_AUTH_ENTRY_POINT);
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 c5b3b28167..3a315be459 100644
--- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java
@@ -645,6 +645,7 @@ public abstract class BaseController {
return ruleNode;
}
+ @SuppressWarnings("unchecked")
protected I emptyId(EntityType entityType) {
return (I) EntityIdFactory.getByTypeAndUuid(entityType, ModelConstants.NULL_UUID);
}
@@ -759,6 +760,7 @@ public abstract class BaseController {
entityNode = json.createObjectNode();
if (actionType == ActionType.ATTRIBUTES_UPDATED) {
String scope = extractParameter(String.class, 0, additionalInfo);
+ @SuppressWarnings("unchecked")
List attributes = extractParameter(List.class, 1, additionalInfo);
metaData.putValue("scope", scope);
if (attributes != null) {
@@ -768,6 +770,7 @@ public abstract class BaseController {
}
} else if (actionType == ActionType.ATTRIBUTES_DELETED) {
String scope = extractParameter(String.class, 0, additionalInfo);
+ @SuppressWarnings("unchecked")
List keys = extractParameter(List.class, 1, additionalInfo);
metaData.putValue("scope", scope);
ArrayNode attrsArrayNode = entityNode.putArray("attributes");
@@ -775,9 +778,11 @@ public abstract class BaseController {
keys.forEach(attrsArrayNode::add);
}
} else if (actionType == ActionType.TIMESERIES_UPDATED) {
+ @SuppressWarnings("unchecked")
List timeseries = extractParameter(List.class, 0, additionalInfo);
addTimeseries(entityNode, timeseries);
} else if (actionType == ActionType.TIMESERIES_DELETED) {
+ @SuppressWarnings("unchecked")
List keys = extractParameter(List.class, 0, additionalInfo);
if (keys != null) {
ArrayNode timeseriesArrayNode = entityNode.putArray("timeseries");
diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java
index 2d2342556c..6250975b01 100644
--- a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java
+++ b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java
@@ -63,7 +63,7 @@ import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
-import static org.apache.commons.lang.StringUtils.isBlank;
+import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.thingsboard.server.controller.CustomerController.CUSTOMER_ID;
/**
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 bd490efdba..c0a9f5e7c5 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
@@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
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.rule.engine.api.NodeConfiguration;
@@ -69,7 +70,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
private ObjectMapper mapper = new ObjectMapper();
private boolean isInstall() {
- return environment.acceptsProfiles("install");
+ return environment.acceptsProfiles(Profiles.of("install"));
}
@PostConstruct
@@ -185,7 +186,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
nodeDefinition.setRelationTypes(getRelationTypesWithFailureRelation(nodeAnnotation));
nodeDefinition.setCustomRelations(nodeAnnotation.customRelations());
Class extends NodeConfiguration> configClazz = nodeAnnotation.configClazz();
- NodeConfiguration config = configClazz.newInstance();
+ NodeConfiguration config = configClazz.getDeclaredConstructor().newInstance();
NodeConfiguration defaultConfiguration = config.defaultConfiguration();
nodeDefinition.setDefaultConfiguration(mapper.valueToTree(defaultConfiguration));
nodeDefinition.setUiResources(nodeAnnotation.uiResources());
diff --git a/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java b/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java
index 2793503a81..3bd540048f 100644
--- a/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java
+++ b/application/src/main/java/org/thingsboard/server/service/device/DeviceProvisionServiceImpl.java
@@ -20,7 +20,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang.RandomStringUtils;
+import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
diff --git a/application/src/main/java/org/thingsboard/server/service/install/cql/CassandraDbHelper.java b/application/src/main/java/org/thingsboard/server/service/install/cql/CassandraDbHelper.java
index 606bb34432..cb987a5e65 100644
--- a/application/src/main/java/org/thingsboard/server/service/install/cql/CassandraDbHelper.java
+++ b/application/src/main/java/org/thingsboard/server/service/install/cql/CassandraDbHelper.java
@@ -146,17 +146,17 @@ public class CassandraDbHelper {
if (row.isNull(index)) {
return null;
} else if (type.getProtocolCode() == ProtocolConstants.DataType.DOUBLE) {
- str = new Double(row.getDouble(index)).toString();
+ str = Double.valueOf(row.getDouble(index)).toString();
} else if (type.getProtocolCode() == ProtocolConstants.DataType.INT) {
- str = new Integer(row.getInt(index)).toString();
+ str = Integer.valueOf(row.getInt(index)).toString();
} else if (type.getProtocolCode() == ProtocolConstants.DataType.BIGINT) {
- str = new Long(row.getLong(index)).toString();
+ str = Long.valueOf(row.getLong(index)).toString();
} else if (type.getProtocolCode() == ProtocolConstants.DataType.UUID) {
str = row.getUuid(index).toString();
} else if (type.getProtocolCode() == ProtocolConstants.DataType.TIMEUUID) {
str = row.getUuid(index).toString();
} else if (type.getProtocolCode() == ProtocolConstants.DataType.FLOAT) {
- str = new Float(row.getFloat(index)).toString();
+ str = Float.valueOf(row.getFloat(index)).toString();
} else if (type.getProtocolCode() == ProtocolConstants.DataType.TIMESTAMP) {
str = ""+row.getInstant(index).toEpochMilli();
} else {
diff --git a/application/src/main/java/org/thingsboard/server/service/install/migrate/CassandraToSqlColumn.java b/application/src/main/java/org/thingsboard/server/service/install/migrate/CassandraToSqlColumn.java
index bc53134973..f841621bbc 100644
--- a/application/src/main/java/org/thingsboard/server/service/install/migrate/CassandraToSqlColumn.java
+++ b/application/src/main/java/org/thingsboard/server/service/install/migrate/CassandraToSqlColumn.java
@@ -153,7 +153,8 @@ public class CassandraToSqlColumn {
sqlInsertStatement.setBoolean(this.sqlIndex, Boolean.parseBoolean(value));
break;
case ENUM_TO_INT:
- Enum enumVal = Enum.valueOf(this.enumClass, value);
+ @SuppressWarnings("unchecked")
+ Enum> enumVal = Enum.valueOf(this.enumClass, value);
int intValue = enumVal.ordinal();
sqlInsertStatement.setInt(this.sqlIndex, intValue);
break;
diff --git a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java
index 3eebf8ff93..4bbe7c46f2 100644
--- a/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java
+++ b/application/src/main/java/org/thingsboard/server/service/install/update/DefaultDataUpdateService.java
@@ -57,7 +57,7 @@ import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
-import static org.apache.commons.lang.StringUtils.isBlank;
+import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.thingsboard.server.service.install.DatabaseHelper.objectMapper;
@Service
diff --git a/application/src/main/java/org/thingsboard/server/service/query/DefaultEntityQueryService.java b/application/src/main/java/org/thingsboard/server/service/query/DefaultEntityQueryService.java
index 39a1c46325..7e1101dfc8 100644
--- a/application/src/main/java/org/thingsboard/server/service/query/DefaultEntityQueryService.java
+++ b/application/src/main/java/org/thingsboard/server/service/query/DefaultEntityQueryService.java
@@ -206,7 +206,7 @@ public class DefaultEntityQueryService implements EntityQueryService {
addItemsToArrayNode(json.putArray("entityTypes"), types);
addItemsToArrayNode(json.putArray("timeseries"), timeseriesKeys);
addItemsToArrayNode(json.putArray("attribute"), attributesKeys);
- response.setResult(new ResponseEntity(json, HttpStatus.OK));
+ response.setResult(new ResponseEntity<>(json, HttpStatus.OK));
}
private void replyWithEmptyResponse(DeferredResult response) {
diff --git a/application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java b/application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java
index 4aae3263d5..1d7a5d9533 100644
--- a/application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java
+++ b/application/src/main/java/org/thingsboard/server/service/script/AbstractNashornJsInvokeService.java
@@ -21,7 +21,6 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import delight.nashornsandbox.NashornSandbox;
import delight.nashornsandbox.NashornSandboxes;
-import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
@@ -33,6 +32,7 @@ import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.script.Invocable;
import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.UUID;
import java.util.concurrent.ExecutionException;
@@ -97,8 +97,8 @@ public abstract class AbstractNashornJsInvokeService extends AbstractJsInvokeSer
sandbox.allowLoadFunctions(true);
sandbox.setMaxPreparedStatements(30);
} else {
- NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
- engine = factory.getScriptEngine(new String[]{"--no-java"});
+ ScriptEngineManager factory = new ScriptEngineManager();
+ engine = factory.getEngineByName("nashorn");
}
}
diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/SkipPathRequestMatcher.java b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/SkipPathRequestMatcher.java
index d9f4b976eb..331bbc6ef6 100644
--- a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/SkipPathRequestMatcher.java
+++ b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/SkipPathRequestMatcher.java
@@ -29,7 +29,7 @@ public class SkipPathRequestMatcher implements RequestMatcher {
private RequestMatcher processingMatcher;
public SkipPathRequestMatcher(List pathsToSkip, String processingPath) {
- Assert.notNull(pathsToSkip);
+ Assert.notNull(pathsToSkip, "List of paths to skip is required.");
List m = pathsToSkip.stream().map(path -> new AntPathRequestMatcher(path)).collect(Collectors.toList());
matchers = new OrRequestMatcher(m);
processingMatcher = new AntPathRequestMatcher(processingPath);
diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java b/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java
index b4e26c1447..cfbf051cad 100644
--- a/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java
+++ b/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtTokenFactory.java
@@ -100,6 +100,7 @@ public class JwtTokenFactory {
Jws jwsClaims = rawAccessToken.parseClaims(settings.getTokenSigningKey());
Claims claims = jwsClaims.getBody();
String subject = claims.getSubject();
+ @SuppressWarnings("unchecked")
List scopes = claims.get(SCOPES, List.class);
if (scopes == null || scopes.isEmpty()) {
throw new IllegalArgumentException("JWT Token doesn't have any scopes");
@@ -155,6 +156,7 @@ public class JwtTokenFactory {
Jws jwsClaims = rawAccessToken.parseClaims(settings.getTokenSigningKey());
Claims claims = jwsClaims.getBody();
String subject = claims.getSubject();
+ @SuppressWarnings("unchecked")
List scopes = claims.get(SCOPES, List.class);
if (scopes == null || scopes.isEmpty()) {
throw new IllegalArgumentException("Refresh Token doesn't have any scopes");
diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java b/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java
index a92b50cda8..4b2c22f501 100644
--- a/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java
+++ b/application/src/main/java/org/thingsboard/server/service/security/permission/CustomerUserPermissions.java
@@ -47,6 +47,7 @@ public class CustomerUserPermissions extends AbstractPermissions {
Operation.READ_ATTRIBUTES, Operation.READ_TELEMETRY, Operation.RPC_CALL, Operation.CLAIM_DEVICES) {
@Override
+ @SuppressWarnings("unchecked")
public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) {
if (!super.hasPermission(user, operation, entityId, entity)) {
@@ -69,6 +70,7 @@ public class CustomerUserPermissions extends AbstractPermissions {
new PermissionChecker.GenericPermissionChecker(Operation.READ, Operation.READ_ATTRIBUTES, Operation.READ_TELEMETRY) {
@Override
+ @SuppressWarnings("unchecked")
public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) {
if (!super.hasPermission(user, operation, entityId, entity)) {
return false;
@@ -119,6 +121,7 @@ public class CustomerUserPermissions extends AbstractPermissions {
private static final PermissionChecker widgetsPermissionChecker = new PermissionChecker.GenericPermissionChecker(Operation.READ) {
@Override
+ @SuppressWarnings("unchecked")
public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) {
if (!super.hasPermission(user, operation, entityId, entity)) {
return false;
diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/DefaultAccessControlService.java b/application/src/main/java/org/thingsboard/server/service/security/permission/DefaultAccessControlService.java
index 624e1743ca..0e56963464 100644
--- a/application/src/main/java/org/thingsboard/server/service/security/permission/DefaultAccessControlService.java
+++ b/application/src/main/java/org/thingsboard/server/service/security/permission/DefaultAccessControlService.java
@@ -56,6 +56,7 @@ public class DefaultAccessControlService implements AccessControlService {
}
@Override
+ @SuppressWarnings("unchecked")
public void checkPermission(SecurityUser user, Resource resource,
Operation operation, I entityId, T entity) throws ThingsboardException {
PermissionChecker permissionChecker = getPermissionChecker(user.getAuthority(), resource);
diff --git a/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java b/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java
index b8d2c539cd..f56e1e0554 100644
--- a/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java
+++ b/application/src/main/java/org/thingsboard/server/service/security/permission/TenantAdminPermissions.java
@@ -59,6 +59,7 @@ public class TenantAdminPermissions extends AbstractPermissions {
new PermissionChecker.GenericPermissionChecker(Operation.READ, Operation.READ_ATTRIBUTES, Operation.READ_TELEMETRY) {
@Override
+ @SuppressWarnings("unchecked")
public boolean hasPermission(SecurityUser user, Operation operation, EntityId entityId, HasTenantId entity) {
if (!super.hasPermission(user, operation, entityId, entity)) {
return false;
diff --git a/application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java b/application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java
index 9ebff31ad4..c86b1cdcfe 100644
--- a/application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java
+++ b/application/src/main/java/org/thingsboard/server/service/security/system/DefaultSystemSecurityService.java
@@ -15,8 +15,8 @@
*/
package org.thingsboard.server.service.security.system;
+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.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@@ -49,6 +49,7 @@ import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.dao.user.UserServiceImpl;
+import org.thingsboard.server.dao.util.mapping.JacksonUtil;
import org.thingsboard.server.service.security.exception.UserPasswordExpiredException;
import org.thingsboard.server.utils.MiscUtils;
@@ -65,8 +66,6 @@ import static org.thingsboard.server.common.data.CacheConstants.SECURITY_SETTING
@Slf4j
public class DefaultSystemSecurityService implements SystemSecurityService {
- private static final ObjectMapper objectMapper = new ObjectMapper();
-
@Autowired
private AdminSettingsService adminSettingsService;
@@ -89,7 +88,7 @@ public class DefaultSystemSecurityService implements SystemSecurityService {
AdminSettings adminSettings = adminSettingsService.findAdminSettingsByKey(tenantId, "securitySettings");
if (adminSettings != null) {
try {
- securitySettings = objectMapper.treeToValue(adminSettings.getJsonValue(), SecuritySettings.class);
+ securitySettings = JacksonUtil.convertValue(adminSettings.getJsonValue(), SecuritySettings.class);
} catch (Exception e) {
throw new RuntimeException("Failed to load security settings!", e);
}
@@ -109,10 +108,10 @@ public class DefaultSystemSecurityService implements SystemSecurityService {
adminSettings = new AdminSettings();
adminSettings.setKey("securitySettings");
}
- adminSettings.setJsonValue(objectMapper.valueToTree(securitySettings));
+ adminSettings.setJsonValue(JacksonUtil.valueToTree(securitySettings));
AdminSettings savedAdminSettings = adminSettingsService.saveAdminSettings(tenantId, adminSettings);
try {
- return objectMapper.treeToValue(savedAdminSettings.getJsonValue(), SecuritySettings.class);
+ return JacksonUtil.convertValue(savedAdminSettings.getJsonValue(), SecuritySettings.class);
} catch (Exception e) {
throw new RuntimeException("Failed to load security settings!", e);
}
@@ -189,7 +188,7 @@ public class DefaultSystemSecurityService implements SystemSecurityService {
JsonNode additionalInfo = user.getAdditionalInfo();
if (additionalInfo instanceof ObjectNode && additionalInfo.has(UserServiceImpl.USER_PASSWORD_HISTORY)) {
JsonNode userPasswordHistoryJson = additionalInfo.get(UserServiceImpl.USER_PASSWORD_HISTORY);
- Map userPasswordHistoryMap = objectMapper.convertValue(userPasswordHistoryJson, Map.class);
+ Map userPasswordHistoryMap = JacksonUtil.convertValue(userPasswordHistoryJson, new TypeReference<>() {});
for (Map.Entry entry : userPasswordHistoryMap.entrySet()) {
if (encoder.matches(password, entry.getValue()) && Long.parseLong(entry.getKey()) > passwordReuseFrequencyTs) {
throw new DataValidationException("Password was already used for the last " + passwordPolicy.getPasswordReuseFrequencyDays() + " days");
diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java
index 1b455085eb..fe2fbce573 100644
--- a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java
+++ b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbEntityDataSubscriptionService.java
@@ -318,6 +318,7 @@ public class DefaultTbEntityDataSubscriptionService implements TbEntityDataSubsc
return ctx;
}
+ @SuppressWarnings("unchecked")
private T getSubCtx(String sessionId, int cmdId) {
Map sessionSubs = subscriptionsBySessionId.get(sessionId);
if (sessionSubs != null) {
diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionService.java b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionService.java
index 868d14ac3e..ee00b28562 100644
--- a/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionService.java
+++ b/application/src/main/java/org/thingsboard/server/service/subscription/DefaultTbLocalSubscriptionService.java
@@ -123,6 +123,7 @@ public class DefaultTbLocalSubscriptionService implements TbLocalSubscriptionSer
}
@Override
+ @SuppressWarnings("unchecked")
public void onSubscriptionUpdate(String sessionId, TelemetrySubscriptionUpdate update, TbCallback callback) {
TbSubscription subscription = subscriptionsBySessionId
.getOrDefault(sessionId, Collections.emptyMap()).get(update.getSubscriptionId());
@@ -143,6 +144,7 @@ public class DefaultTbLocalSubscriptionService implements TbLocalSubscriptionSer
}
@Override
+ @SuppressWarnings("unchecked")
public void onSubscriptionUpdate(String sessionId, AlarmSubscriptionUpdate update, TbCallback callback) {
TbSubscription subscription = subscriptionsBySessionId
.getOrDefault(sessionId, Collections.emptyMap()).get(update.getSubscriptionId());
diff --git a/application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractDataSubCtx.java b/application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractDataSubCtx.java
index 9b03e40f1e..a200f31a3f 100644
--- a/application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractDataSubCtx.java
+++ b/application/src/main/java/org/thingsboard/server/service/subscription/TbAbstractDataSubCtx.java
@@ -264,6 +264,7 @@ public abstract class TbAbstractDataSubCtx T doGetAsyncTyped(String urlTemplate, TypeReference responseType, Object... urlVariables) throws Exception {
+ return readResponse(doGetAsync(urlTemplate, urlVariables).andExpect(status().isOk()), responseType);
+ }
+
protected ResultActions doGetAsync(String urlTemplate, Object... urlVariables) throws Exception {
MockHttpServletRequestBuilder getRequest;
getRequest = get(urlTemplate, urlVariables);
diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java
index 35ff3703c0..c6d0073d83 100644
--- a/application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java
+++ b/application/src/test/java/org/thingsboard/server/controller/BaseEntityViewControllerTest.java
@@ -347,8 +347,8 @@ public abstract class BaseEntityViewControllerTest extends AbstractControllerTes
Thread.sleep(1000);
- Listorg.mockito
- mockito-all
+ mockito-coretest
diff --git a/common/actor/src/test/java/org/thingsboard/server/actors/ActorSystemTest.java b/common/actor/src/test/java/org/thingsboard/server/actors/ActorSystemTest.java
index 8ce0942f2a..31fae3d7a4 100644
--- a/common/actor/src/test/java/org/thingsboard/server/actors/ActorSystemTest.java
+++ b/common/actor/src/test/java/org/thingsboard/server/actors/ActorSystemTest.java
@@ -21,7 +21,7 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.junit.MockitoJUnitRunner;
import org.thingsboard.server.common.data.id.DeviceId;
import java.util.ArrayList;
diff --git a/common/dao-api/pom.xml b/common/dao-api/pom.xml
index b427846d91..ba30e5bb43 100644
--- a/common/dao-api/pom.xml
+++ b/common/dao-api/pom.xml
@@ -48,6 +48,10 @@
com.google.guavaguava
+
+ javax.annotation
+ javax.annotation-api
+ com.github.fgejson-schema-validator
@@ -99,7 +103,7 @@
org.mockito
- mockito-all
+ mockito-coretest
diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java
index d03c0d167b..57b0e2a140 100644
--- a/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java
+++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java
@@ -23,6 +23,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
+import org.springframework.core.env.Profiles;
import org.thingsboard.server.dao.cassandra.guava.GuavaSession;
import org.thingsboard.server.dao.cassandra.guava.GuavaSessionBuilder;
import org.thingsboard.server.dao.cassandra.guava.GuavaSessionUtils;
@@ -77,7 +78,7 @@ public abstract class AbstractCassandraCluster {
}
private boolean isInstall() {
- return environment.acceptsProfiles("install");
+ return environment.acceptsProfiles(Profiles.of("install"));
}
private void initSession() {
diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/guava/GuavaSessionBuilder.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/guava/GuavaSessionBuilder.java
index 45f3e6fd6a..8187e5e6f2 100644
--- a/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/guava/GuavaSessionBuilder.java
+++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/cassandra/guava/GuavaSessionBuilder.java
@@ -18,38 +18,25 @@ package org.thingsboard.server.dao.cassandra.guava;
import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.config.DriverConfigLoader;
import com.datastax.oss.driver.api.core.context.DriverContext;
-import com.datastax.oss.driver.api.core.metadata.Node;
-import com.datastax.oss.driver.api.core.metadata.NodeStateListener;
-import com.datastax.oss.driver.api.core.metadata.schema.SchemaChangeListener;
+import com.datastax.oss.driver.api.core.session.ProgrammaticArguments;
import com.datastax.oss.driver.api.core.session.SessionBuilder;
-import com.datastax.oss.driver.api.core.tracker.RequestTracker;
-import com.datastax.oss.driver.api.core.type.codec.TypeCodec;
import edu.umd.cs.findbugs.annotations.NonNull;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Predicate;
public class GuavaSessionBuilder extends SessionBuilder {
@Override
protected DriverContext buildContext(
DriverConfigLoader configLoader,
- List> typeCodecs,
- NodeStateListener nodeStateListener,
- SchemaChangeListener schemaChangeListener,
- RequestTracker requestTracker,
- Map localDatacenters,
- Map> nodeFilters,
- ClassLoader classLoader) {
+ ProgrammaticArguments programmaticArguments) {
return new GuavaDriverContext(
configLoader,
- typeCodecs,
- nodeStateListener,
- schemaChangeListener,
- requestTracker,
- localDatacenters,
- nodeFilters,
- classLoader);
+ programmaticArguments.getTypeCodecs(),
+ programmaticArguments.getNodeStateListener(),
+ programmaticArguments.getSchemaChangeListener(),
+ programmaticArguments.getRequestTracker(),
+ programmaticArguments.getLocalDatacenters(),
+ programmaticArguments.getNodeFilters(),
+ programmaticArguments.getClassLoader());
}
@Override
diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/claim/ClaimResult.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/claim/ClaimResult.java
index 0dddc66ebe..fbf3256d8c 100644
--- a/common/dao-api/src/main/java/org/thingsboard/server/dao/device/claim/ClaimResult.java
+++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/device/claim/ClaimResult.java
@@ -18,9 +18,11 @@ package org.thingsboard.server.dao.device.claim;
import lombok.AllArgsConstructor;
import lombok.Data;
+import lombok.NoArgsConstructor;
import org.thingsboard.server.common.data.Device;
@AllArgsConstructor
+@NoArgsConstructor
@Data
public class ClaimResult {
diff --git a/common/data/pom.xml b/common/data/pom.xml
index 6d484bd107..79b3bc8e26 100644
--- a/common/data/pom.xml
+++ b/common/data/pom.xml
@@ -63,7 +63,7 @@
org.mockito
- mockito-all
+ mockito-coretest
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/ClaimRequest.java b/common/data/src/main/java/org/thingsboard/server/common/data/ClaimRequest.java
index a9ef3473aa..a1dec1d216 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/ClaimRequest.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/ClaimRequest.java
@@ -15,9 +15,13 @@
*/
package org.thingsboard.server.common.data;
+import lombok.AllArgsConstructor;
import lombok.Data;
+import lombok.NoArgsConstructor;
@Data
+@AllArgsConstructor
+@NoArgsConstructor(force = true)
public class ClaimRequest {
private final String secretKey;
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboardInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboardInfo.java
index 1cbc1c737e..30d271af95 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboardInfo.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/HomeDashboardInfo.java
@@ -17,10 +17,12 @@ package org.thingsboard.server.common.data;
import lombok.AllArgsConstructor;
import lombok.Data;
+import lombok.NoArgsConstructor;
import org.thingsboard.server.common.data.id.DashboardId;
@Data
@AllArgsConstructor
+@NoArgsConstructor
public class HomeDashboardInfo {
private DashboardId dashboardId;
private boolean hideDashboardToolbar;
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/ShortCustomerInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/ShortCustomerInfo.java
index aa03cd7e59..11bd9e6955 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/ShortCustomerInfo.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/ShortCustomerInfo.java
@@ -17,6 +17,7 @@ package org.thingsboard.server.common.data;
import lombok.AllArgsConstructor;
import lombok.Getter;
+import lombok.NoArgsConstructor;
import lombok.Setter;
import org.thingsboard.server.common.data.id.CustomerId;
@@ -25,6 +26,7 @@ import org.thingsboard.server.common.data.id.CustomerId;
*/
@AllArgsConstructor
+@NoArgsConstructor
public class ShortCustomerInfo {
@Getter @Setter
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AllowCreateNewDevicesDeviceProfileProvisionConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AllowCreateNewDevicesDeviceProfileProvisionConfiguration.java
index 79532d34f3..2370dc9f11 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AllowCreateNewDevicesDeviceProfileProvisionConfiguration.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AllowCreateNewDevicesDeviceProfileProvisionConfiguration.java
@@ -15,10 +15,14 @@
*/
package org.thingsboard.server.common.data.device.profile;
+import lombok.AllArgsConstructor;
import lombok.Data;
+import lombok.NoArgsConstructor;
import org.thingsboard.server.common.data.DeviceProfileProvisionType;
@Data
+@AllArgsConstructor
+@NoArgsConstructor(force = true)
public class AllowCreateNewDevicesDeviceProfileProvisionConfiguration implements DeviceProfileProvisionConfiguration {
private final String provisionDeviceSecret;
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration.java
index 1c2c1e9eaa..e2e37d3979 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration.java
@@ -15,10 +15,14 @@
*/
package org.thingsboard.server.common.data.device.profile;
+import lombok.AllArgsConstructor;
import lombok.Data;
+import lombok.NoArgsConstructor;
import org.thingsboard.server.common.data.DeviceProfileProvisionType;
@Data
+@AllArgsConstructor
+@NoArgsConstructor(force = true)
public class CheckPreProvisionedDevicesDeviceProfileProvisionConfiguration implements DeviceProfileProvisionConfiguration {
private final String provisionDeviceSecret;
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DisabledDeviceProfileProvisionConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DisabledDeviceProfileProvisionConfiguration.java
index 10021ddb1a..7c2d11c8eb 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DisabledDeviceProfileProvisionConfiguration.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/DisabledDeviceProfileProvisionConfiguration.java
@@ -15,10 +15,14 @@
*/
package org.thingsboard.server.common.data.device.profile;
+import lombok.AllArgsConstructor;
import lombok.Data;
+import lombok.NoArgsConstructor;
import org.thingsboard.server.common.data.DeviceProfileProvisionType;
@Data
+@AllArgsConstructor
+@NoArgsConstructor(force = true)
public class DisabledDeviceProfileProvisionConfiguration implements DeviceProfileProvisionConfiguration {
private final String provisionDeviceSecret;
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/DynamicValue.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/DynamicValue.java
index 3d46f8d2ab..25be8d7502 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/query/DynamicValue.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/DynamicValue.java
@@ -15,7 +15,9 @@
*/
package org.thingsboard.server.common.data.query;
+import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.Getter;
@@ -30,4 +32,11 @@ public class DynamicValue {
@Getter
private final String sourceAttribute;
+ @JsonCreator
+ public DynamicValue(@JsonProperty("sourceType") DynamicValueSourceType sourceType,
+ @JsonProperty("sourceAttribute") String sourceAttribute) {
+ this.sourceType = sourceType;
+ this.sourceAttribute = sourceAttribute;
+ }
+
}
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityData.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityData.java
index 0998d348d4..2ff6902f75 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityData.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityData.java
@@ -15,12 +15,16 @@
*/
package org.thingsboard.server.common.data.query;
+import lombok.AllArgsConstructor;
import lombok.Data;
+import lombok.NoArgsConstructor;
import org.thingsboard.server.common.data.id.EntityId;
import java.util.Map;
@Data
+@AllArgsConstructor
+@NoArgsConstructor(force = true)
public class EntityData {
private final EntityId entityId;
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityKey.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityKey.java
index 191ef02f11..54fc13f1f4 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityKey.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/EntityKey.java
@@ -15,9 +15,13 @@
*/
package org.thingsboard.server.common.data.query;
+import lombok.AllArgsConstructor;
import lombok.Data;
+import lombok.NoArgsConstructor;
@Data
+@AllArgsConstructor
+@NoArgsConstructor(force = true)
public class EntityKey {
private final EntityKeyType type;
private final String key;
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/query/TsValue.java b/common/data/src/main/java/org/thingsboard/server/common/data/query/TsValue.java
index bb2735b2d0..25d2ac76aa 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/query/TsValue.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/query/TsValue.java
@@ -15,9 +15,13 @@
*/
package org.thingsboard.server.common.data.query;
+import lombok.AllArgsConstructor;
import lombok.Data;
+import lombok.NoArgsConstructor;
@Data
+@AllArgsConstructor
+@NoArgsConstructor(force = true)
public class TsValue {
private final long ts;
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityTypeFilter.java b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityTypeFilter.java
index 8b9849d6a1..3660ea02c5 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityTypeFilter.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityTypeFilter.java
@@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.relation;
import lombok.AllArgsConstructor;
import lombok.Data;
+import lombok.NoArgsConstructor;
import org.thingsboard.server.common.data.EntityType;
import java.util.List;
@@ -26,6 +27,7 @@ import java.util.List;
*/
@Data
@AllArgsConstructor
+@NoArgsConstructor
public class EntityTypeFilter {
private String relationType;
diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java b/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java
index f44337ff29..ed63a5ffe5 100644
--- a/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java
+++ b/common/data/src/main/java/org/thingsboard/server/common/data/relation/RelationsSearchParameters.java
@@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.relation;
import lombok.AllArgsConstructor;
import lombok.Data;
+import lombok.NoArgsConstructor;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
@@ -28,6 +29,7 @@ import java.util.UUID;
*/
@Data
@AllArgsConstructor
+@NoArgsConstructor
public class RelationsSearchParameters {
private UUID rootId;
diff --git a/common/data/src/test/java/org/thingsboard/server/common/data/UUIDConverterTest.java b/common/data/src/test/java/org/thingsboard/server/common/data/UUIDConverterTest.java
index adb173f367..0f5bf5f724 100644
--- a/common/data/src/test/java/org/thingsboard/server/common/data/UUIDConverterTest.java
+++ b/common/data/src/test/java/org/thingsboard/server/common/data/UUIDConverterTest.java
@@ -19,7 +19,7 @@ import com.datastax.oss.driver.api.core.uuid.Uuids;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.junit.MockitoJUnitRunner;
import java.util.ArrayList;
import java.util.Arrays;
diff --git a/common/message/pom.xml b/common/message/pom.xml
index 8bc2653bb0..06ba4aff3b 100644
--- a/common/message/pom.xml
+++ b/common/message/pom.xml
@@ -76,7 +76,7 @@
org.mockito
- mockito-all
+ mockito-coretest
diff --git a/common/queue/pom.xml b/common/queue/pom.xml
index 4c3eb4aeba..e0b30dd654 100644
--- a/common/queue/pom.xml
+++ b/common/queue/pom.xml
@@ -124,7 +124,7 @@
org.mockito
- mockito-all
+ mockito-coretest
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/azure/servicebus/TbServiceBusConsumerTemplate.java b/common/queue/src/main/java/org/thingsboard/server/queue/azure/servicebus/TbServiceBusConsumerTemplate.java
index 5b562cbfbf..525f9bfe92 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/azure/servicebus/TbServiceBusConsumerTemplate.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/azure/servicebus/TbServiceBusConsumerTemplate.java
@@ -154,6 +154,7 @@ public class TbServiceBusConsumerTemplate extends Abstract
}
private CompletableFuture> fromList(List> futures) {
+ @SuppressWarnings("unchecked")
CompletableFuture>[] arrayFuture = new CompletableFuture[futures.size()];
futures.toArray(arrayFuture);
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/memory/InMemoryStorage.java b/common/queue/src/main/java/org/thingsboard/server/queue/memory/InMemoryStorage.java
index b46fd4c87d..226ed32682 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/memory/InMemoryStorage.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/memory/InMemoryStorage.java
@@ -60,6 +60,7 @@ public final class InMemoryStorage {
public List get(String topic) throws InterruptedException {
if (storage.containsKey(topic)) {
List entities;
+ @SuppressWarnings("unchecked")
T first = (T) storage.get(topic).poll();
if (first != null) {
entities = new ArrayList<>();
@@ -67,7 +68,9 @@ public final class InMemoryStorage {
List otherList = new ArrayList<>();
storage.get(topic).drainTo(otherList, 999);
for (TbQueueMsg other : otherList) {
- entities.add((T) other);
+ @SuppressWarnings("unchecked")
+ T entity = (T) other;
+ entities.add(entity);
}
} else {
entities = Collections.emptyList();
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/memory/InMemoryTbQueueConsumer.java b/common/queue/src/main/java/org/thingsboard/server/queue/memory/InMemoryTbQueueConsumer.java
index 95af725bb4..6e28d48a4b 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/memory/InMemoryTbQueueConsumer.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/memory/InMemoryTbQueueConsumer.java
@@ -64,6 +64,7 @@ public class InMemoryTbQueueConsumer implements TbQueueCon
@Override
public List poll(long durationInMillis) {
if (subscribed) {
+ @SuppressWarnings("unchecked")
List messages = partitions
.stream()
.map(tpi -> {
diff --git a/common/queue/src/main/java/org/thingsboard/server/queue/usagestats/DefaultTbApiUsageClient.java b/common/queue/src/main/java/org/thingsboard/server/queue/usagestats/DefaultTbApiUsageClient.java
index 066475d5ba..01a322f158 100644
--- a/common/queue/src/main/java/org/thingsboard/server/queue/usagestats/DefaultTbApiUsageClient.java
+++ b/common/queue/src/main/java/org/thingsboard/server/queue/usagestats/DefaultTbApiUsageClient.java
@@ -47,6 +47,7 @@ public class DefaultTbApiUsageClient implements TbApiUsageClient {
@Value("${usage.stats.report.interval:10}")
private int interval;
+ @SuppressWarnings("unchecked")
private final ConcurrentMap[] values = new ConcurrentMap[ApiUsageRecordKey.values().length];
private final PartitionService partitionService;
private final SchedulerComponent scheduler;
diff --git a/common/stats/pom.xml b/common/stats/pom.xml
index 205f5c1dc6..005c210b7b 100644
--- a/common/stats/pom.xml
+++ b/common/stats/pom.xml
@@ -79,7 +79,7 @@
org.mockito
- mockito-all
+ mockito-coretest
@@ -89,4 +89,4 @@
-
\ No newline at end of file
+
diff --git a/common/transport/coap/pom.xml b/common/transport/coap/pom.xml
index a8a1ac452a..cea8ddc0ce 100644
--- a/common/transport/coap/pom.xml
+++ b/common/transport/coap/pom.xml
@@ -80,7 +80,7 @@
org.mockito
- mockito-all
+ mockito-coretest
diff --git a/common/transport/http/pom.xml b/common/transport/http/pom.xml
index 2c8a9bbeae..f229627480 100644
--- a/common/transport/http/pom.xml
+++ b/common/transport/http/pom.xml
@@ -73,7 +73,7 @@
org.mockito
- mockito-all
+ mockito-coretest
diff --git a/common/transport/mqtt/pom.xml b/common/transport/mqtt/pom.xml
index 18c2126f07..676593804e 100644
--- a/common/transport/mqtt/pom.xml
+++ b/common/transport/mqtt/pom.xml
@@ -90,7 +90,7 @@
org.mockito
- mockito-all
+ mockito-coretest
diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java
index ec4247b718..c2cf3686e9 100644
--- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java
+++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java
@@ -45,6 +45,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
+import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.CountDownLatch;
@@ -154,7 +155,7 @@ public class MqttSslHandlerProvider {
String credentialsBody = null;
for (X509Certificate cert : chain) {
try {
- String strCert = SslUtil.getX509CertificateString(cert);
+ String strCert = SslUtil.getCertificateString(cert);
String sha3Hash = EncryptionUtil.getSha3Hash(strCert);
final String[] credentialsBodyHolder = new String[1];
CountDownLatch latch = new CountDownLatch(1);
@@ -179,7 +180,7 @@ public class MqttSslHandlerProvider {
credentialsBody = credentialsBodyHolder[0];
break;
}
- } catch (InterruptedException | IOException e) {
+ } catch (InterruptedException | CertificateEncodingException e) {
log.error(e.getMessage(), e);
}
}
diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java
index 8a8fcff2a4..06a8dcacdc 100644
--- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java
+++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java
@@ -35,6 +35,7 @@ import io.netty.handler.codec.mqtt.MqttSubscribeMessage;
import io.netty.handler.codec.mqtt.MqttTopicSubscription;
import io.netty.handler.codec.mqtt.MqttUnsubscribeMessage;
import io.netty.handler.ssl.SslHandler;
+import io.netty.util.CharsetUtil;
import io.netty.util.ReferenceCountUtil;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
@@ -68,7 +69,8 @@ import org.thingsboard.server.transport.mqtt.session.MqttTopicMatcher;
import org.thingsboard.server.transport.mqtt.util.SslUtil;
import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.security.cert.X509Certificate;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
@@ -315,7 +317,7 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
}
private TransportServiceCallback getPubAckCallback(final ChannelHandlerContext ctx, final int msgId, final T msg) {
- return new TransportServiceCallback() {
+ return new TransportServiceCallback<>() {
@Override
public void onSuccess(Void dummy) {
log.trace("[{}] Published msg: {}", sessionId, msg);
@@ -482,12 +484,13 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
if (userName != null) {
request.setUserName(userName);
}
- String password = connectMessage.payload().password();
- if (password != null) {
+ byte[] passwordBytes = connectMessage.payload().passwordInBytes();
+ if (passwordBytes != null) {
+ String password = new String(passwordBytes, CharsetUtil.UTF_8);
request.setPassword(password);
}
transportService.process(DeviceTransportType.MQTT, request.build(),
- new TransportServiceCallback() {
+ new TransportServiceCallback<>() {
@Override
public void onSuccess(ValidateDeviceCredentialsResponse msg) {
onValidateDeviceResponse(msg, ctx, connectMessage);
@@ -507,10 +510,10 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
if (!context.isSkipValidityCheckForClientCert()) {
cert.checkValidity();
}
- String strCert = SslUtil.getX509CertificateString(cert);
+ String strCert = SslUtil.getCertificateString(cert);
String sha3Hash = EncryptionUtil.getSha3Hash(strCert);
transportService.process(DeviceTransportType.MQTT, ValidateDeviceX509CertRequestMsg.newBuilder().setHash(sha3Hash).build(),
- new TransportServiceCallback() {
+ new TransportServiceCallback<>() {
@Override
public void onSuccess(ValidateDeviceCredentialsResponse msg) {
onValidateDeviceResponse(msg, ctx, connectMessage);
@@ -531,9 +534,9 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement
private X509Certificate getX509Certificate() {
try {
- X509Certificate[] certChain = sslHandler.engine().getSession().getPeerCertificateChain();
+ Certificate[] certChain = sslHandler.engine().getSession().getPeerCertificates();
if (certChain.length > 0) {
- return certChain[0];
+ return (X509Certificate) certChain[0];
}
} catch (SSLPeerUnverifiedException e) {
log.warn(e.getMessage());
diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/SslUtil.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/SslUtil.java
index bd0d034c35..f376077b84 100644
--- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/SslUtil.java
+++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/util/SslUtil.java
@@ -20,8 +20,8 @@ import org.springframework.util.Base64Utils;
import org.thingsboard.server.common.msg.EncryptionUtil;
import java.io.IOException;
+import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
-import java.security.cert.X509Certificate;
/**
* @author Valerii Sosliuk
@@ -32,15 +32,8 @@ public class SslUtil {
private SslUtil() {
}
- public static String getX509CertificateString(X509Certificate cert)
- throws CertificateEncodingException, IOException {
- Base64Utils.encodeToString(cert.getEncoded());
- return EncryptionUtil.trimNewLines(Base64Utils.encodeToString(cert.getEncoded()));
- }
-
- public static String getX509CertificateString(javax.security.cert.X509Certificate cert)
- throws javax.security.cert.CertificateEncodingException, IOException {
- Base64Utils.encodeToString(cert.getEncoded());
+ public static String getCertificateString(Certificate cert)
+ throws CertificateEncodingException {
return EncryptionUtil.trimNewLines(Base64Utils.encodeToString(cert.getEncoded()));
}
}
diff --git a/common/transport/mqtt/src/test/java/org/thingsboard/server/transport/mqtt/util/MqttTopicFilterFactoryTest.java b/common/transport/mqtt/src/test/java/org/thingsboard/server/transport/mqtt/util/MqttTopicFilterFactoryTest.java
index 178d174543..cc59d8bd0b 100644
--- a/common/transport/mqtt/src/test/java/org/thingsboard/server/transport/mqtt/util/MqttTopicFilterFactoryTest.java
+++ b/common/transport/mqtt/src/test/java/org/thingsboard/server/transport/mqtt/util/MqttTopicFilterFactoryTest.java
@@ -17,7 +17,7 @@ package org.thingsboard.server.transport.mqtt.util;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.runners.MockitoJUnitRunner;
+import org.mockito.junit.MockitoJUnitRunner;
import javax.script.ScriptException;
diff --git a/common/transport/transport-api/pom.xml b/common/transport/transport-api/pom.xml
index 69a03dd170..60700bc3e7 100644
--- a/common/transport/transport-api/pom.xml
+++ b/common/transport/transport-api/pom.xml
@@ -87,7 +87,7 @@
org.mockito
- mockito-all
+ mockito-coretest
diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/util/ProtoWithFSTService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/util/ProtoWithFSTService.java
index 73ff79634d..a3b65c2248 100644
--- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/util/ProtoWithFSTService.java
+++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/util/ProtoWithFSTService.java
@@ -32,6 +32,7 @@ public class ProtoWithFSTService implements DataDecodingEncodingService {
@Override
public Optional decode(byte[] byteArray) {
try {
+ @SuppressWarnings("unchecked")
T msg = (T) config.asObject(byteArray);
return Optional.of(msg);
} catch (IllegalArgumentException e) {
diff --git a/common/util/pom.xml b/common/util/pom.xml
index 68ad14d2eb..13afe4663a 100644
--- a/common/util/pom.xml
+++ b/common/util/pom.xml
@@ -41,6 +41,10 @@
guavaprovided
+
+ javax.annotation
+ javax.annotation-api
+ org.slf4jslf4j-api
@@ -64,7 +68,7 @@
org.mockito
- mockito-all
+ mockito-coretest
diff --git a/dao/pom.xml b/dao/pom.xml
index e9ee4e9219..cbd3899f25 100644
--- a/dao/pom.xml
+++ b/dao/pom.xml
@@ -92,7 +92,7 @@
org.mockito
- mockito-all
+ mockito-coretest
diff --git a/dao/src/main/java/org/thingsboard/server/dao/DaoUtil.java b/dao/src/main/java/org/thingsboard/server/dao/DaoUtil.java
index 445cf1c897..8f7071eadc 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/DaoUtil.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/DaoUtil.java
@@ -40,11 +40,11 @@ public abstract class DaoUtil {
public static PageData toPageData(Page extends ToData> page) {
List data = convertDataList(page.getContent());
- return new PageData(data, page.getTotalPages(), page.getTotalElements(), page.hasNext());
+ return new PageData<>(data, page.getTotalPages(), page.getTotalElements(), page.hasNext());
}
public static PageData pageToPageData(Page page) {
- return new PageData(page.getContent(), page.getTotalPages(), page.getTotalElements(), page.hasNext());
+ return new PageData<>(page.getContent(), page.getTotalPages(), page.getTotalElements(), page.hasNext());
}
public static Pageable toPageable(PageLink pageLink) {
diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java
index b239b8e9f8..9af4dc4749 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java
@@ -306,7 +306,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
));
}
return Futures.transform(Futures.successfulAsList(alarmFutures),
- alarmInfos -> new PageData(alarmInfos, alarms.getTotalPages(), alarms.getTotalElements(),
+ alarmInfos -> new PageData<>(alarmInfos, alarms.getTotalPages(), alarms.getTotalElements(),
alarms.hasNext()), MoreExecutors.directExecutor());
}
return Futures.immediateFuture(alarms);
diff --git a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java
index 8e0490b2c7..27eca316f9 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/audit/AuditLogServiceImpl.java
@@ -190,6 +190,7 @@ public class AuditLogServiceImpl implements AuditLogService {
case ATTRIBUTES_UPDATED:
actionData.put("entityId", entityId.toString());
String scope = extractParameter(String.class, 0, additionalInfo);
+ @SuppressWarnings("unchecked")
List attributes = extractParameter(List.class, 1, additionalInfo);
actionData.put("scope", scope);
ObjectNode attrsNode = JacksonUtil.newObjectNode();
@@ -205,6 +206,7 @@ public class AuditLogServiceImpl implements AuditLogService {
actionData.put("entityId", entityId.toString());
scope = extractParameter(String.class, 0, additionalInfo);
actionData.put("scope", scope);
+ @SuppressWarnings("unchecked")
List keys = extractParameter(List.class, 1, additionalInfo);
ArrayNode attrsArrayNode = actionData.putArray("attributes");
if (keys != null) {
@@ -267,6 +269,7 @@ public class AuditLogServiceImpl implements AuditLogService {
break;
case TIMESERIES_UPDATED:
actionData.put("entityId", entityId.toString());
+ @SuppressWarnings("unchecked")
List updatedTimeseries = extractParameter(List.class, 0, additionalInfo);
if (updatedTimeseries != null) {
ArrayNode result = actionData.putArray("timeseries");
@@ -283,6 +286,7 @@ public class AuditLogServiceImpl implements AuditLogService {
break;
case TIMESERIES_DELETED:
actionData.put("entityId", entityId.toString());
+ @SuppressWarnings("unchecked")
List timeseriesKeys = extractParameter(List.class, 0, additionalInfo);
if (timeseriesKeys != null) {
ArrayNode timeseriesArrayNode = actionData.putArray("timeseries");
diff --git a/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java
index e19e580b9e..46190464db 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/audit/DummyAuditLogServiceImpl.java
@@ -36,22 +36,22 @@ public class DummyAuditLogServiceImpl implements AuditLogService {
@Override
public PageData findAuditLogsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, List actionTypes, TimePageLink pageLink) {
- return new PageData();
+ return new PageData<>();
}
@Override
public PageData findAuditLogsByTenantIdAndUserId(TenantId tenantId, UserId userId, List actionTypes, TimePageLink pageLink) {
- return new PageData();
+ return new PageData<>();
}
@Override
public PageData findAuditLogsByTenantIdAndEntityId(TenantId tenantId, EntityId entityId, List actionTypes, TimePageLink pageLink) {
- return new PageData();
+ return new PageData<>();
}
@Override
public PageData findAuditLogsByTenantId(TenantId tenantId, List actionTypes, TimePageLink pageLink) {
- return new PageData();
+ return new PageData<>();
}
@Override
diff --git a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java
index db7dc6bd2d..5b6ae32437 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java
@@ -275,6 +275,7 @@ public class EntityViewServiceImpl extends AbstractEntityService implements Enti
tenantIdAndEntityId.add(entityId);
Cache cache = cacheManager.getCache(ENTITY_VIEW_CACHE);
+ @SuppressWarnings("unchecked")
List fromCache = cache.get(tenantIdAndEntityId, List.class);
if (fromCache != null) {
return Futures.immediateFuture(fromCache);
diff --git a/dao/src/main/java/org/thingsboard/server/dao/oauth2/HybridClientRegistrationRepository.java b/dao/src/main/java/org/thingsboard/server/dao/oauth2/HybridClientRegistrationRepository.java
index 1639074338..7361dc21d2 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/oauth2/HybridClientRegistrationRepository.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/oauth2/HybridClientRegistrationRepository.java
@@ -53,7 +53,7 @@ public class HybridClientRegistrationRepository implements ClientRegistrationRep
.userNameAttributeName(localClientRegistration.getUserNameAttributeName())
.jwkSetUri(localClientRegistration.getJwkSetUri())
.clientAuthenticationMethod(new ClientAuthenticationMethod(localClientRegistration.getClientAuthenticationMethod()))
- .redirectUriTemplate(defaultRedirectUriTemplate)
+ .redirectUri(defaultRedirectUriTemplate)
.build();
}
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java
index 9b936b94e8..1fa9f057b2 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java
@@ -301,6 +301,7 @@ public class BaseRelationService implements RelationService {
fromAndTypeGroup.add(EntitySearchDirection.FROM.name());
Cache cache = cacheManager.getCache(RELATIONS_CACHE);
+ @SuppressWarnings("unchecked")
List fromCache = cache.get(fromAndTypeGroup, List.class);
if (fromCache != null) {
return Futures.immediateFuture(fromCache);
@@ -382,6 +383,7 @@ public class BaseRelationService implements RelationService {
toAndTypeGroup.add(EntitySearchDirection.TO.name());
Cache cache = cacheManager.getCache(RELATIONS_CACHE);
+ @SuppressWarnings("unchecked")
List fromCache = cache.get(toAndTypeGroup, List.class);
if (fromCache != null) {
return Futures.immediateFuture(fromCache);
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardInfoDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardInfoDao.java
index 3e6c5818ad..6d026327dd 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardInfoDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/dashboard/JpaDashboardInfoDao.java
@@ -45,12 +45,12 @@ public class JpaDashboardInfoDao extends JpaAbstractSearchTextDao getEntityClass() {
return DashboardInfoEntity.class;
}
@Override
- protected CrudRepository getCrudRepository() {
+ protected CrudRepository getCrudRepository() {
return dashboardInfoRepository;
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceProfileDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceProfileDao.java
index 70136aa216..92085d44f4 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceProfileDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/device/JpaDeviceProfileDao.java
@@ -15,7 +15,7 @@
*/
package org.thingsboard.server.dao.sql.device;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/relation/RelationRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/relation/RelationRepository.java
index a27b39ced0..c5a1774ae6 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/relation/RelationRepository.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/relation/RelationRepository.java
@@ -49,7 +49,7 @@ public interface RelationRepository
String fromType);
@Transactional
- RelationEntity save(RelationEntity entity);
+ S save(S entity);
@Transactional
void deleteById(RelationCompositeKey id);
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleChainDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleChainDao.java
index 0a750778e3..66907fea5f 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleChainDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleChainDao.java
@@ -39,12 +39,12 @@ public class JpaRuleChainDao extends JpaAbstractSearchTextDao getEntityClass() {
return RuleChainEntity.class;
}
@Override
- protected CrudRepository getCrudRepository() {
+ protected CrudRepository getCrudRepository() {
return ruleChainRepository;
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java
index b99d26ebe0..362299f9b3 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeDao.java
@@ -24,6 +24,8 @@ import org.thingsboard.server.dao.model.sql.RuleNodeEntity;
import org.thingsboard.server.dao.rule.RuleNodeDao;
import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
+import java.util.UUID;
+
@Slf4j
@Component
public class JpaRuleNodeDao extends JpaAbstractSearchTextDao implements RuleNodeDao {
@@ -32,12 +34,12 @@ public class JpaRuleNodeDao extends JpaAbstractSearchTextDao getEntityClass() {
return RuleNodeEntity.class;
}
@Override
- protected CrudRepository getCrudRepository() {
+ protected CrudRepository getCrudRepository() {
return ruleNodeRepository;
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeStateDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeStateDao.java
index 3f1647b155..2be895bf86 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeStateDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaRuleNodeStateDao.java
@@ -39,12 +39,12 @@ public class JpaRuleNodeStateDao extends JpaAbstractDao getEntityClass() {
return RuleNodeStateEntity.class;
}
@Override
- protected CrudRepository getCrudRepository() {
+ protected CrudRepository getCrudRepository() {
return ruleNodeStateRepository;
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java
index 4bf2f48a85..09e4bb55ae 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/RuleNodeRepository.java
@@ -18,6 +18,8 @@ package org.thingsboard.server.dao.sql.rule;
import org.springframework.data.repository.CrudRepository;
import org.thingsboard.server.dao.model.sql.RuleNodeEntity;
-public interface RuleNodeRepository extends CrudRepository {
+import java.util.UUID;
+
+public interface RuleNodeRepository extends CrudRepository {
}
diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java
index f0888055f2..2f817634c3 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java
@@ -32,6 +32,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
+import org.springframework.core.env.Profiles;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
@@ -108,7 +109,7 @@ public class CassandraBaseTimeseriesDao extends AbstractCassandraBaseTimeseriesD
private PreparedStatement deletePartitionStmt;
private boolean isInstall() {
- return environment.acceptsProfiles("install");
+ return environment.acceptsProfiles(Profiles.of("install"));
}
@PostConstruct
diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java
index 519092274b..4efff2582e 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/user/UserServiceImpl.java
@@ -15,8 +15,8 @@
*/
package org.thingsboard.server.dao.user;
+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.ObjectNode;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j;
@@ -48,6 +48,7 @@ import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.service.PaginatedRemover;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.dao.tenant.TenantDao;
+import org.thingsboard.server.dao.util.mapping.JacksonUtil;
import java.util.HashMap;
import java.util.Map;
@@ -71,8 +72,6 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
private static final String USER_CREDENTIALS_ENABLED = "userCredentialsEnabled";
- private static final ObjectMapper objectMapper = new ObjectMapper();
-
@Value("${security.user_login_case_sensitive:true}")
private boolean userLoginCaseSensitive;
@@ -279,7 +278,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
User user = findUserById(tenantId, userId);
JsonNode additionalInfo = user.getAdditionalInfo();
if (!(additionalInfo instanceof ObjectNode)) {
- additionalInfo = objectMapper.createObjectNode();
+ additionalInfo = JacksonUtil.newObjectNode();
}
((ObjectNode) additionalInfo).put(USER_CREDENTIALS_ENABLED, enabled);
user.setAdditionalInfo(additionalInfo);
@@ -302,7 +301,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
private void setLastLoginTs(User user) {
JsonNode additionalInfo = user.getAdditionalInfo();
if (!(additionalInfo instanceof ObjectNode)) {
- additionalInfo = objectMapper.createObjectNode();
+ additionalInfo = JacksonUtil.newObjectNode();
}
((ObjectNode) additionalInfo).put(LAST_LOGIN_TS, System.currentTimeMillis());
user.setAdditionalInfo(additionalInfo);
@@ -311,7 +310,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
private void resetFailedLoginAttempts(User user) {
JsonNode additionalInfo = user.getAdditionalInfo();
if (!(additionalInfo instanceof ObjectNode)) {
- additionalInfo = objectMapper.createObjectNode();
+ additionalInfo = JacksonUtil.newObjectNode();
}
((ObjectNode) additionalInfo).put(FAILED_LOGIN_ATTEMPTS, 0);
user.setAdditionalInfo(additionalInfo);
@@ -329,7 +328,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
private int increaseFailedLoginAttempts(User user) {
JsonNode additionalInfo = user.getAdditionalInfo();
if (!(additionalInfo instanceof ObjectNode)) {
- additionalInfo = objectMapper.createObjectNode();
+ additionalInfo = JacksonUtil.newObjectNode();
}
int failedLoginAttempts = 0;
if (additionalInfo.has(FAILED_LOGIN_ATTEMPTS)) {
@@ -353,26 +352,30 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
private void updatePasswordHistory(User user, UserCredentials userCredentials) {
JsonNode additionalInfo = user.getAdditionalInfo();
if (!(additionalInfo instanceof ObjectNode)) {
- additionalInfo = objectMapper.createObjectNode();
+ additionalInfo = JacksonUtil.newObjectNode();
}
+ Map userPasswordHistoryMap = null;
+ JsonNode userPasswordHistoryJson;
if (additionalInfo.has(USER_PASSWORD_HISTORY)) {
- JsonNode userPasswordHistoryJson = additionalInfo.get(USER_PASSWORD_HISTORY);
- Map userPasswordHistoryMap = objectMapper.convertValue(userPasswordHistoryJson, Map.class);
+ userPasswordHistoryJson = additionalInfo.get(USER_PASSWORD_HISTORY);
+ userPasswordHistoryMap = JacksonUtil.convertValue(userPasswordHistoryJson, new TypeReference<>(){});
+ }
+ if (userPasswordHistoryMap != null) {
userPasswordHistoryMap.put(Long.toString(System.currentTimeMillis()), userCredentials.getPassword());
- userPasswordHistoryJson = objectMapper.valueToTree(userPasswordHistoryMap);
+ userPasswordHistoryJson = JacksonUtil.valueToTree(userPasswordHistoryMap);
((ObjectNode) additionalInfo).replace(USER_PASSWORD_HISTORY, userPasswordHistoryJson);
} else {
- Map userPasswordHistoryMap = new HashMap<>();
+ userPasswordHistoryMap = new HashMap<>();
userPasswordHistoryMap.put(Long.toString(System.currentTimeMillis()), userCredentials.getPassword());
- JsonNode userPasswordHistoryJson = objectMapper.valueToTree(userPasswordHistoryMap);
+ userPasswordHistoryJson = JacksonUtil.valueToTree(userPasswordHistoryMap);
((ObjectNode) additionalInfo).set(USER_PASSWORD_HISTORY, userPasswordHistoryJson);
}
user.setAdditionalInfo(additionalInfo);
saveUser(user);
}
- private DataValidator userValidator =
- new DataValidator() {
+ private final DataValidator userValidator =
+ new DataValidator<>() {
@Override
protected void validateCreate(TenantId tenantId, User user) {
if (!user.getTenantId().getId().equals(ModelConstants.NULL_UUID)) {
@@ -452,8 +455,8 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
}
};
- private DataValidator userCredentialsValidator =
- new DataValidator() {
+ private final DataValidator userCredentialsValidator =
+ new DataValidator<>() {
@Override
protected void validateCreate(TenantId tenantId, UserCredentials userCredentials) {
@@ -484,7 +487,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
}
};
- private PaginatedRemover tenantAdminsRemover = new PaginatedRemover() {
+ private final PaginatedRemover tenantAdminsRemover = new PaginatedRemover<>() {
@Override
protected PageData findEntities(TenantId tenantId, TenantId id, PageLink pageLink) {
return userDao.findTenantAdmins(id.getId(), pageLink);
@@ -496,7 +499,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic
}
};
- private PaginatedRemover customerUsersRemover = new PaginatedRemover() {
+ private final PaginatedRemover customerUsersRemover = new PaginatedRemover<>() {
@Override
protected PageData findEntities(TenantId tenantId, CustomerId id, PageLink pageLink) {
return userDao.findCustomerUsers(tenantId.getId(), id.getId(), pageLink);
diff --git a/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JacksonUtil.java b/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JacksonUtil.java
index 1a56ff54e1..43c7318470 100644
--- a/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JacksonUtil.java
+++ b/dao/src/main/java/org/thingsboard/server/dao/util/mapping/JacksonUtil.java
@@ -16,6 +16,7 @@
package org.thingsboard.server.dao.util.mapping;
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.ObjectNode;
@@ -38,6 +39,15 @@ public class JacksonUtil {
}
}
+ public static T convertValue(Object fromValue, TypeReference toValueTypeRef) {
+ try {
+ return fromValue != null ? OBJECT_MAPPER.convertValue(fromValue, toValueTypeRef) : null;
+ } catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("The given object value: "
+ + fromValue + " cannot be converted to " + toValueTypeRef, e);
+ }
+ }
+
public static T fromString(String string, Class clazz) {
try {
return string != null ? OBJECT_MAPPER.readValue(string, clazz) : null;
@@ -72,7 +82,9 @@ public class JacksonUtil {
}
public static T clone(T value) {
- return fromString(toString(value), (Class) value.getClass());
+ @SuppressWarnings("unchecked")
+ Class valueClass = (Class) value.getClass();
+ return fromString(toString(value), valueClass);
}
public static JsonNode valueToTree(T value) {
diff --git a/dao/src/test/java/org/apache/cassandra/io/sstable/Descriptor.java b/dao/src/test/java/org/apache/cassandra/io/sstable/Descriptor.java
index a5e6122537..69a164f729 100644
--- a/dao/src/test/java/org/apache/cassandra/io/sstable/Descriptor.java
+++ b/dao/src/test/java/org/apache/cassandra/io/sstable/Descriptor.java
@@ -244,6 +244,7 @@ public class Descriptor
*
* @return A Descriptor for the SSTable, and the Component remainder.
*/
+ @SuppressWarnings("deprecation")
public static Pair fromFilename(File directory, String name, boolean skipComponent)
{
File parentDirectory = directory != null ? directory : new File(".");
@@ -319,6 +320,7 @@ public class Descriptor
component);
}
+ @SuppressWarnings("deprecation")
public IMetadataSerializer getMetadataSerializer()
{
if (version.hasNewStatsFile())
diff --git a/dao/src/test/java/org/apache/cassandra/io/sstable/format/SSTableFormat.java b/dao/src/test/java/org/apache/cassandra/io/sstable/format/SSTableFormat.java
index af6af442a3..350d27591f 100644
--- a/dao/src/test/java/org/apache/cassandra/io/sstable/format/SSTableFormat.java
+++ b/dao/src/test/java/org/apache/cassandra/io/sstable/format/SSTableFormat.java
@@ -56,6 +56,7 @@ public interface SSTableFormat
return BIG;
}
+ @SuppressWarnings("deprecation")
private Type(String name, SSTableFormat info)
{
//Since format comes right after generation
diff --git a/dao/src/test/java/org/apache/cassandra/io/util/FileUtils.java b/dao/src/test/java/org/apache/cassandra/io/util/FileUtils.java
new file mode 100644
index 0000000000..2609a2c3d0
--- /dev/null
+++ b/dao/src/test/java/org/apache/cassandra/io/util/FileUtils.java
@@ -0,0 +1,760 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cassandra.io.util;
+
+import java.io.*;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileAttributeView;
+import java.nio.file.attribute.FileStoreAttributeView;
+import java.text.DecimalFormat;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
+import java.util.stream.StreamSupport;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.cassandra.concurrent.ScheduledExecutors;
+import org.apache.cassandra.io.FSError;
+import org.apache.cassandra.io.FSErrorHandler;
+import org.apache.cassandra.io.FSReadError;
+import org.apache.cassandra.io.FSWriteError;
+import org.apache.cassandra.io.sstable.CorruptSSTableException;
+import org.apache.cassandra.utils.JVMStabilityInspector;
+
+import static com.google.common.base.Throwables.throwIfUnchecked;
+import static org.apache.cassandra.utils.Throwables.maybeFail;
+import static org.apache.cassandra.utils.Throwables.merge;
+
+public final class FileUtils
+{
+ public static final Charset CHARSET = StandardCharsets.UTF_8;
+
+ private static final Logger logger = LoggerFactory.getLogger(FileUtils.class);
+ public static final long ONE_KB = 1024;
+ public static final long ONE_MB = 1024 * ONE_KB;
+ public static final long ONE_GB = 1024 * ONE_MB;
+ public static final long ONE_TB = 1024 * ONE_GB;
+
+ private static final DecimalFormat df = new DecimalFormat("#.##");
+ public static final boolean isCleanerAvailable = false;
+ private static final AtomicReference> fsErrorHandler = new AtomicReference<>(Optional.empty());
+
+ public static void createHardLink(String from, String to)
+ {
+ createHardLink(new File(from), new File(to));
+ }
+
+ public static void createHardLink(File from, File to)
+ {
+ if (to.exists())
+ throw new RuntimeException("Tried to create duplicate hard link to " + to);
+ if (!from.exists())
+ throw new RuntimeException("Tried to hard link to file that does not exist " + from);
+
+ try
+ {
+ Files.createLink(to.toPath(), from.toPath());
+ }
+ catch (IOException e)
+ {
+ throw new FSWriteError(e, to);
+ }
+ }
+
+ public static File createTempFile(String prefix, String suffix, File directory)
+ {
+ try
+ {
+ return File.createTempFile(prefix, suffix, directory);
+ }
+ catch (IOException e)
+ {
+ throw new FSWriteError(e, directory);
+ }
+ }
+
+ public static File createTempFile(String prefix, String suffix)
+ {
+ return createTempFile(prefix, suffix, new File(System.getProperty("java.io.tmpdir")));
+ }
+
+ public static Throwable deleteWithConfirm(String filePath, boolean expect, Throwable accumulate)
+ {
+ return deleteWithConfirm(new File(filePath), expect, accumulate);
+ }
+
+ public static Throwable deleteWithConfirm(File file, boolean expect, Throwable accumulate)
+ {
+ boolean exists = file.exists();
+ assert exists || !expect : "attempted to delete non-existing file " + file.getName();
+ try
+ {
+ if (exists)
+ Files.delete(file.toPath());
+ }
+ catch (Throwable t)
+ {
+ try
+ {
+ throw new FSWriteError(t, file);
+ }
+ catch (Throwable t2)
+ {
+ accumulate = merge(accumulate, t2);
+ }
+ }
+ return accumulate;
+ }
+
+ public static void deleteWithConfirm(String file)
+ {
+ deleteWithConfirm(new File(file));
+ }
+
+ public static void deleteWithConfirm(File file)
+ {
+ maybeFail(deleteWithConfirm(file, true, null));
+ }
+
+ public static void renameWithOutConfirm(String from, String to)
+ {
+ try
+ {
+ atomicMoveWithFallback(new File(from).toPath(), new File(to).toPath());
+ }
+ catch (IOException e)
+ {
+ if (logger.isTraceEnabled())
+ logger.trace("Could not move file "+from+" to "+to, e);
+ }
+ }
+
+ public static void renameWithConfirm(String from, String to)
+ {
+ renameWithConfirm(new File(from), new File(to));
+ }
+
+ public static void renameWithConfirm(File from, File to)
+ {
+ assert from.exists();
+ if (logger.isTraceEnabled())
+ logger.trace("Renaming {} to {}", from.getPath(), to.getPath());
+ // this is not FSWE because usually when we see it it's because we didn't close the file before renaming it,
+ // and Windows is picky about that.
+ try
+ {
+ atomicMoveWithFallback(from.toPath(), to.toPath());
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(String.format("Failed to rename %s to %s", from.getPath(), to.getPath()), e);
+ }
+ }
+
+ /**
+ * Move a file atomically, if it fails, it falls back to a non-atomic operation
+ * @param from
+ * @param to
+ * @throws IOException
+ */
+ private static void atomicMoveWithFallback(Path from, Path to) throws IOException
+ {
+ try
+ {
+ Files.move(from, to, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE);
+ }
+ catch (AtomicMoveNotSupportedException e)
+ {
+ logger.trace("Could not do an atomic move", e);
+ Files.move(from, to, StandardCopyOption.REPLACE_EXISTING);
+ }
+
+ }
+ public static void truncate(String path, long size)
+ {
+ try(FileChannel channel = FileChannel.open(Paths.get(path), StandardOpenOption.READ, StandardOpenOption.WRITE))
+ {
+ channel.truncate(size);
+ }
+ catch (IOException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void closeQuietly(Closeable c)
+ {
+ try
+ {
+ if (c != null)
+ c.close();
+ }
+ catch (Exception e)
+ {
+ logger.warn("Failed closing {}", c, e);
+ }
+ }
+
+ public static void closeQuietly(AutoCloseable c)
+ {
+ try
+ {
+ if (c != null)
+ c.close();
+ }
+ catch (Exception e)
+ {
+ logger.warn("Failed closing {}", c, e);
+ }
+ }
+
+ public static void close(Closeable... cs) throws IOException
+ {
+ close(Arrays.asList(cs));
+ }
+
+ public static void close(Iterable extends Closeable> cs) throws IOException
+ {
+ Throwable e = null;
+ for (Closeable c : cs)
+ {
+ try
+ {
+ if (c != null)
+ c.close();
+ }
+ catch (Throwable ex)
+ {
+ if (e == null) e = ex;
+ else e.addSuppressed(ex);
+ logger.warn("Failed closing stream {}", c, ex);
+ }
+ }
+ maybeFail(e, IOException.class);
+ }
+
+ public static void closeQuietly(Iterable extends AutoCloseable> cs)
+ {
+ for (AutoCloseable c : cs)
+ {
+ try
+ {
+ if (c != null)
+ c.close();
+ }
+ catch (Exception ex)
+ {
+ logger.warn("Failed closing {}", c, ex);
+ }
+ }
+ }
+
+ public static String getCanonicalPath(String filename)
+ {
+ try
+ {
+ return new File(filename).getCanonicalPath();
+ }
+ catch (IOException e)
+ {
+ throw new FSReadError(e, filename);
+ }
+ }
+
+ public static String getCanonicalPath(File file)
+ {
+ try
+ {
+ return file.getCanonicalPath();
+ }
+ catch (IOException e)
+ {
+ throw new FSReadError(e, file);
+ }
+ }
+
+ /** Return true if file is contained in folder */
+ public static boolean isContained(File folder, File file)
+ {
+ Path folderPath = Paths.get(getCanonicalPath(folder));
+ Path filePath = Paths.get(getCanonicalPath(file));
+
+ return filePath.startsWith(folderPath);
+ }
+
+ /** Convert absolute path into a path relative to the base path */
+ public static String getRelativePath(String basePath, String path)
+ {
+ try
+ {
+ return Paths.get(basePath).relativize(Paths.get(path)).toString();
+ }
+ catch(Exception ex)
+ {
+ String absDataPath = FileUtils.getCanonicalPath(basePath);
+ return Paths.get(absDataPath).relativize(Paths.get(path)).toString();
+ }
+ }
+
+ public static void clean(ByteBuffer buffer)
+ {
+ if (buffer == null)
+ return;
+ }
+
+ public static void createDirectory(String directory)
+ {
+ createDirectory(new File(directory));
+ }
+
+ public static void createDirectory(File directory)
+ {
+ if (!directory.exists())
+ {
+ if (!directory.mkdirs())
+ throw new FSWriteError(new IOException("Failed to mkdirs " + directory), directory);
+ }
+ }
+
+ public static boolean delete(String file)
+ {
+ File f = new File(file);
+ return f.delete();
+ }
+
+ public static void delete(File... files)
+ {
+ if (files == null)
+ {
+ // CASSANDRA-13389: some callers use Files.listFiles() which, on error, silently returns null
+ logger.debug("Received null list of files to delete");
+ return;
+ }
+
+ for ( File file : files )
+ {
+ file.delete();
+ }
+ }
+
+ public static void deleteAsync(final String file)
+ {
+ Runnable runnable = new Runnable()
+ {
+ public void run()
+ {
+ deleteWithConfirm(new File(file));
+ }
+ };
+ ScheduledExecutors.nonPeriodicTasks.execute(runnable);
+ }
+
+ public static void visitDirectory(Path dir, Predicate super File> filter, Consumer super File> consumer)
+ {
+ try (DirectoryStream stream = Files.newDirectoryStream(dir))
+ {
+ StreamSupport.stream(stream.spliterator(), false)
+ .map(Path::toFile)
+ // stream directories are weakly consistent so we always check if the file still exists
+ .filter(f -> f.exists() && (filter == null || filter.test(f)))
+ .forEach(consumer);
+ }
+ catch (IOException|DirectoryIteratorException ex)
+ {
+ logger.error("Failed to list files in {} with exception: {}", dir, ex.getMessage(), ex);
+ }
+ }
+
+ public static String stringifyFileSize(double value)
+ {
+ double d;
+ if ( value >= ONE_TB )
+ {
+ d = value / ONE_TB;
+ String val = df.format(d);
+ return val + " TiB";
+ }
+ else if ( value >= ONE_GB )
+ {
+ d = value / ONE_GB;
+ String val = df.format(d);
+ return val + " GiB";
+ }
+ else if ( value >= ONE_MB )
+ {
+ d = value / ONE_MB;
+ String val = df.format(d);
+ return val + " MiB";
+ }
+ else if ( value >= ONE_KB )
+ {
+ d = value / ONE_KB;
+ String val = df.format(d);
+ return val + " KiB";
+ }
+ else
+ {
+ String val = df.format(value);
+ return val + " bytes";
+ }
+ }
+
+ /**
+ * Deletes all files and subdirectories under "dir".
+ * @param dir Directory to be deleted
+ * @throws FSWriteError if any part of the tree cannot be deleted
+ */
+ public static void deleteRecursive(File dir)
+ {
+ if (dir.isDirectory())
+ {
+ String[] children = dir.list();
+ for (String child : children)
+ deleteRecursive(new File(dir, child));
+ }
+
+ // The directory is now empty so now it can be smoked
+ deleteWithConfirm(dir);
+ }
+
+ /**
+ * Schedules deletion of all file and subdirectories under "dir" on JVM shutdown.
+ * @param dir Directory to be deleted
+ */
+ public static void deleteRecursiveOnExit(File dir)
+ {
+ if (dir.isDirectory())
+ {
+ String[] children = dir.list();
+ for (String child : children)
+ deleteRecursiveOnExit(new File(dir, child));
+ }
+
+ logger.trace("Scheduling deferred deletion of file: {}", dir);
+ dir.deleteOnExit();
+ }
+
+ public static void handleCorruptSSTable(CorruptSSTableException e)
+ {
+ fsErrorHandler.get().ifPresent(handler -> handler.handleCorruptSSTable(e));
+ }
+
+ public static void handleFSError(FSError e)
+ {
+ fsErrorHandler.get().ifPresent(handler -> handler.handleFSError(e));
+ }
+
+ /**
+ * handleFSErrorAndPropagate will invoke the disk failure policy error handler,
+ * which may or may not stop the daemon or transports. However, if we don't exit,
+ * we still want to propagate the exception to the caller in case they have custom
+ * exception handling
+ *
+ * @param e A filesystem error
+ */
+ public static void handleFSErrorAndPropagate(FSError e)
+ {
+ JVMStabilityInspector.inspectThrowable(e);
+ throwIfUnchecked(e);
+ throw new RuntimeException(e);
+ }
+
+ /**
+ * Get the size of a directory in bytes
+ * @param folder The directory for which we need size.
+ * @return The size of the directory
+ */
+ public static long folderSize(File folder)
+ {
+ final long [] sizeArr = {0L};
+ try
+ {
+ Files.walkFileTree(folder.toPath(), new SimpleFileVisitor()
+ {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ {
+ sizeArr[0] += attrs.size();
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+ catch (IOException e)
+ {
+ logger.error("Error while getting {} folder size. {}", folder, e);
+ }
+ return sizeArr[0];
+ }
+
+ public static void copyTo(DataInput in, OutputStream out, int length) throws IOException
+ {
+ byte[] buffer = new byte[64 * 1024];
+ int copiedBytes = 0;
+
+ while (copiedBytes + buffer.length < length)
+ {
+ in.readFully(buffer);
+ out.write(buffer);
+ copiedBytes += buffer.length;
+ }
+
+ if (copiedBytes < length)
+ {
+ int left = length - copiedBytes;
+ in.readFully(buffer, 0, left);
+ out.write(buffer, 0, left);
+ }
+ }
+
+ public static boolean isSubDirectory(File parent, File child) throws IOException
+ {
+ parent = parent.getCanonicalFile();
+ child = child.getCanonicalFile();
+
+ File toCheck = child;
+ while (toCheck != null)
+ {
+ if (parent.equals(toCheck))
+ return true;
+ toCheck = toCheck.getParentFile();
+ }
+ return false;
+ }
+
+ public static void append(File file, String ... lines)
+ {
+ if (file.exists())
+ write(file, Arrays.asList(lines), StandardOpenOption.APPEND);
+ else
+ write(file, Arrays.asList(lines), StandardOpenOption.CREATE);
+ }
+
+ public static void appendAndSync(File file, String ... lines)
+ {
+ if (file.exists())
+ write(file, Arrays.asList(lines), StandardOpenOption.APPEND, StandardOpenOption.SYNC);
+ else
+ write(file, Arrays.asList(lines), StandardOpenOption.CREATE, StandardOpenOption.SYNC);
+ }
+
+ public static void replace(File file, String ... lines)
+ {
+ write(file, Arrays.asList(lines), StandardOpenOption.TRUNCATE_EXISTING);
+ }
+
+ public static void write(File file, List lines, StandardOpenOption ... options)
+ {
+ try
+ {
+ Files.write(file.toPath(),
+ lines,
+ CHARSET,
+ options);
+ }
+ catch (IOException ex)
+ {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public static List readLines(File file)
+ {
+ try
+ {
+ return Files.readAllLines(file.toPath(), CHARSET);
+ }
+ catch (IOException ex)
+ {
+ if (ex instanceof NoSuchFileException)
+ return Collections.emptyList();
+
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public static void setFSErrorHandler(FSErrorHandler handler)
+ {
+ fsErrorHandler.getAndSet(Optional.ofNullable(handler));
+ }
+
+ /**
+ * Returns the size of the specified partition.
+ *
This method handles large file system by returning {@code Long.MAX_VALUE} if the size overflow.
+ * See JDK-8179320 for more information.
+ *
+ * @param file the partition
+ * @return the size, in bytes, of the partition or {@code 0L} if the abstract pathname does not name a partition
+ */
+ public static long getTotalSpace(File file)
+ {
+ return handleLargeFileSystem(file.getTotalSpace());
+ }
+
+ /**
+ * Returns the number of unallocated bytes on the specified partition.
+ *
This method handles large file system by returning {@code Long.MAX_VALUE} if the number of unallocated bytes
+ * overflow. See JDK-8179320 for more information
+ *
+ * @param file the partition
+ * @return the number of unallocated bytes on the partition or {@code 0L}
+ * if the abstract pathname does not name a partition.
+ */
+ public static long getFreeSpace(File file)
+ {
+ return handleLargeFileSystem(file.getFreeSpace());
+ }
+
+ /**
+ * Returns the number of available bytes on the specified partition.
+ *
This method handles large file system by returning {@code Long.MAX_VALUE} if the number of available bytes
+ * overflow. See JDK-8179320 for more information
+ *
+ * @param file the partition
+ * @return the number of available bytes on the partition or {@code 0L}
+ * if the abstract pathname does not name a partition.
+ */
+ public static long getUsableSpace(File file)
+ {
+ return handleLargeFileSystem(file.getUsableSpace());
+ }
+
+ /**
+ * Returns the {@link FileStore} representing the file store where a file
+ * is located. This {@link FileStore} handles large file system by returning {@code Long.MAX_VALUE}
+ * from {@code FileStore#getTotalSpace()}, {@code FileStore#getUnallocatedSpace()} and {@code FileStore#getUsableSpace()}
+ * it the value is bigger than {@code Long.MAX_VALUE}. See JDK-8162520
+ * for more information.
+ *
+ * @param path the path to the file
+ * @return the file store where the file is stored
+ */
+ public static FileStore getFileStore(Path path) throws IOException
+ {
+ return new SafeFileStore(Files.getFileStore(path));
+ }
+
+ /**
+ * Handle large file system by returning {@code Long.MAX_VALUE} when the size overflows.
+ * @param size returned by the Java's FileStore methods
+ * @return the size or {@code Long.MAX_VALUE} if the size was bigger than {@code Long.MAX_VALUE}
+ */
+ private static long handleLargeFileSystem(long size)
+ {
+ return size < 0 ? Long.MAX_VALUE : size;
+ }
+
+ /**
+ * Private constructor as the class contains only static methods.
+ */
+ private FileUtils()
+ {
+ }
+
+ /**
+ * FileStore decorator used to safely handle large file system.
+ *
+ *
Java's FileStore methods (getTotalSpace/getUnallocatedSpace/getUsableSpace) are limited to reporting bytes as
+ * signed long (2^63-1), if the filesystem is any bigger, then the size overflows. {@code SafeFileStore} will
+ * return {@code Long.MAX_VALUE} if the size overflow.