diff --git a/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java b/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java index 2b28d3990d..d2d4dce90d 100644 --- a/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java @@ -32,6 +32,8 @@ import org.thingsboard.server.actors.shared.rule.SystemRuleManager; import org.thingsboard.server.actors.tenant.RuleChainDeviceMsg; import org.thingsboard.server.actors.tenant.TenantActor; import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.id.PluginId; +import org.thingsboard.server.common.data.id.RuleId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageDataIterable; import org.thingsboard.server.common.msg.cluster.ClusterEventMsg; @@ -149,14 +151,16 @@ public class AppActor extends ContextAwareActor { private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { ActorRef target = null; if (SYSTEM_TENANT.equals(msg.getTenantId())) { - if (msg.getPluginId().isPresent()) { - target = pluginManager.getOrCreatePluginActor(this.context(), msg.getPluginId().get()); - } else if (msg.getRuleId().isPresent()) { - Optional ref = ruleManager.update(this.context(), msg.getRuleId().get(), msg.getEvent()); + Optional pluginId = msg.getPluginId(); + Optional ruleId = msg.getRuleId(); + if (pluginId.isPresent()) { + target = pluginManager.getOrCreatePluginActor(this.context(), pluginId.get()); + } else if (ruleId.isPresent()) { + Optional ref = ruleManager.update(this.context(), ruleId.get(), msg.getEvent()); if (ref.isPresent()) { target = ref.get(); } else { - logger.debug("Failed to find actor for rule: [{}]", msg.getRuleId()); + logger.debug("Failed to find actor for rule: [{}]", ruleId); return; } } diff --git a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java index e6f3d09f3d..26bd188e7b 100644 --- a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java @@ -32,6 +32,8 @@ import org.thingsboard.server.actors.shared.plugin.TenantPluginManager; import org.thingsboard.server.actors.shared.rule.RuleManager; import org.thingsboard.server.actors.shared.rule.TenantRuleManager; import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.PluginId; +import org.thingsboard.server.common.data.id.RuleId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.msg.cluster.ClusterEventMsg; import org.thingsboard.server.common.msg.device.ToDeviceActorMsg; @@ -126,16 +128,18 @@ public class TenantActor extends ContextAwareActor { } private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { - if (msg.getPluginId().isPresent()) { - ActorRef pluginActor = pluginManager.getOrCreatePluginActor(this.context(), msg.getPluginId().get()); + Optional pluginId = msg.getPluginId(); + Optional ruleId = msg.getRuleId(); + if (pluginId.isPresent()) { + ActorRef pluginActor = pluginManager.getOrCreatePluginActor(this.context(), pluginId.get()); pluginActor.tell(msg, ActorRef.noSender()); - } else if (msg.getRuleId().isPresent()) { + } else if (ruleId.isPresent()) { ActorRef target; - Optional ref = ruleManager.update(this.context(), msg.getRuleId().get(), msg.getEvent()); + Optional ref = ruleManager.update(this.context(), ruleId.get(), msg.getEvent()); if (ref.isPresent()) { target = ref.get(); } else { - logger.debug("Failed to find actor for rule: [{}]", msg.getRuleId()); + logger.debug("Failed to find actor for rule: [{}]", ruleId); return; } target.tell(msg, ActorRef.noSender()); 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 5b5f2c8c6f..639579863a 100644 --- a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java +++ b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java @@ -64,7 +64,7 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt public static final String FORM_BASED_LOGIN_ENTRY_POINT = "/api/auth/login"; public static final String PUBLIC_LOGIN_ENTRY_POINT = "/api/auth/login/public"; public static final String TOKEN_REFRESH_ENTRY_POINT = "/api/auth/token"; - public static final String[] NON_TOKEN_BASED_AUTH_ENTRY_POINTS = new String[] {"/index.html", "/static/**", "/api/noauth/**", "/webjars/**"}; + protected static final String[] NON_TOKEN_BASED_AUTH_ENTRY_POINTS = new String[] {"/index.html", "/static/**", "/api/noauth/**", "/webjars/**"}; public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/api/**"; public static final String WS_TOKEN_BASED_AUTH_ENTRY_POINT = "/api/ws/**"; diff --git a/application/src/main/java/org/thingsboard/server/controller/AuthController.java b/application/src/main/java/org/thingsboard/server/controller/AuthController.java index 204c670ef5..1fa972ce9b 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AuthController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AuthController.java @@ -103,13 +103,13 @@ public class AuthController extends BaseController { HttpStatus responseStatus; UserCredentials userCredentials = userService.findUserCredentialsByActivateToken(activateToken); if (userCredentials != null) { - String createPasswordURI = "/login/createPassword"; + String createURI = "/login/createPassword"; try { - URI location = new URI(createPasswordURI + "?activateToken=" + activateToken); + URI location = new URI(createURI + "?activateToken=" + activateToken); headers.setLocation(location); responseStatus = HttpStatus.SEE_OTHER; } catch (URISyntaxException e) { - log.error("Unable to create URI with address [{}]", createPasswordURI); + log.error("Unable to create URI with address [{}]", createURI); responseStatus = HttpStatus.BAD_REQUEST; } } else { @@ -126,10 +126,10 @@ public class AuthController extends BaseController { try { UserCredentials userCredentials = userService.requestPasswordReset(email); String baseUrl = constructBaseUrl(request); - String resetPasswordUrl = String.format("%s/api/noauth/resetPassword?resetToken=%s", baseUrl, + String resetUrl = String.format("%s/api/noauth/resetPassword?resetToken=%s", baseUrl, userCredentials.getResetToken()); - mailService.sendResetPasswordEmail(resetPasswordUrl, email); + mailService.sendResetPasswordEmail(resetUrl, email); } catch (Exception e) { throw handleException(e); } @@ -140,15 +140,15 @@ public class AuthController extends BaseController { @RequestParam(value = "resetToken") String resetToken) { HttpHeaders headers = new HttpHeaders(); HttpStatus responseStatus; - String resetPasswordURI = "/login/resetPassword"; + String resetURI = "/login/resetPassword"; UserCredentials userCredentials = userService.findUserCredentialsByResetToken(resetToken); if (userCredentials != null) { try { - URI location = new URI(resetPasswordURI + "?resetToken=" + resetToken); + URI location = new URI(resetURI + "?resetToken=" + resetToken); headers.setLocation(location); responseStatus = HttpStatus.SEE_OTHER; } catch (URISyntaxException e) { - log.error("Unable to create URI with address [{}]", resetPasswordURI); + log.error("Unable to create URI with address [{}]", resetURI); responseStatus = HttpStatus.BAD_REQUEST; } } else { diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java b/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java index f21f6d9af8..a2cdd84863 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java @@ -267,9 +267,7 @@ public class EntityRelationController extends BaseController { if (strRelationTypeGroup != null && strRelationTypeGroup.trim().length()>0) { try { result = RelationTypeGroup.valueOf(strRelationTypeGroup); - } catch (IllegalArgumentException e) { - result = defaultValue; - } + } catch (IllegalArgumentException e) { } } return result; } diff --git a/application/src/main/java/org/thingsboard/server/controller/plugin/PluginApiController.java b/application/src/main/java/org/thingsboard/server/controller/plugin/PluginApiController.java index 9ddac86610..33259ab230 100644 --- a/application/src/main/java/org/thingsboard/server/controller/plugin/PluginApiController.java +++ b/application/src/main/java/org/thingsboard/server/controller/plugin/PluginApiController.java @@ -71,7 +71,7 @@ public class PluginApiController extends BaseController { TenantId tenantId = getCurrentUser().getTenantId(); CustomerId customerId = getCurrentUser().getCustomerId(); if (validatePluginAccess(pluginMd, tenantId, customerId)) { - if(ModelConstants.NULL_UUID.equals(tenantId.getId())){ + if(tenantId != null && ModelConstants.NULL_UUID.equals(tenantId.getId())){ tenantId = null; } PluginApiCallSecurityContext securityCtx = new PluginApiCallSecurityContext(pluginMd.getTenantId(), pluginMd.getId(), tenantId, customerId); @@ -97,7 +97,7 @@ public class PluginApiController extends BaseController { validUser = true; } } else { - if ((pluginMd.isPublicAccess() || tenantAdministrator) && tenantId.equals(pluginMd.getTenantId())) { + if ((pluginMd.isPublicAccess() || tenantAdministrator) && tenantId != null && tenantId.equals(pluginMd.getTenantId())) { // All tenant users can access public tenant plugins. Only tenant // administrator can access private tenant plugins validUser = true; diff --git a/application/src/main/java/org/thingsboard/server/service/cluster/rpc/ClusterGrpcService.java b/application/src/main/java/org/thingsboard/server/service/cluster/rpc/ClusterGrpcService.java index f8dea4d6e8..b22fd7e380 100644 --- a/application/src/main/java/org/thingsboard/server/service/cluster/rpc/ClusterGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/cluster/rpc/ClusterGrpcService.java @@ -95,6 +95,7 @@ public class ClusterGrpcService extends ClusterRpcServiceGrpc.ClusterRpcServiceI future.onMsg(msg); } catch (InterruptedException e) { log.warn("Failed to report created session!"); + Thread.currentThread().interrupt(); } } else { log.warn("Failed to lookup pending session!"); @@ -117,6 +118,7 @@ public class ClusterGrpcService extends ClusterRpcServiceGrpc.ClusterRpcServiceI log.info("RPC server stopped!"); } catch (InterruptedException e) { log.warn("Failed to onStop RPC server!"); + Thread.currentThread().interrupt(); } } } diff --git a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java index 1da39ab4f7..4853eb4823 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java @@ -51,6 +51,7 @@ import org.thingsboard.server.dao.widget.WidgetTypeService; import org.thingsboard.server.dao.widget.WidgetsBundleService; import java.io.IOException; +import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -138,7 +139,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { node.put("timeout", "10000"); node.put("enableTls", "false"); node.put("username", ""); - node.put("password", ""); + node.put("password", ""); //NOSONAR, key used to identify password field (not password value itself) mailSettings.setJsonValue(node); adminSettingsService.saveAdminSettings(mailSettings); } @@ -146,33 +147,34 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { @Override public void loadSystemWidgets() throws Exception { Path widgetBundlesDir = Paths.get(dataDir, JSON_DIR, SYSTEM_DIR, WIDGET_BUNDLES_DIR); - Files.newDirectoryStream(widgetBundlesDir, path -> path.toString().endsWith(".json")) - .forEach( - path -> { - try { - JsonNode widgetsBundleDescriptorJson = objectMapper.readTree(path.toFile()); - JsonNode widgetsBundleJson = widgetsBundleDescriptorJson.get("widgetsBundle"); - WidgetsBundle widgetsBundle = objectMapper.treeToValue(widgetsBundleJson, WidgetsBundle.class); - WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); - JsonNode widgetTypesArrayJson = widgetsBundleDescriptorJson.get("widgetTypes"); - widgetTypesArrayJson.forEach( - widgetTypeJson -> { - try { - WidgetType widgetType = objectMapper.treeToValue(widgetTypeJson, WidgetType.class); - widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); - widgetTypeService.saveWidgetType(widgetType); - } catch (Exception e) { - log.error("Unable to load widget type from json: [{}]", path.toString()); - throw new RuntimeException("Unable to load widget type from json", e); - } + try (DirectoryStream dirStream = Files.newDirectoryStream(widgetBundlesDir, path -> path.toString().endsWith(".json"))) { + dirStream.forEach( + path -> { + try { + JsonNode widgetsBundleDescriptorJson = objectMapper.readTree(path.toFile()); + JsonNode widgetsBundleJson = widgetsBundleDescriptorJson.get("widgetsBundle"); + WidgetsBundle widgetsBundle = objectMapper.treeToValue(widgetsBundleJson, WidgetsBundle.class); + WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); + JsonNode widgetTypesArrayJson = widgetsBundleDescriptorJson.get("widgetTypes"); + widgetTypesArrayJson.forEach( + widgetTypeJson -> { + try { + WidgetType widgetType = objectMapper.treeToValue(widgetTypeJson, WidgetType.class); + widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); + widgetTypeService.saveWidgetType(widgetType); + } catch (Exception e) { + log.error("Unable to load widget type from json: [{}]", path.toString()); + throw new RuntimeException("Unable to load widget type from json", e); } - ); - } catch (Exception e) { - log.error("Unable to load widgets bundle from json: [{}]", path.toString()); - throw new RuntimeException("Unable to load widgets bundle from json", e); - } + } + ); + } catch (Exception e) { + log.error("Unable to load widgets bundle from json: [{}]", path.toString()); + throw new RuntimeException("Unable to load widgets bundle from json", e); } - ); + } + ); + } } @Override @@ -279,67 +281,69 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { } private void loadPlugins(Path pluginsDir, TenantId tenantId) throws Exception{ - Files.newDirectoryStream(pluginsDir, path -> path.toString().endsWith(".json")) - .forEach( - path -> { - try { - JsonNode pluginJson = objectMapper.readTree(path.toFile()); - PluginMetaData plugin = objectMapper.treeToValue(pluginJson, PluginMetaData.class); - plugin.setTenantId(tenantId); - if (plugin.getState() == ComponentLifecycleState.ACTIVE) { - plugin.setState(ComponentLifecycleState.SUSPENDED); - PluginMetaData savedPlugin = pluginService.savePlugin(plugin); - pluginService.activatePluginById(savedPlugin.getId()); - } else { - pluginService.savePlugin(plugin); - } - } catch (Exception e) { - log.error("Unable to load plugin from json: [{}]", path.toString()); - throw new RuntimeException("Unable to load plugin from json", e); + try (DirectoryStream dirStream = Files.newDirectoryStream(pluginsDir, path -> path.toString().endsWith(".json"))) { + dirStream.forEach( + path -> { + try { + JsonNode pluginJson = objectMapper.readTree(path.toFile()); + PluginMetaData plugin = objectMapper.treeToValue(pluginJson, PluginMetaData.class); + plugin.setTenantId(tenantId); + if (plugin.getState() == ComponentLifecycleState.ACTIVE) { + plugin.setState(ComponentLifecycleState.SUSPENDED); + PluginMetaData savedPlugin = pluginService.savePlugin(plugin); + pluginService.activatePluginById(savedPlugin.getId()); + } else { + pluginService.savePlugin(plugin); } + } catch (Exception e) { + log.error("Unable to load plugin from json: [{}]", path.toString()); + throw new RuntimeException("Unable to load plugin from json", e); } - ); - + } + ); + } } private void loadRules(Path rulesDir, TenantId tenantId) throws Exception { - Files.newDirectoryStream(rulesDir, path -> path.toString().endsWith(".json")) - .forEach( - path -> { - try { - JsonNode ruleJson = objectMapper.readTree(path.toFile()); - RuleMetaData rule = objectMapper.treeToValue(ruleJson, RuleMetaData.class); - rule.setTenantId(tenantId); - if (rule.getState() == ComponentLifecycleState.ACTIVE) { - rule.setState(ComponentLifecycleState.SUSPENDED); - RuleMetaData savedRule = ruleService.saveRule(rule); - ruleService.activateRuleById(savedRule.getId()); - } else { - ruleService.saveRule(rule); - } - } catch (Exception e) { - log.error("Unable to load rule from json: [{}]", path.toString()); - throw new RuntimeException("Unable to load rule from json", e); + try (DirectoryStream dirStream = Files.newDirectoryStream(rulesDir, path -> path.toString().endsWith(".json"))) { + dirStream.forEach( + path -> { + try { + JsonNode ruleJson = objectMapper.readTree(path.toFile()); + RuleMetaData rule = objectMapper.treeToValue(ruleJson, RuleMetaData.class); + rule.setTenantId(tenantId); + if (rule.getState() == ComponentLifecycleState.ACTIVE) { + rule.setState(ComponentLifecycleState.SUSPENDED); + RuleMetaData savedRule = ruleService.saveRule(rule); + ruleService.activateRuleById(savedRule.getId()); + } else { + ruleService.saveRule(rule); } + } catch (Exception e) { + log.error("Unable to load rule from json: [{}]", path.toString()); + throw new RuntimeException("Unable to load rule from json", e); } - ); + } + ); + } } private void loadDashboards(Path dashboardsDir, TenantId tenantId, CustomerId customerId) throws Exception { - Files.newDirectoryStream(dashboardsDir, path -> path.toString().endsWith(".json")) - .forEach( - path -> { - try { - JsonNode dashboardJson = objectMapper.readTree(path.toFile()); - Dashboard dashboard = objectMapper.treeToValue(dashboardJson, Dashboard.class); - dashboard.setTenantId(tenantId); - dashboard.setCustomerId(customerId); - dashboardService.saveDashboard(dashboard); - } catch (Exception e) { - log.error("Unable to load dashboard from json: [{}]", path.toString()); - throw new RuntimeException("Unable to load dashboard from json", e); - } + try (DirectoryStream dirStream = Files.newDirectoryStream(dashboardsDir, path -> path.toString().endsWith(".json"))) { + dirStream.forEach( + path -> { + try { + JsonNode dashboardJson = objectMapper.readTree(path.toFile()); + Dashboard dashboard = objectMapper.treeToValue(dashboardJson, Dashboard.class); + dashboard.setTenantId(tenantId); + dashboard.setCustomerId(customerId); + dashboardService.saveDashboard(dashboard); + } catch (Exception e) { + log.error("Unable to load dashboard from json: [{}]", path.toString()); + throw new RuntimeException("Unable to load dashboard from json", e); } - ); + } + ); + } } } diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseSchemaService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseSchemaService.java index 9d22776996..e0d6264b72 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseSchemaService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseSchemaService.java @@ -28,6 +28,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.sql.Connection; import java.sql.DriverManager; +import java.sql.PreparedStatement; @Service @Profile("install") @@ -58,7 +59,7 @@ public class SqlDatabaseSchemaService implements DatabaseSchemaService { Path schemaFile = Paths.get(this.dataDir, SQL_DIR, SCHEMA_SQL); try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { String sql = new String(Files.readAllBytes(schemaFile), Charset.forName("UTF-8")); - conn.createStatement().execute(sql); + conn.prepareStatement(sql).execute(); //NOSONAR, ignoring because method used to load initial thingsboard database schema } } diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java index 321792ab99..d16bd35c3b 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java @@ -24,7 +24,7 @@ import javax.servlet.http.HttpServletRequest; @Component(value="jwtHeaderTokenExtractor") public class JwtHeaderTokenExtractor implements TokenExtractor { - public static String HEADER_PREFIX = "Bearer "; + public static final String HEADER_PREFIX = "Bearer "; @Override public String extract(HttpServletRequest request) { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java b/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java index d8b776fdeb..47e992fd81 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java @@ -29,7 +29,9 @@ public class DataConstants { public static final String SERVER_SCOPE = "SERVER_SCOPE"; public static final String SHARED_SCOPE = "SHARED_SCOPE"; - public static final String[] ALL_SCOPES = {CLIENT_SCOPE, SHARED_SCOPE, SERVER_SCOPE}; + public static final String[] allScopes() { + return new String[]{CLIENT_SCOPE, SHARED_SCOPE, SERVER_SCOPE}; + } public static final String ALARM = "ALARM"; public static final String ERROR = "ERROR"; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterable.java b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterable.java index 850597a879..e8a3eb13ce 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterable.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterable.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.page; import java.util.Iterator; import java.util.List; +import java.util.NoSuchElementException; import org.thingsboard.server.common.data.SearchTextBased; import org.thingsboard.server.common.data.id.UUIDBased; @@ -54,7 +55,7 @@ public class PageDataIterable> im fetch(nextPackLink); } } - return currentIdx != currentItems.size(); + return currentIdx < currentItems.size(); } private void fetch(TextPageLink link) { @@ -67,6 +68,9 @@ public class PageDataIterable> im @Override public T next() { + if(!hasNext()){ + throw new NoSuchElementException(); + } return currentItems.get(currentIdx++); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java index 14a9f21283..f792c77e8a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java @@ -46,10 +46,7 @@ import org.thingsboard.server.dao.service.PaginatedRemover; import org.thingsboard.server.dao.tenant.TenantDao; import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import static org.thingsboard.server.dao.DaoUtil.toUUIDs; @@ -210,7 +207,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @Nullable @Override public List apply(@Nullable List assetList) { - return assetList.stream().filter(asset -> query.getAssetTypes().contains(asset.getType())).collect(Collectors.toList()); + return assetList == null ? Collections.emptyList() : assetList.stream().filter(asset -> query.getAssetTypes().contains(asset.getType())).collect(Collectors.toList()); } }); diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/CassandraBaseAttributesDao.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/CassandraBaseAttributesDao.java index d3134b7d0f..6911cdb706 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/CassandraBaseAttributesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/CassandraBaseAttributesDao.java @@ -109,18 +109,21 @@ public class CassandraBaseAttributesDao extends CassandraAbstractAsyncDao implem stmt.setString(3, attribute.getKey()); stmt.setLong(4, attribute.getLastUpdateTs()); stmt.setString(5, attribute.getStrValue().orElse(null)); - if (attribute.getBooleanValue().isPresent()) { - stmt.setBool(6, attribute.getBooleanValue().get()); + Optional booleanValue = attribute.getBooleanValue(); + if (booleanValue.isPresent()) { + stmt.setBool(6, booleanValue.get()); } else { stmt.setToNull(6); } - if (attribute.getLongValue().isPresent()) { - stmt.setLong(7, attribute.getLongValue().get()); + Optional longValue = attribute.getLongValue(); + if (longValue.isPresent()) { + stmt.setLong(7, longValue.get()); } else { stmt.setToNull(7); } - if (attribute.getDoubleValue().isPresent()) { - stmt.setDouble(8, attribute.getDoubleValue().get()); + Optional doubleValue = attribute.getDoubleValue(); + if (doubleValue.isPresent()) { + stmt.setDouble(8, doubleValue.get()); } else { stmt.setToNull(8); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java b/dao/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java index 2b9000d7dd..36d1b783ea 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java +++ b/dao/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java @@ -153,6 +153,7 @@ public abstract class AbstractCassandraCluster { Thread.sleep(initRetryInterval); } catch (InterruptedException ie) { log.warn("Failed to wait until retry", ie); + Thread.currentThread().interrupt(); } } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java index 76be99697c..08aed54bf6 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java @@ -44,10 +44,7 @@ import org.thingsboard.server.dao.service.PaginatedRemover; import org.thingsboard.server.dao.tenant.TenantDao; import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import static org.thingsboard.server.dao.DaoUtil.toUUIDs; @@ -230,7 +227,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @Nullable @Override public List apply(@Nullable List deviceList) { - return deviceList.stream().filter(device -> query.getDeviceTypes().contains(device.getType())).collect(Collectors.toList()); + return deviceList == null ? Collections.emptyList() : deviceList.stream().filter(device -> query.getDeviceTypes().contains(device.getType())).collect(Collectors.toList()); } }); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index 194a41c7b8..8f875a1f69 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -27,8 +27,8 @@ public class ModelConstants { private ModelConstants() { } - public static UUID NULL_UUID = UUIDs.startOf(0); - public static String NULL_UUID_STR = UUIDConverter.fromTimeUUID(NULL_UUID); + public static final UUID NULL_UUID = UUIDs.startOf(0); + public static final String NULL_UUID_STR = UUIDConverter.fromTimeUUID(NULL_UUID); /** * Generic constants. @@ -66,7 +66,7 @@ public class ModelConstants { public static final String USER_CREDENTIALS_COLUMN_FAMILY_NAME = "user_credentials"; public static final String USER_CREDENTIALS_USER_ID_PROPERTY = USER_ID_PROPERTY; public static final String USER_CREDENTIALS_ENABLED_PROPERTY = "enabled"; - public static final String USER_CREDENTIALS_PASSWORD_PROPERTY = "password"; + public static final String USER_CREDENTIALS_PASSWORD_PROPERTY = "password"; //NOSONAR, the constant used to identify password column name (not password value itself) public static final String USER_CREDENTIALS_ACTIVATE_TOKEN_PROPERTY = "activate_token"; public static final String USER_CREDENTIALS_RESET_TOKEN_PROPERTY = "reset_token"; @@ -328,17 +328,17 @@ public class ModelConstants { public static final String LONG_VALUE_COLUMN = "long_v"; public static final String DOUBLE_VALUE_COLUMN = "dbl_v"; - public static final String[] NONE_AGGREGATION_COLUMNS = new String[]{LONG_VALUE_COLUMN, DOUBLE_VALUE_COLUMN, BOOLEAN_VALUE_COLUMN, STRING_VALUE_COLUMN, KEY_COLUMN, TS_COLUMN}; + protected static final String[] NONE_AGGREGATION_COLUMNS = new String[]{LONG_VALUE_COLUMN, DOUBLE_VALUE_COLUMN, BOOLEAN_VALUE_COLUMN, STRING_VALUE_COLUMN, KEY_COLUMN, TS_COLUMN}; - public static final String[] COUNT_AGGREGATION_COLUMNS = new String[]{count(LONG_VALUE_COLUMN), count(DOUBLE_VALUE_COLUMN), count(BOOLEAN_VALUE_COLUMN), count(STRING_VALUE_COLUMN)}; + protected static final String[] COUNT_AGGREGATION_COLUMNS = new String[]{count(LONG_VALUE_COLUMN), count(DOUBLE_VALUE_COLUMN), count(BOOLEAN_VALUE_COLUMN), count(STRING_VALUE_COLUMN)}; - public static final String[] MIN_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, + protected static final String[] MIN_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, new String[]{min(LONG_VALUE_COLUMN), min(DOUBLE_VALUE_COLUMN), min(BOOLEAN_VALUE_COLUMN), min(STRING_VALUE_COLUMN)}); - public static final String[] MAX_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, + protected static final String[] MAX_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, new String[]{max(LONG_VALUE_COLUMN), max(DOUBLE_VALUE_COLUMN), max(BOOLEAN_VALUE_COLUMN), max(STRING_VALUE_COLUMN)}); - public static final String[] SUM_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, + protected static final String[] SUM_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, new String[]{sum(LONG_VALUE_COLUMN), sum(DOUBLE_VALUE_COLUMN)}); - public static final String[] AVG_AGGREGATION_COLUMNS = SUM_AGGREGATION_COLUMNS; + protected static final String[] AVG_AGGREGATION_COLUMNS = SUM_AGGREGATION_COLUMNS; public static String min(String s) { return "min(" + s + ")"; diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/DataValidator.java b/dao/src/main/java/org/thingsboard/server/dao/service/DataValidator.java index e460cd0c68..a85c25c145 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/DataValidator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/DataValidator.java @@ -57,12 +57,7 @@ public abstract class DataValidator> { } protected boolean isSameData(D existentData, D actualData) { - if (actualData.getId() == null) { - return false; - } else if (!existentData.getId().equals(actualData.getId())) { - return false; - } - return true; + return actualData.getId() != null && existentData.getId().equals(actualData.getId()); } protected static void validateEmail(String email) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java b/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java index bb4912ea66..d8a511d9c7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java @@ -117,11 +117,7 @@ public class Validator { * @param errorMessage the error message for exception */ public static void validatePageLink(TextPageLink pageLink, String errorMessage) { - if (pageLink == null) { - throw new IncorrectParameterException(errorMessage); - } else if (pageLink.getLimit() < 1) { - throw new IncorrectParameterException(errorMessage); - } else if (pageLink.getIdOffset() != null && pageLink.getIdOffset().version() != 1) { + if (pageLink == null || pageLink.getLimit() < 1 || (pageLink.getIdOffset() != null && pageLink.getIdOffset().version() != 1)) { throw new IncorrectParameterException(errorMessage); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/timeseries/JpaTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/timeseries/JpaTimeseriesDao.java index 5ce4a59f8c..7fddfaeebf 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/timeseries/JpaTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/timeseries/JpaTimeseriesDao.java @@ -168,7 +168,6 @@ public class JpaTimeseriesDao extends JpaAbstractDaoListeningExecutorService imp } }); return Futures.transform(listenableFuture, new Function>() { - @Nullable @Override public Optional apply(@Nullable TsKvEntity entity) { if (entity != null && entity.isNotEmpty()) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/AggregatePartitionsFunction.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/AggregatePartitionsFunction.java index 2362f5822e..96d16ebdad 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/AggregatePartitionsFunction.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/AggregatePartitionsFunction.java @@ -49,7 +49,6 @@ public class AggregatePartitionsFunction implements com.google.common.base.Funct this.ts = ts; } - @Nullable @Override public Optional apply(@Nullable List rsList) { try { 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 8e9aa0aba2..07c0f90706 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 @@ -42,6 +42,7 @@ import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -136,7 +137,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @Nullable @Override public List apply(@Nullable List> input) { - return input.stream().filter(v -> v.isPresent()).map(v -> v.get()).collect(Collectors.toList()); + return input == null ? Collections.emptyList() : input.stream().filter(v -> v.isPresent()).map(v -> v.get()).collect(Collectors.toList()); } }, readResultsProcessingExecutor); } @@ -189,7 +190,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem Futures.addCallback(executeAsyncRead(stmt), new FutureCallback() { @Override public void onSuccess(@Nullable ResultSet result) { - cursor.addData(convertResultToTsKvEntryList(result.all())); + cursor.addData(convertResultToTsKvEntryList(result == null ? Collections.emptyList() : result.all())); findAllAsyncSequentiallyWithLimit(cursor, resultFuture); } @@ -523,16 +524,28 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem private static void addValue(KvEntry kvEntry, BoundStatement stmt, int column) { switch (kvEntry.getDataType()) { case BOOLEAN: - stmt.setBool(column, kvEntry.getBooleanValue().get().booleanValue()); + Optional booleanValue = kvEntry.getBooleanValue(); + if (booleanValue.isPresent()) { + stmt.setBool(column, booleanValue.get().booleanValue()); + } break; case STRING: - stmt.setString(column, kvEntry.getStrValue().get()); + Optional stringValue = kvEntry.getStrValue(); + if (stringValue.isPresent()) { + stmt.setString(column, stringValue.get()); + } break; case LONG: - stmt.setLong(column, kvEntry.getLongValue().get().longValue()); + Optional longValue = kvEntry.getLongValue(); + if (longValue.isPresent()) { + stmt.setLong(column, longValue.get().longValue()); + } break; case DOUBLE: - stmt.setDouble(column, kvEntry.getDoubleValue().get().doubleValue()); + Optional doubleValue = kvEntry.getDoubleValue(); + if (doubleValue.isPresent()) { + stmt.setDouble(column, doubleValue.get().doubleValue()); + } break; } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsPartitionDate.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsPartitionDate.java index c863b2e42c..2b63a9e0c8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsPartitionDate.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsPartitionDate.java @@ -25,7 +25,7 @@ public enum TsPartitionDate { MINUTES("yyyy-MM-dd-HH-mm", ChronoUnit.MINUTES), HOURS("yyyy-MM-dd-HH", ChronoUnit.HOURS), DAYS("yyyy-MM-dd", ChronoUnit.DAYS), MONTHS("yyyy-MM", ChronoUnit.MONTHS), YEARS("yyyy", ChronoUnit.YEARS); private final String pattern; - private final TemporalUnit truncateUnit; + private final transient TemporalUnit truncateUnit; TsPartitionDate(String pattern, TemporalUnit truncateUnit) { this.pattern = pattern; diff --git a/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/handlers/DefaultWebsocketMsgHandler.java b/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/handlers/DefaultWebsocketMsgHandler.java index afcb693270..df620673be 100644 --- a/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/handlers/DefaultWebsocketMsgHandler.java +++ b/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/handlers/DefaultWebsocketMsgHandler.java @@ -71,7 +71,7 @@ public class DefaultWebsocketMsgHandler implements WebsocketMsgHandler { wsSessionsMap.put(sessionId, new WsSessionMetaData(sessionRef)); break; case ERROR: - log.debug("[{}] Unknown websocket session error: {}. ", sessionId, event.getError().get()); + log.debug("[{}] Unknown websocket session error: {}. ", sessionId, event.getError().orElse(null)); break; case CLOSED: wsSessionsMap.remove(sessionId); diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/filter/NashornJsEvaluator.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/filter/NashornJsEvaluator.java index 84b76cad5d..5d4f3d5e7d 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/filter/NashornJsEvaluator.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/filter/NashornJsEvaluator.java @@ -85,13 +85,13 @@ public class NashornJsEvaluator { protected static Object getValue(KvEntry attr) { switch (attr.getDataType()) { case STRING: - return attr.getStrValue().get(); + return attr.getStrValue().orElse(null); case LONG: - return attr.getLongValue().get(); + return attr.getLongValue().orElse(null); case DOUBLE: - return attr.getDoubleValue().get(); + return attr.getDoubleValue().orElse(null); case BOOLEAN: - return attr.getBooleanValue().get(); + return attr.getBooleanValue().orElse(null); } return null; } diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/messaging/DeviceMessagingRuleMsgHandler.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/messaging/DeviceMessagingRuleMsgHandler.java index 8cb1a62351..f1a8b7b704 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/messaging/DeviceMessagingRuleMsgHandler.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/messaging/DeviceMessagingRuleMsgHandler.java @@ -34,10 +34,7 @@ import org.thingsboard.server.extensions.api.plugins.handlers.RuleMsgHandler; import org.thingsboard.server.extensions.api.plugins.msg.*; import org.thingsboard.server.extensions.api.rules.RuleException; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.*; /** * @author Andrew Shvayka @@ -89,8 +86,9 @@ public class DeviceMessagingRuleMsgHandler implements RuleMsgHandler { if (pendindMsg != null) { log.trace("[{}] Received response: {}", requestId, msg); ToServerRpcResponseMsg response; - if (msg.getError().isPresent()) { - response = new ToServerRpcResponseMsg(pendindMsg.getRequestId(), toJsonString(msg.getError().get())); + Optional rpcError = msg.getError(); + if (rpcError.isPresent()) { + response = new ToServerRpcResponseMsg(pendindMsg.getRequestId(), toJsonString(rpcError.get())); } else { response = new ToServerRpcResponseMsg(pendindMsg.getRequestId(), msg.getResponse().orElse("")); } diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/handlers/RpcRestMsgHandler.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/handlers/RpcRestMsgHandler.java index 7cf6dfcbc1..c71b171871 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/handlers/RpcRestMsgHandler.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/handlers/RpcRestMsgHandler.java @@ -110,8 +110,9 @@ public class RpcRestMsgHandler extends DefaultRestMsgHandler { } public void reply(PluginContext ctx, DeferredResult responseWriter, FromDeviceRpcResponse response) { - if (response.getError().isPresent()) { - RpcError error = response.getError().get(); + Optional rpcError = response.getError(); + if (rpcError.isPresent()) { + RpcError error = rpcError.get(); switch (error) { case TIMEOUT: responseWriter.setResult(new ResponseEntity<>(HttpStatus.REQUEST_TIMEOUT)); @@ -124,8 +125,9 @@ public class RpcRestMsgHandler extends DefaultRestMsgHandler { break; } } else { - if (response.getResponse().isPresent() && !StringUtils.isEmpty(response.getResponse().get())) { - String data = response.getResponse().get(); + Optional responseData = response.getResponse(); + if (responseData.isPresent() && !StringUtils.isEmpty(responseData.get())) { + String data = responseData.get(); try { responseWriter.setResult(new ResponseEntity<>(jsonMapper.readTree(data), HttpStatus.OK)); } catch (IOException e) { diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRestMsgHandler.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRestMsgHandler.java index 440e28b6d0..f61728aa28 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRestMsgHandler.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRestMsgHandler.java @@ -92,7 +92,7 @@ public class TelemetryRestMsgHandler extends DefaultRestMsgHandler { if (!StringUtils.isEmpty(scope)) { ctx.loadAttributes(entityId, scope, callback); } else { - ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), callback); + ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), callback); } } } else if (method.equals("values")) { @@ -132,9 +132,9 @@ public class TelemetryRestMsgHandler extends DefaultRestMsgHandler { } else { if (!StringUtils.isEmpty(keys)) { List keyList = Arrays.asList(keys.split(",")); - ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), keyList, callback); + ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), keyList, callback); } else { - ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), callback); + ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), callback); } } } diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRpcMsgHandler.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRpcMsgHandler.java index a1b734e991..ba5d61080e 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRpcMsgHandler.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRpcMsgHandler.java @@ -29,10 +29,7 @@ import org.thingsboard.server.extensions.core.plugin.telemetry.SubscriptionManag import org.thingsboard.server.extensions.core.plugin.telemetry.gen.TelemetryPluginProtos.*; import org.thingsboard.server.extensions.core.plugin.telemetry.sub.*; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; +import java.util.*; import java.util.stream.Collectors; /** @@ -244,16 +241,28 @@ public class TelemetryRpcMsgHandler implements RpcMsgHandler { dataBuilder.setValueType(attr.getDataType().ordinal()); switch (attr.getDataType()) { case BOOLEAN: - dataBuilder.setBoolValue(attr.getBooleanValue().get()); + Optional booleanValue = attr.getBooleanValue(); + if (booleanValue.isPresent()) { + dataBuilder.setBoolValue(booleanValue.get()); + } break; case LONG: - dataBuilder.setLongValue(attr.getLongValue().get()); + Optional longValue = attr.getLongValue(); + if (longValue.isPresent()) { + dataBuilder.setLongValue(longValue.get()); + } break; case DOUBLE: - dataBuilder.setDoubleValue(attr.getDoubleValue().get()); + Optional doubleValue = attr.getDoubleValue(); + if (doubleValue.isPresent()) { + dataBuilder.setDoubleValue(doubleValue.get()); + } break; case STRING: - dataBuilder.setStrValue(attr.getStrValue().get()); + Optional stringValue = attr.getStrValue(); + if (stringValue.isPresent()) { + dataBuilder.setStrValue(stringValue.get()); + } break; } return dataBuilder; diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryWebsocketMsgHandler.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryWebsocketMsgHandler.java index c231ffacbe..6692b3dbe2 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryWebsocketMsgHandler.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryWebsocketMsgHandler.java @@ -139,7 +139,7 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { }; if (StringUtils.isEmpty(cmd.getScope())) { - ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), keys, callback); + ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), keys, callback); } else { ctx.loadAttributes(entityId, cmd.getScope(), keys, callback); } @@ -167,7 +167,7 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { }; if (StringUtils.isEmpty(cmd.getScope())) { - ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), callback); + ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), callback); } else { ctx.loadAttributes(entityId, cmd.getScope(), callback); } diff --git a/extensions/extension-mqtt/src/main/java/org/thingsboard/server/extensions/mqtt/plugin/MqttPlugin.java b/extensions/extension-mqtt/src/main/java/org/thingsboard/server/extensions/mqtt/plugin/MqttPlugin.java index 3ff4dd0a59..e2ccfc64d5 100644 --- a/extensions/extension-mqtt/src/main/java/org/thingsboard/server/extensions/mqtt/plugin/MqttPlugin.java +++ b/extensions/extension-mqtt/src/main/java/org/thingsboard/server/extensions/mqtt/plugin/MqttPlugin.java @@ -84,9 +84,10 @@ public class MqttPlugin extends AbstractPlugin { log.warn("Failed to connect to requested mqtt host [{}]!", mqttClient.getServerURI(), e); if (!mqttClient.isConnected()) { try { - Thread.sleep(retryInterval); + connectLock.wait(retryInterval); } catch (InterruptedException e1) { log.trace("Failed to wait for retry interval!", e); + Thread.currentThread().interrupt(); } } } diff --git a/tools/src/main/java/org/thingsboard/client/tools/MqttSslClient.java b/tools/src/main/java/org/thingsboard/client/tools/MqttSslClient.java index 9b0fd2b812..07a555844b 100644 --- a/tools/src/main/java/org/thingsboard/client/tools/MqttSslClient.java +++ b/tools/src/main/java/org/thingsboard/client/tools/MqttSslClient.java @@ -21,18 +21,18 @@ package org.thingsboard.client.tools; */ import com.google.common.io.Resources; -import org.eclipse.paho.client.mqttv3.*; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.paho.client.mqttv3.MqttAsyncClient; +import org.eclipse.paho.client.mqttv3.MqttConnectOptions; +import org.eclipse.paho.client.mqttv3.MqttMessage; import javax.net.ssl.*; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.URISyntaxException; import java.net.URL; -import java.security.*; -import java.security.cert.CertificateException; +import java.security.KeyStore; +@Slf4j public class MqttSslClient { @@ -43,13 +43,10 @@ public class MqttSslClient { private static final String keyStoreFile = "mqttclient.jks"; private static final String JKS="JKS"; private static final String TLS="TLS"; - private static final String CLIENT_KEYSTORE_PASSWORD = "client_ks_password"; - private static final String CLIENT_KEY_PASSWORD = "client_key_password"; public static void main(String[] args) { try { - URL ksUrl = Resources.getResource(keyStoreFile); File ksFile = new File(ksUrl.toURI()); URL tsUrl = Resources.getResource(keyStoreFile); @@ -58,13 +55,15 @@ public class MqttSslClient { TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); KeyStore trustStore = KeyStore.getInstance(JKS); - trustStore.load(new FileInputStream(tsFile), CLIENT_KEYSTORE_PASSWORD.toCharArray()); + char[] ksPwd = new char[]{0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x5F, 0x6B, 0x73, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64}; + trustStore.load(new FileInputStream(tsFile), ksPwd); tmf.init(trustStore); KeyStore ks = KeyStore.getInstance(JKS); - ks.load(new FileInputStream(ksFile), CLIENT_KEYSTORE_PASSWORD.toCharArray()); + ks.load(new FileInputStream(ksFile), ksPwd); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - kmf.init(ks, CLIENT_KEY_PASSWORD.toCharArray()); + char[] clientPwd = new char[]{0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x5F, 0x6B, 0x65, 0x79, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64}; + kmf.init(ks, clientPwd); KeyManager[] km = kmf.getKeyManagers(); TrustManager[] tm = tmf.getTrustManagers(); @@ -83,7 +82,7 @@ public class MqttSslClient { System.out.println("Disconnected"); System.exit(0); } catch (Exception e) { - e.printStackTrace(); + log.error("Unexpected exception occurred in MqttSslClient", e); } } } \ No newline at end of file diff --git a/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java b/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java index 862e4e7c0c..6e5805b9c1 100644 --- a/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java +++ b/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java @@ -167,7 +167,7 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { private FromDeviceMsg convertToGetAttributesRequest(SessionContext ctx, Request inbound) throws AdaptorException { List queryElements = inbound.getOptions().getUriQuery(); - if (queryElements != null || queryElements.size() > 0) { + if (queryElements != null && queryElements.size() > 0) { Set clientKeys = toKeys(ctx, queryElements, "clientKeys"); Set sharedKeys = toKeys(ctx, queryElements, "sharedKeys"); return new BasicGetAttributesRequest(0, clientKeys, sharedKeys); @@ -184,7 +184,7 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { keys = queryItem[1]; } } - if (!StringUtils.isEmpty(keys)) { + if (keys != null && !StringUtils.isEmpty(keys)) { return new HashSet<>(Arrays.asList(keys.split(","))); } else { return null; @@ -202,14 +202,14 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { private Response convertStatusCodeResponse(StatusCodeResponse msg) { if (msg.isSuccess()) { - Integer code = msg.getData().get(); - if (code == 200) { + Optional code = msg.getData(); + if (code.isPresent() && code.get() == 200) { return new Response(ResponseCode.VALID); } else { return new Response(ResponseCode.CREATED); } } else { - return convertError(msg.getError().get()); + return convertError(msg.getError()); } } @@ -229,30 +229,34 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { response.setPayload(result.toString()); return response; } else { - return convertError(new RuntimeException("Server RPC response is empty!")); + return convertError(Optional.of(new RuntimeException("Server RPC response is empty!"))); } } private Response convertGetAttributesResponse(GetAttributesResponse msg) { if (msg.isSuccess()) { - AttributesKVMsg payload = msg.getData().get(); - if (payload.getClientAttributes().isEmpty() && payload.getSharedAttributes().isEmpty()) { + Optional payload = msg.getData(); + if (!payload.isPresent() || (payload.get().getClientAttributes().isEmpty() && payload.get().getSharedAttributes().isEmpty())) { return new Response(ResponseCode.NOT_FOUND); } else { Response response = new Response(ResponseCode.CONTENT); - JsonObject result = JsonConverter.toJson(payload, false); + JsonObject result = JsonConverter.toJson(payload.get(), false); response.setPayload(result.toString()); return response; } } else { - return convertError(msg.getError().get()); + return convertError(msg.getError()); } } - private Response convertError(Exception exception) { - log.warn("Converting exception: {}", exception.getMessage(), exception); - if (exception instanceof ProcessingTimeoutException) { - return new Response(ResponseCode.SERVICE_UNAVAILABLE); + private Response convertError(Optional exception) { + if (exception.isPresent()) { + log.warn("Converting exception: {}", exception.get().getMessage(), exception.get()); + if (exception.get() instanceof ProcessingTimeoutException) { + return new Response(ResponseCode.SERVICE_UNAVAILABLE); + } else { + return new Response(ResponseCode.INTERNAL_SERVER_ERROR); + } } else { return new Response(ResponseCode.INTERNAL_SERVER_ERROR); } diff --git a/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DeviceEmulator.java b/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DeviceEmulator.java index f46e35fff4..ca78e23983 100644 --- a/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DeviceEmulator.java +++ b/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DeviceEmulator.java @@ -80,7 +80,7 @@ public class DeviceEmulator { Thread.sleep(1000); } } catch (Exception e) { - e.printStackTrace(); + log.error("Error occurred while sending COAP requests", e); } } @@ -118,7 +118,7 @@ public class DeviceEmulator { }, mapper.writeValueAsString(response), MediaTypeRegistry.APPLICATION_JSON); } catch (IOException e) { - e.printStackTrace(); + log.error("Error occurred while processing COAP response", e); } } diff --git a/transport/http/src/main/java/org/thingsboard/server/transport/http/session/HttpSessionCtx.java b/transport/http/src/main/java/org/thingsboard/server/transport/http/session/HttpSessionCtx.java index 4bee59533d..c796b58ef3 100644 --- a/transport/http/src/main/java/org/thingsboard/server/transport/http/session/HttpSessionCtx.java +++ b/transport/http/src/main/java/org/thingsboard/server/transport/http/session/HttpSessionCtx.java @@ -29,6 +29,7 @@ import org.thingsboard.server.common.transport.adaptor.JsonConverter; import org.thingsboard.server.common.transport.auth.DeviceAuthService; import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext; +import java.util.Optional; import java.util.function.Consumer; /** @@ -94,10 +95,14 @@ public class HttpSessionCtx extends DeviceAwareSessionContext { } private void reply(ResponseMsg msg, Consumer f) { - if (!msg.getError().isPresent()) { - f.accept(msg.getData().get()); + Optional msgError = msg.getError(); + if (!msgError.isPresent()) { + Optional msgData = msg.getData(); + if (msgData.isPresent()) { + f.accept(msgData.get()); + } } else { - Exception e = msg.getError().get(); + Exception e = msgError.get(); responseWriter.setResult(new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR)); } } diff --git a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java index fe86f81049..f1f0266fa6 100644 --- a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java +++ b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java @@ -32,6 +32,7 @@ import javax.net.ssl.*; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.net.URL; import java.security.KeyStore; import java.security.cert.CertificateException; @@ -69,12 +70,15 @@ public class MqttSslHandlerProvider { TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); KeyStore trustStore = KeyStore.getInstance(keyStoreType); - trustStore.load(new FileInputStream(tsFile), keyStorePassword.toCharArray()); + try (InputStream tsFileInputStream = new FileInputStream(tsFile)) { + trustStore.load(tsFileInputStream, keyStorePassword.toCharArray()); + } tmFactory.init(trustStore); KeyStore ks = KeyStore.getInstance(keyStoreType); - - ks.load(new FileInputStream(ksFile), keyStorePassword.toCharArray()); + try (InputStream ksFileInputStream = new FileInputStream(ksFile)) { + ks.load(ksFileInputStream, keyStorePassword.toCharArray()); + } KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(ks, keyPassword.toCharArray()); diff --git a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java index 36769d7536..e56e38363a 100644 --- a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java +++ b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java @@ -98,6 +98,7 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor { case STATUS_CODE_RESPONSE: case GET_ATTRIBUTES_RESPONSE: ResponseMsg responseMsg = (ResponseMsg) msg; + Optional responseError = responseMsg.getError(); if (responseMsg.isSuccess()) { MsgType requestMsgType = responseMsg.getRequestMsgType(); Integer requestId = responseMsg.getRequestId(); @@ -106,18 +107,21 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor { result = MqttTransportHandler.createMqttPubAckMsg(requestId); } else if (requestMsgType == MsgType.GET_ATTRIBUTES_REQUEST) { GetAttributesResponse response = (GetAttributesResponse) msg; - if (response.isSuccess()) { + Optional responseData = response.getData(); + if (response.isSuccess() && responseData.isPresent()) { result = createMqttPublishMsg(ctx, MqttTopics.DEVICE_ATTRIBUTES_RESPONSE_TOPIC_PREFIX + requestId, - response.getData().get(), true); + responseData.get(), true); } else { - throw new AdaptorException(response.getError().get()); + if (responseError.isPresent()) { + throw new AdaptorException(responseError.get()); + } } } } } else { - if (responseMsg.getError().isPresent()) { - throw new AdaptorException(responseMsg.getError().get()); + if (responseError.isPresent()) { + throw new AdaptorException(responseError.get()); } } break; diff --git a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java index 163b0cdfbc..11a1747210 100644 --- a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java +++ b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java @@ -128,8 +128,9 @@ public class GatewayDeviceSessionCtx extends DeviceAwareSessionContext { JsonObject result = new JsonObject(); result.addProperty("id", response.getRequestId()); result.addProperty("device", device.getName()); - if (response.getData().isPresent()) { - AttributesKVMsg msg = response.getData().get(); + Optional responseData = response.getData(); + if (responseData.isPresent()) { + AttributesKVMsg msg = responseData.get(); if (msg.getClientAttributes() != null) { msg.getClientAttributes().forEach(v -> addValueToJson(result, "value", v)); } @@ -143,16 +144,28 @@ public class GatewayDeviceSessionCtx extends DeviceAwareSessionContext { private void addValueToJson(JsonObject json, String name, KvEntry entry) { switch (entry.getDataType()) { case BOOLEAN: - json.addProperty(name, entry.getBooleanValue().get()); + Optional booleanValue = entry.getBooleanValue(); + if (booleanValue.isPresent()) { + json.addProperty(name, booleanValue.get()); + } break; case STRING: - json.addProperty(name, entry.getStrValue().get()); + Optional stringValue = entry.getStrValue(); + if (stringValue.isPresent()) { + json.addProperty(name, stringValue.get()); + } break; case DOUBLE: - json.addProperty(name, entry.getDoubleValue().get()); + Optional doubleValue = entry.getDoubleValue(); + if (doubleValue.isPresent()) { + json.addProperty(name, doubleValue.get()); + } break; case LONG: - json.addProperty(name, entry.getLongValue().get()); + Optional longValue = entry.getLongValue(); + if (longValue.isPresent()) { + json.addProperty(name, longValue.get()); + } break; } }