Browse Source

Fix sonar issues.

pull/327/head
Igor Kulikov 9 years ago
parent
commit
ff3f6d140c
  1. 14
      application/src/main/java/org/thingsboard/server/actors/app/AppActor.java
  2. 14
      application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java
  3. 2
      application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java
  4. 16
      application/src/main/java/org/thingsboard/server/controller/AuthController.java
  5. 4
      application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java
  6. 4
      application/src/main/java/org/thingsboard/server/controller/plugin/PluginApiController.java
  7. 2
      application/src/main/java/org/thingsboard/server/service/cluster/rpc/ClusterGrpcService.java
  8. 158
      application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java
  9. 3
      application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseSchemaService.java
  10. 2
      application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java
  11. 4
      common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java
  12. 6
      common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterable.java
  13. 7
      dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java
  14. 15
      dao/src/main/java/org/thingsboard/server/dao/attributes/CassandraBaseAttributesDao.java
  15. 1
      dao/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java
  16. 7
      dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java
  17. 18
      dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java
  18. 7
      dao/src/main/java/org/thingsboard/server/dao/service/DataValidator.java
  19. 6
      dao/src/main/java/org/thingsboard/server/dao/service/Validator.java
  20. 1
      dao/src/main/java/org/thingsboard/server/dao/sql/timeseries/JpaTimeseriesDao.java
  21. 1
      dao/src/main/java/org/thingsboard/server/dao/timeseries/AggregatePartitionsFunction.java
  22. 25
      dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java
  23. 2
      dao/src/main/java/org/thingsboard/server/dao/timeseries/TsPartitionDate.java
  24. 2
      extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/handlers/DefaultWebsocketMsgHandler.java
  25. 8
      extensions-core/src/main/java/org/thingsboard/server/extensions/core/filter/NashornJsEvaluator.java
  26. 10
      extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/messaging/DeviceMessagingRuleMsgHandler.java
  27. 10
      extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/handlers/RpcRestMsgHandler.java
  28. 6
      extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRestMsgHandler.java
  29. 25
      extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRpcMsgHandler.java
  30. 4
      extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryWebsocketMsgHandler.java
  31. 3
      extensions/extension-mqtt/src/main/java/org/thingsboard/server/extensions/mqtt/plugin/MqttPlugin.java
  32. 25
      tools/src/main/java/org/thingsboard/client/tools/MqttSslClient.java
  33. 32
      transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java
  34. 4
      transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DeviceEmulator.java
  35. 11
      transport/http/src/main/java/org/thingsboard/server/transport/http/session/HttpSessionCtx.java
  36. 10
      transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java
  37. 14
      transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java
  38. 25
      transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java

14
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.RuleChainDeviceMsg;
import org.thingsboard.server.actors.tenant.TenantActor; import org.thingsboard.server.actors.tenant.TenantActor;
import org.thingsboard.server.common.data.Tenant; 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.id.TenantId;
import org.thingsboard.server.common.data.page.PageDataIterable; import org.thingsboard.server.common.data.page.PageDataIterable;
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg; import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
@ -149,14 +151,16 @@ public class AppActor extends ContextAwareActor {
private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) {
ActorRef target = null; ActorRef target = null;
if (SYSTEM_TENANT.equals(msg.getTenantId())) { if (SYSTEM_TENANT.equals(msg.getTenantId())) {
if (msg.getPluginId().isPresent()) { Optional<PluginId> pluginId = msg.getPluginId();
target = pluginManager.getOrCreatePluginActor(this.context(), msg.getPluginId().get()); Optional<RuleId> ruleId = msg.getRuleId();
} else if (msg.getRuleId().isPresent()) { if (pluginId.isPresent()) {
Optional<ActorRef> ref = ruleManager.update(this.context(), msg.getRuleId().get(), msg.getEvent()); target = pluginManager.getOrCreatePluginActor(this.context(), pluginId.get());
} else if (ruleId.isPresent()) {
Optional<ActorRef> ref = ruleManager.update(this.context(), ruleId.get(), msg.getEvent());
if (ref.isPresent()) { if (ref.isPresent()) {
target = ref.get(); target = ref.get();
} else { } else {
logger.debug("Failed to find actor for rule: [{}]", msg.getRuleId()); logger.debug("Failed to find actor for rule: [{}]", ruleId);
return; return;
} }
} }

14
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.RuleManager;
import org.thingsboard.server.actors.shared.rule.TenantRuleManager; import org.thingsboard.server.actors.shared.rule.TenantRuleManager;
import org.thingsboard.server.common.data.id.DeviceId; 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.data.id.TenantId;
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg; import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
import org.thingsboard.server.common.msg.device.ToDeviceActorMsg; import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;
@ -126,16 +128,18 @@ public class TenantActor extends ContextAwareActor {
} }
private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) {
if (msg.getPluginId().isPresent()) { Optional<PluginId> pluginId = msg.getPluginId();
ActorRef pluginActor = pluginManager.getOrCreatePluginActor(this.context(), msg.getPluginId().get()); Optional<RuleId> ruleId = msg.getRuleId();
if (pluginId.isPresent()) {
ActorRef pluginActor = pluginManager.getOrCreatePluginActor(this.context(), pluginId.get());
pluginActor.tell(msg, ActorRef.noSender()); pluginActor.tell(msg, ActorRef.noSender());
} else if (msg.getRuleId().isPresent()) { } else if (ruleId.isPresent()) {
ActorRef target; ActorRef target;
Optional<ActorRef> ref = ruleManager.update(this.context(), msg.getRuleId().get(), msg.getEvent()); Optional<ActorRef> ref = ruleManager.update(this.context(), ruleId.get(), msg.getEvent());
if (ref.isPresent()) { if (ref.isPresent()) {
target = ref.get(); target = ref.get();
} else { } else {
logger.debug("Failed to find actor for rule: [{}]", msg.getRuleId()); logger.debug("Failed to find actor for rule: [{}]", ruleId);
return; return;
} }
target.tell(msg, ActorRef.noSender()); target.tell(msg, ActorRef.noSender());

2
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 FORM_BASED_LOGIN_ENTRY_POINT = "/api/auth/login";
public static final String PUBLIC_LOGIN_ENTRY_POINT = "/api/auth/login/public"; 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 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 TOKEN_BASED_AUTH_ENTRY_POINT = "/api/**";
public static final String WS_TOKEN_BASED_AUTH_ENTRY_POINT = "/api/ws/**"; public static final String WS_TOKEN_BASED_AUTH_ENTRY_POINT = "/api/ws/**";

16
application/src/main/java/org/thingsboard/server/controller/AuthController.java

@ -103,13 +103,13 @@ public class AuthController extends BaseController {
HttpStatus responseStatus; HttpStatus responseStatus;
UserCredentials userCredentials = userService.findUserCredentialsByActivateToken(activateToken); UserCredentials userCredentials = userService.findUserCredentialsByActivateToken(activateToken);
if (userCredentials != null) { if (userCredentials != null) {
String createPasswordURI = "/login/createPassword"; String createURI = "/login/createPassword";
try { try {
URI location = new URI(createPasswordURI + "?activateToken=" + activateToken); URI location = new URI(createURI + "?activateToken=" + activateToken);
headers.setLocation(location); headers.setLocation(location);
responseStatus = HttpStatus.SEE_OTHER; responseStatus = HttpStatus.SEE_OTHER;
} catch (URISyntaxException e) { } 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; responseStatus = HttpStatus.BAD_REQUEST;
} }
} else { } else {
@ -126,10 +126,10 @@ public class AuthController extends BaseController {
try { try {
UserCredentials userCredentials = userService.requestPasswordReset(email); UserCredentials userCredentials = userService.requestPasswordReset(email);
String baseUrl = constructBaseUrl(request); 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()); userCredentials.getResetToken());
mailService.sendResetPasswordEmail(resetPasswordUrl, email); mailService.sendResetPasswordEmail(resetUrl, email);
} catch (Exception e) { } catch (Exception e) {
throw handleException(e); throw handleException(e);
} }
@ -140,15 +140,15 @@ public class AuthController extends BaseController {
@RequestParam(value = "resetToken") String resetToken) { @RequestParam(value = "resetToken") String resetToken) {
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
HttpStatus responseStatus; HttpStatus responseStatus;
String resetPasswordURI = "/login/resetPassword"; String resetURI = "/login/resetPassword";
UserCredentials userCredentials = userService.findUserCredentialsByResetToken(resetToken); UserCredentials userCredentials = userService.findUserCredentialsByResetToken(resetToken);
if (userCredentials != null) { if (userCredentials != null) {
try { try {
URI location = new URI(resetPasswordURI + "?resetToken=" + resetToken); URI location = new URI(resetURI + "?resetToken=" + resetToken);
headers.setLocation(location); headers.setLocation(location);
responseStatus = HttpStatus.SEE_OTHER; responseStatus = HttpStatus.SEE_OTHER;
} catch (URISyntaxException e) { } 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; responseStatus = HttpStatus.BAD_REQUEST;
} }
} else { } else {

4
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) { if (strRelationTypeGroup != null && strRelationTypeGroup.trim().length()>0) {
try { try {
result = RelationTypeGroup.valueOf(strRelationTypeGroup); result = RelationTypeGroup.valueOf(strRelationTypeGroup);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) { }
result = defaultValue;
}
} }
return result; return result;
} }

4
application/src/main/java/org/thingsboard/server/controller/plugin/PluginApiController.java

@ -71,7 +71,7 @@ public class PluginApiController extends BaseController {
TenantId tenantId = getCurrentUser().getTenantId(); TenantId tenantId = getCurrentUser().getTenantId();
CustomerId customerId = getCurrentUser().getCustomerId(); CustomerId customerId = getCurrentUser().getCustomerId();
if (validatePluginAccess(pluginMd, tenantId, customerId)) { if (validatePluginAccess(pluginMd, tenantId, customerId)) {
if(ModelConstants.NULL_UUID.equals(tenantId.getId())){ if(tenantId != null && ModelConstants.NULL_UUID.equals(tenantId.getId())){
tenantId = null; tenantId = null;
} }
PluginApiCallSecurityContext securityCtx = new PluginApiCallSecurityContext(pluginMd.getTenantId(), pluginMd.getId(), tenantId, customerId); PluginApiCallSecurityContext securityCtx = new PluginApiCallSecurityContext(pluginMd.getTenantId(), pluginMd.getId(), tenantId, customerId);
@ -97,7 +97,7 @@ public class PluginApiController extends BaseController {
validUser = true; validUser = true;
} }
} else { } 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 // All tenant users can access public tenant plugins. Only tenant
// administrator can access private tenant plugins // administrator can access private tenant plugins
validUser = true; validUser = true;

2
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); future.onMsg(msg);
} catch (InterruptedException e) { } catch (InterruptedException e) {
log.warn("Failed to report created session!"); log.warn("Failed to report created session!");
Thread.currentThread().interrupt();
} }
} else { } else {
log.warn("Failed to lookup pending session!"); log.warn("Failed to lookup pending session!");
@ -117,6 +118,7 @@ public class ClusterGrpcService extends ClusterRpcServiceGrpc.ClusterRpcServiceI
log.info("RPC server stopped!"); log.info("RPC server stopped!");
} catch (InterruptedException e) { } catch (InterruptedException e) {
log.warn("Failed to onStop RPC server!"); log.warn("Failed to onStop RPC server!");
Thread.currentThread().interrupt();
} }
} }
} }

158
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 org.thingsboard.server.dao.widget.WidgetsBundleService;
import java.io.IOException; import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
@ -138,7 +139,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
node.put("timeout", "10000"); node.put("timeout", "10000");
node.put("enableTls", "false"); node.put("enableTls", "false");
node.put("username", ""); node.put("username", "");
node.put("password", ""); node.put("password", ""); //NOSONAR, key used to identify password field (not password value itself)
mailSettings.setJsonValue(node); mailSettings.setJsonValue(node);
adminSettingsService.saveAdminSettings(mailSettings); adminSettingsService.saveAdminSettings(mailSettings);
} }
@ -146,33 +147,34 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
@Override @Override
public void loadSystemWidgets() throws Exception { public void loadSystemWidgets() throws Exception {
Path widgetBundlesDir = Paths.get(dataDir, JSON_DIR, SYSTEM_DIR, WIDGET_BUNDLES_DIR); Path widgetBundlesDir = Paths.get(dataDir, JSON_DIR, SYSTEM_DIR, WIDGET_BUNDLES_DIR);
Files.newDirectoryStream(widgetBundlesDir, path -> path.toString().endsWith(".json")) try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(widgetBundlesDir, path -> path.toString().endsWith(".json"))) {
.forEach( dirStream.forEach(
path -> { path -> {
try { try {
JsonNode widgetsBundleDescriptorJson = objectMapper.readTree(path.toFile()); JsonNode widgetsBundleDescriptorJson = objectMapper.readTree(path.toFile());
JsonNode widgetsBundleJson = widgetsBundleDescriptorJson.get("widgetsBundle"); JsonNode widgetsBundleJson = widgetsBundleDescriptorJson.get("widgetsBundle");
WidgetsBundle widgetsBundle = objectMapper.treeToValue(widgetsBundleJson, WidgetsBundle.class); WidgetsBundle widgetsBundle = objectMapper.treeToValue(widgetsBundleJson, WidgetsBundle.class);
WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
JsonNode widgetTypesArrayJson = widgetsBundleDescriptorJson.get("widgetTypes"); JsonNode widgetTypesArrayJson = widgetsBundleDescriptorJson.get("widgetTypes");
widgetTypesArrayJson.forEach( widgetTypesArrayJson.forEach(
widgetTypeJson -> { widgetTypeJson -> {
try { try {
WidgetType widgetType = objectMapper.treeToValue(widgetTypeJson, WidgetType.class); WidgetType widgetType = objectMapper.treeToValue(widgetTypeJson, WidgetType.class);
widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
widgetTypeService.saveWidgetType(widgetType); widgetTypeService.saveWidgetType(widgetType);
} catch (Exception e) { } catch (Exception e) {
log.error("Unable to load widget type from json: [{}]", path.toString()); log.error("Unable to load widget type from json: [{}]", path.toString());
throw new RuntimeException("Unable to load widget type from json", e); 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()); } catch (Exception e) {
throw new RuntimeException("Unable to load widgets bundle from json", e); log.error("Unable to load widgets bundle from json: [{}]", path.toString());
} throw new RuntimeException("Unable to load widgets bundle from json", e);
} }
); }
);
}
} }
@Override @Override
@ -279,67 +281,69 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
} }
private void loadPlugins(Path pluginsDir, TenantId tenantId) throws Exception{ private void loadPlugins(Path pluginsDir, TenantId tenantId) throws Exception{
Files.newDirectoryStream(pluginsDir, path -> path.toString().endsWith(".json")) try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(pluginsDir, path -> path.toString().endsWith(".json"))) {
.forEach( dirStream.forEach(
path -> { path -> {
try { try {
JsonNode pluginJson = objectMapper.readTree(path.toFile()); JsonNode pluginJson = objectMapper.readTree(path.toFile());
PluginMetaData plugin = objectMapper.treeToValue(pluginJson, PluginMetaData.class); PluginMetaData plugin = objectMapper.treeToValue(pluginJson, PluginMetaData.class);
plugin.setTenantId(tenantId); plugin.setTenantId(tenantId);
if (plugin.getState() == ComponentLifecycleState.ACTIVE) { if (plugin.getState() == ComponentLifecycleState.ACTIVE) {
plugin.setState(ComponentLifecycleState.SUSPENDED); plugin.setState(ComponentLifecycleState.SUSPENDED);
PluginMetaData savedPlugin = pluginService.savePlugin(plugin); PluginMetaData savedPlugin = pluginService.savePlugin(plugin);
pluginService.activatePluginById(savedPlugin.getId()); pluginService.activatePluginById(savedPlugin.getId());
} else { } else {
pluginService.savePlugin(plugin); 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);
} }
} 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 { private void loadRules(Path rulesDir, TenantId tenantId) throws Exception {
Files.newDirectoryStream(rulesDir, path -> path.toString().endsWith(".json")) try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(rulesDir, path -> path.toString().endsWith(".json"))) {
.forEach( dirStream.forEach(
path -> { path -> {
try { try {
JsonNode ruleJson = objectMapper.readTree(path.toFile()); JsonNode ruleJson = objectMapper.readTree(path.toFile());
RuleMetaData rule = objectMapper.treeToValue(ruleJson, RuleMetaData.class); RuleMetaData rule = objectMapper.treeToValue(ruleJson, RuleMetaData.class);
rule.setTenantId(tenantId); rule.setTenantId(tenantId);
if (rule.getState() == ComponentLifecycleState.ACTIVE) { if (rule.getState() == ComponentLifecycleState.ACTIVE) {
rule.setState(ComponentLifecycleState.SUSPENDED); rule.setState(ComponentLifecycleState.SUSPENDED);
RuleMetaData savedRule = ruleService.saveRule(rule); RuleMetaData savedRule = ruleService.saveRule(rule);
ruleService.activateRuleById(savedRule.getId()); ruleService.activateRuleById(savedRule.getId());
} else { } else {
ruleService.saveRule(rule); 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);
} }
} 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 { private void loadDashboards(Path dashboardsDir, TenantId tenantId, CustomerId customerId) throws Exception {
Files.newDirectoryStream(dashboardsDir, path -> path.toString().endsWith(".json")) try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(dashboardsDir, path -> path.toString().endsWith(".json"))) {
.forEach( dirStream.forEach(
path -> { path -> {
try { try {
JsonNode dashboardJson = objectMapper.readTree(path.toFile()); JsonNode dashboardJson = objectMapper.readTree(path.toFile());
Dashboard dashboard = objectMapper.treeToValue(dashboardJson, Dashboard.class); Dashboard dashboard = objectMapper.treeToValue(dashboardJson, Dashboard.class);
dashboard.setTenantId(tenantId); dashboard.setTenantId(tenantId);
dashboard.setCustomerId(customerId); dashboard.setCustomerId(customerId);
dashboardService.saveDashboard(dashboard); dashboardService.saveDashboard(dashboard);
} catch (Exception e) { } catch (Exception e) {
log.error("Unable to load dashboard from json: [{}]", path.toString()); log.error("Unable to load dashboard from json: [{}]", path.toString());
throw new RuntimeException("Unable to load dashboard from json", e); throw new RuntimeException("Unable to load dashboard from json", e);
}
} }
); }
);
}
} }
} }

3
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.nio.file.Paths;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.PreparedStatement;
@Service @Service
@Profile("install") @Profile("install")
@ -58,7 +59,7 @@ public class SqlDatabaseSchemaService implements DatabaseSchemaService {
Path schemaFile = Paths.get(this.dataDir, SQL_DIR, SCHEMA_SQL); Path schemaFile = Paths.get(this.dataDir, SQL_DIR, SCHEMA_SQL);
try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
String sql = new String(Files.readAllBytes(schemaFile), Charset.forName("UTF-8")); 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
} }
} }

2
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") @Component(value="jwtHeaderTokenExtractor")
public class JwtHeaderTokenExtractor implements TokenExtractor { public class JwtHeaderTokenExtractor implements TokenExtractor {
public static String HEADER_PREFIX = "Bearer "; public static final String HEADER_PREFIX = "Bearer ";
@Override @Override
public String extract(HttpServletRequest request) { public String extract(HttpServletRequest request) {

4
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 SERVER_SCOPE = "SERVER_SCOPE";
public static final String SHARED_SCOPE = "SHARED_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 ALARM = "ALARM";
public static final String ERROR = "ERROR"; public static final String ERROR = "ERROR";

6
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.Iterator;
import java.util.List; import java.util.List;
import java.util.NoSuchElementException;
import org.thingsboard.server.common.data.SearchTextBased; import org.thingsboard.server.common.data.SearchTextBased;
import org.thingsboard.server.common.data.id.UUIDBased; import org.thingsboard.server.common.data.id.UUIDBased;
@ -54,7 +55,7 @@ public class PageDataIterable<T extends SearchTextBased<? extends UUIDBased>> im
fetch(nextPackLink); fetch(nextPackLink);
} }
} }
return currentIdx != currentItems.size(); return currentIdx < currentItems.size();
} }
private void fetch(TextPageLink link) { private void fetch(TextPageLink link) {
@ -67,6 +68,9 @@ public class PageDataIterable<T extends SearchTextBased<? extends UUIDBased>> im
@Override @Override
public T next() { public T next() {
if(!hasNext()){
throw new NoSuchElementException();
}
return currentItems.get(currentIdx++); return currentItems.get(currentIdx++);
} }

7
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 org.thingsboard.server.dao.tenant.TenantDao;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.*;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.thingsboard.server.dao.DaoUtil.toUUIDs; import static org.thingsboard.server.dao.DaoUtil.toUUIDs;
@ -210,7 +207,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
@Nullable @Nullable
@Override @Override
public List<Asset> apply(@Nullable List<Asset> assetList) { public List<Asset> apply(@Nullable List<Asset> 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());
} }
}); });

15
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.setString(3, attribute.getKey());
stmt.setLong(4, attribute.getLastUpdateTs()); stmt.setLong(4, attribute.getLastUpdateTs());
stmt.setString(5, attribute.getStrValue().orElse(null)); stmt.setString(5, attribute.getStrValue().orElse(null));
if (attribute.getBooleanValue().isPresent()) { Optional<Boolean> booleanValue = attribute.getBooleanValue();
stmt.setBool(6, attribute.getBooleanValue().get()); if (booleanValue.isPresent()) {
stmt.setBool(6, booleanValue.get());
} else { } else {
stmt.setToNull(6); stmt.setToNull(6);
} }
if (attribute.getLongValue().isPresent()) { Optional<Long> longValue = attribute.getLongValue();
stmt.setLong(7, attribute.getLongValue().get()); if (longValue.isPresent()) {
stmt.setLong(7, longValue.get());
} else { } else {
stmt.setToNull(7); stmt.setToNull(7);
} }
if (attribute.getDoubleValue().isPresent()) { Optional<Double> doubleValue = attribute.getDoubleValue();
stmt.setDouble(8, attribute.getDoubleValue().get()); if (doubleValue.isPresent()) {
stmt.setDouble(8, doubleValue.get());
} else { } else {
stmt.setToNull(8); stmt.setToNull(8);
} }

1
dao/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java

@ -153,6 +153,7 @@ public abstract class AbstractCassandraCluster {
Thread.sleep(initRetryInterval); Thread.sleep(initRetryInterval);
} catch (InterruptedException ie) { } catch (InterruptedException ie) {
log.warn("Failed to wait until retry", ie); log.warn("Failed to wait until retry", ie);
Thread.currentThread().interrupt();
} }
} }
} }

7
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 org.thingsboard.server.dao.tenant.TenantDao;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.*;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.thingsboard.server.dao.DaoUtil.toUUIDs; import static org.thingsboard.server.dao.DaoUtil.toUUIDs;
@ -230,7 +227,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
@Nullable @Nullable
@Override @Override
public List<Device> apply(@Nullable List<Device> deviceList) { public List<Device> apply(@Nullable List<Device> 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());
} }
}); });

18
dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java

@ -27,8 +27,8 @@ public class ModelConstants {
private ModelConstants() { private ModelConstants() {
} }
public static UUID NULL_UUID = UUIDs.startOf(0); public static final UUID NULL_UUID = UUIDs.startOf(0);
public static String NULL_UUID_STR = UUIDConverter.fromTimeUUID(NULL_UUID); public static final String NULL_UUID_STR = UUIDConverter.fromTimeUUID(NULL_UUID);
/** /**
* Generic constants. * 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_COLUMN_FAMILY_NAME = "user_credentials";
public static final String USER_CREDENTIALS_USER_ID_PROPERTY = USER_ID_PROPERTY; 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_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_ACTIVATE_TOKEN_PROPERTY = "activate_token";
public static final String USER_CREDENTIALS_RESET_TOKEN_PROPERTY = "reset_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 LONG_VALUE_COLUMN = "long_v";
public static final String DOUBLE_VALUE_COLUMN = "dbl_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)}); 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)}); 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)}); 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) { public static String min(String s) {
return "min(" + s + ")"; return "min(" + s + ")";

7
dao/src/main/java/org/thingsboard/server/dao/service/DataValidator.java

@ -57,12 +57,7 @@ public abstract class DataValidator<D extends BaseData<?>> {
} }
protected boolean isSameData(D existentData, D actualData) { protected boolean isSameData(D existentData, D actualData) {
if (actualData.getId() == null) { return actualData.getId() != null && existentData.getId().equals(actualData.getId());
return false;
} else if (!existentData.getId().equals(actualData.getId())) {
return false;
}
return true;
} }
protected static void validateEmail(String email) { protected static void validateEmail(String email) {

6
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 * @param errorMessage the error message for exception
*/ */
public static void validatePageLink(TextPageLink pageLink, String errorMessage) { public static void validatePageLink(TextPageLink pageLink, String errorMessage) {
if (pageLink == null) { if (pageLink == null || pageLink.getLimit() < 1 || (pageLink.getIdOffset() != null && pageLink.getIdOffset().version() != 1)) {
throw new IncorrectParameterException(errorMessage);
} else if (pageLink.getLimit() < 1) {
throw new IncorrectParameterException(errorMessage);
} else if (pageLink.getIdOffset() != null && pageLink.getIdOffset().version() != 1) {
throw new IncorrectParameterException(errorMessage); throw new IncorrectParameterException(errorMessage);
} }
} }

1
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<TsKvEntity, Optional<TsKvEntry>>() { return Futures.transform(listenableFuture, new Function<TsKvEntity, Optional<TsKvEntry>>() {
@Nullable
@Override @Override
public Optional<TsKvEntry> apply(@Nullable TsKvEntity entity) { public Optional<TsKvEntry> apply(@Nullable TsKvEntity entity) {
if (entity != null && entity.isNotEmpty()) { if (entity != null && entity.isNotEmpty()) {

1
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; this.ts = ts;
} }
@Nullable
@Override @Override
public Optional<TsKvEntry> apply(@Nullable List<ResultSet> rsList) { public Optional<TsKvEntry> apply(@Nullable List<ResultSet> rsList) {
try { try {

25
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.LocalDateTime;
import java.time.ZoneOffset; import java.time.ZoneOffset;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -136,7 +137,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
@Nullable @Nullable
@Override @Override
public List<TsKvEntry> apply(@Nullable List<Optional<TsKvEntry>> input) { public List<TsKvEntry> apply(@Nullable List<Optional<TsKvEntry>> 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); }, readResultsProcessingExecutor);
} }
@ -189,7 +190,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
Futures.addCallback(executeAsyncRead(stmt), new FutureCallback<ResultSet>() { Futures.addCallback(executeAsyncRead(stmt), new FutureCallback<ResultSet>() {
@Override @Override
public void onSuccess(@Nullable ResultSet result) { public void onSuccess(@Nullable ResultSet result) {
cursor.addData(convertResultToTsKvEntryList(result.all())); cursor.addData(convertResultToTsKvEntryList(result == null ? Collections.emptyList() : result.all()));
findAllAsyncSequentiallyWithLimit(cursor, resultFuture); findAllAsyncSequentiallyWithLimit(cursor, resultFuture);
} }
@ -523,16 +524,28 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
private static void addValue(KvEntry kvEntry, BoundStatement stmt, int column) { private static void addValue(KvEntry kvEntry, BoundStatement stmt, int column) {
switch (kvEntry.getDataType()) { switch (kvEntry.getDataType()) {
case BOOLEAN: case BOOLEAN:
stmt.setBool(column, kvEntry.getBooleanValue().get().booleanValue()); Optional<Boolean> booleanValue = kvEntry.getBooleanValue();
if (booleanValue.isPresent()) {
stmt.setBool(column, booleanValue.get().booleanValue());
}
break; break;
case STRING: case STRING:
stmt.setString(column, kvEntry.getStrValue().get()); Optional<String> stringValue = kvEntry.getStrValue();
if (stringValue.isPresent()) {
stmt.setString(column, stringValue.get());
}
break; break;
case LONG: case LONG:
stmt.setLong(column, kvEntry.getLongValue().get().longValue()); Optional<Long> longValue = kvEntry.getLongValue();
if (longValue.isPresent()) {
stmt.setLong(column, longValue.get().longValue());
}
break; break;
case DOUBLE: case DOUBLE:
stmt.setDouble(column, kvEntry.getDoubleValue().get().doubleValue()); Optional<Double> doubleValue = kvEntry.getDoubleValue();
if (doubleValue.isPresent()) {
stmt.setDouble(column, doubleValue.get().doubleValue());
}
break; break;
} }
} }

2
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); 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 String pattern;
private final TemporalUnit truncateUnit; private final transient TemporalUnit truncateUnit;
TsPartitionDate(String pattern, TemporalUnit truncateUnit) { TsPartitionDate(String pattern, TemporalUnit truncateUnit) {
this.pattern = pattern; this.pattern = pattern;

2
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)); wsSessionsMap.put(sessionId, new WsSessionMetaData(sessionRef));
break; break;
case ERROR: case ERROR:
log.debug("[{}] Unknown websocket session error: {}. ", sessionId, event.getError().get()); log.debug("[{}] Unknown websocket session error: {}. ", sessionId, event.getError().orElse(null));
break; break;
case CLOSED: case CLOSED:
wsSessionsMap.remove(sessionId); wsSessionsMap.remove(sessionId);

8
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) { protected static Object getValue(KvEntry attr) {
switch (attr.getDataType()) { switch (attr.getDataType()) {
case STRING: case STRING:
return attr.getStrValue().get(); return attr.getStrValue().orElse(null);
case LONG: case LONG:
return attr.getLongValue().get(); return attr.getLongValue().orElse(null);
case DOUBLE: case DOUBLE:
return attr.getDoubleValue().get(); return attr.getDoubleValue().orElse(null);
case BOOLEAN: case BOOLEAN:
return attr.getBooleanValue().get(); return attr.getBooleanValue().orElse(null);
} }
return null; return null;
} }

10
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.plugins.msg.*;
import org.thingsboard.server.extensions.api.rules.RuleException; import org.thingsboard.server.extensions.api.rules.RuleException;
import java.util.HashMap; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/** /**
* @author Andrew Shvayka * @author Andrew Shvayka
@ -89,8 +86,9 @@ public class DeviceMessagingRuleMsgHandler implements RuleMsgHandler {
if (pendindMsg != null) { if (pendindMsg != null) {
log.trace("[{}] Received response: {}", requestId, msg); log.trace("[{}] Received response: {}", requestId, msg);
ToServerRpcResponseMsg response; ToServerRpcResponseMsg response;
if (msg.getError().isPresent()) { Optional<RpcError> rpcError = msg.getError();
response = new ToServerRpcResponseMsg(pendindMsg.getRequestId(), toJsonString(msg.getError().get())); if (rpcError.isPresent()) {
response = new ToServerRpcResponseMsg(pendindMsg.getRequestId(), toJsonString(rpcError.get()));
} else { } else {
response = new ToServerRpcResponseMsg(pendindMsg.getRequestId(), msg.getResponse().orElse("")); response = new ToServerRpcResponseMsg(pendindMsg.getRequestId(), msg.getResponse().orElse(""));
} }

10
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<ResponseEntity> responseWriter, FromDeviceRpcResponse response) { public void reply(PluginContext ctx, DeferredResult<ResponseEntity> responseWriter, FromDeviceRpcResponse response) {
if (response.getError().isPresent()) { Optional<RpcError> rpcError = response.getError();
RpcError error = response.getError().get(); if (rpcError.isPresent()) {
RpcError error = rpcError.get();
switch (error) { switch (error) {
case TIMEOUT: case TIMEOUT:
responseWriter.setResult(new ResponseEntity<>(HttpStatus.REQUEST_TIMEOUT)); responseWriter.setResult(new ResponseEntity<>(HttpStatus.REQUEST_TIMEOUT));
@ -124,8 +125,9 @@ public class RpcRestMsgHandler extends DefaultRestMsgHandler {
break; break;
} }
} else { } else {
if (response.getResponse().isPresent() && !StringUtils.isEmpty(response.getResponse().get())) { Optional<String> responseData = response.getResponse();
String data = response.getResponse().get(); if (responseData.isPresent() && !StringUtils.isEmpty(responseData.get())) {
String data = responseData.get();
try { try {
responseWriter.setResult(new ResponseEntity<>(jsonMapper.readTree(data), HttpStatus.OK)); responseWriter.setResult(new ResponseEntity<>(jsonMapper.readTree(data), HttpStatus.OK));
} catch (IOException e) { } catch (IOException e) {

6
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)) { if (!StringUtils.isEmpty(scope)) {
ctx.loadAttributes(entityId, scope, callback); ctx.loadAttributes(entityId, scope, callback);
} else { } else {
ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), callback); ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), callback);
} }
} }
} else if (method.equals("values")) { } else if (method.equals("values")) {
@ -132,9 +132,9 @@ public class TelemetryRestMsgHandler extends DefaultRestMsgHandler {
} else { } else {
if (!StringUtils.isEmpty(keys)) { if (!StringUtils.isEmpty(keys)) {
List<String> keyList = Arrays.asList(keys.split(",")); List<String> 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 { } else {
ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), callback); ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), callback);
} }
} }
} }

25
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.gen.TelemetryPluginProtos.*;
import org.thingsboard.server.extensions.core.plugin.telemetry.sub.*; import org.thingsboard.server.extensions.core.plugin.telemetry.sub.*;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -244,16 +241,28 @@ public class TelemetryRpcMsgHandler implements RpcMsgHandler {
dataBuilder.setValueType(attr.getDataType().ordinal()); dataBuilder.setValueType(attr.getDataType().ordinal());
switch (attr.getDataType()) { switch (attr.getDataType()) {
case BOOLEAN: case BOOLEAN:
dataBuilder.setBoolValue(attr.getBooleanValue().get()); Optional<Boolean> booleanValue = attr.getBooleanValue();
if (booleanValue.isPresent()) {
dataBuilder.setBoolValue(booleanValue.get());
}
break; break;
case LONG: case LONG:
dataBuilder.setLongValue(attr.getLongValue().get()); Optional<Long> longValue = attr.getLongValue();
if (longValue.isPresent()) {
dataBuilder.setLongValue(longValue.get());
}
break; break;
case DOUBLE: case DOUBLE:
dataBuilder.setDoubleValue(attr.getDoubleValue().get()); Optional<Double> doubleValue = attr.getDoubleValue();
if (doubleValue.isPresent()) {
dataBuilder.setDoubleValue(doubleValue.get());
}
break; break;
case STRING: case STRING:
dataBuilder.setStrValue(attr.getStrValue().get()); Optional<String> stringValue = attr.getStrValue();
if (stringValue.isPresent()) {
dataBuilder.setStrValue(stringValue.get());
}
break; break;
} }
return dataBuilder; return dataBuilder;

4
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())) { 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 { } else {
ctx.loadAttributes(entityId, cmd.getScope(), keys, callback); ctx.loadAttributes(entityId, cmd.getScope(), keys, callback);
} }
@ -167,7 +167,7 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler {
}; };
if (StringUtils.isEmpty(cmd.getScope())) { if (StringUtils.isEmpty(cmd.getScope())) {
ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), callback); ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), callback);
} else { } else {
ctx.loadAttributes(entityId, cmd.getScope(), callback); ctx.loadAttributes(entityId, cmd.getScope(), callback);
} }

3
extensions/extension-mqtt/src/main/java/org/thingsboard/server/extensions/mqtt/plugin/MqttPlugin.java

@ -84,9 +84,10 @@ public class MqttPlugin extends AbstractPlugin<MqttPluginConfiguration> {
log.warn("Failed to connect to requested mqtt host [{}]!", mqttClient.getServerURI(), e); log.warn("Failed to connect to requested mqtt host [{}]!", mqttClient.getServerURI(), e);
if (!mqttClient.isConnected()) { if (!mqttClient.isConnected()) {
try { try {
Thread.sleep(retryInterval); connectLock.wait(retryInterval);
} catch (InterruptedException e1) { } catch (InterruptedException e1) {
log.trace("Failed to wait for retry interval!", e); log.trace("Failed to wait for retry interval!", e);
Thread.currentThread().interrupt();
} }
} }
} }

25
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 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 javax.net.ssl.*;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.security.*; import java.security.KeyStore;
import java.security.cert.CertificateException;
@Slf4j
public class MqttSslClient { public class MqttSslClient {
@ -43,13 +43,10 @@ public class MqttSslClient {
private static final String keyStoreFile = "mqttclient.jks"; private static final String keyStoreFile = "mqttclient.jks";
private static final String JKS="JKS"; private static final String JKS="JKS";
private static final String TLS="TLS"; 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) { public static void main(String[] args) {
try { try {
URL ksUrl = Resources.getResource(keyStoreFile); URL ksUrl = Resources.getResource(keyStoreFile);
File ksFile = new File(ksUrl.toURI()); File ksFile = new File(ksUrl.toURI());
URL tsUrl = Resources.getResource(keyStoreFile); URL tsUrl = Resources.getResource(keyStoreFile);
@ -58,13 +55,15 @@ public class MqttSslClient {
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore trustStore = KeyStore.getInstance(JKS); 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); tmf.init(trustStore);
KeyStore ks = KeyStore.getInstance(JKS); 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()); 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(); KeyManager[] km = kmf.getKeyManagers();
TrustManager[] tm = tmf.getTrustManagers(); TrustManager[] tm = tmf.getTrustManagers();
@ -83,7 +82,7 @@ public class MqttSslClient {
System.out.println("Disconnected"); System.out.println("Disconnected");
System.exit(0); System.exit(0);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); log.error("Unexpected exception occurred in MqttSslClient", e);
} }
} }
} }

32
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 { private FromDeviceMsg convertToGetAttributesRequest(SessionContext ctx, Request inbound) throws AdaptorException {
List<String> queryElements = inbound.getOptions().getUriQuery(); List<String> queryElements = inbound.getOptions().getUriQuery();
if (queryElements != null || queryElements.size() > 0) { if (queryElements != null && queryElements.size() > 0) {
Set<String> clientKeys = toKeys(ctx, queryElements, "clientKeys"); Set<String> clientKeys = toKeys(ctx, queryElements, "clientKeys");
Set<String> sharedKeys = toKeys(ctx, queryElements, "sharedKeys"); Set<String> sharedKeys = toKeys(ctx, queryElements, "sharedKeys");
return new BasicGetAttributesRequest(0, clientKeys, sharedKeys); return new BasicGetAttributesRequest(0, clientKeys, sharedKeys);
@ -184,7 +184,7 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor {
keys = queryItem[1]; keys = queryItem[1];
} }
} }
if (!StringUtils.isEmpty(keys)) { if (keys != null && !StringUtils.isEmpty(keys)) {
return new HashSet<>(Arrays.asList(keys.split(","))); return new HashSet<>(Arrays.asList(keys.split(",")));
} else { } else {
return null; return null;
@ -202,14 +202,14 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor {
private Response convertStatusCodeResponse(StatusCodeResponse msg) { private Response convertStatusCodeResponse(StatusCodeResponse msg) {
if (msg.isSuccess()) { if (msg.isSuccess()) {
Integer code = msg.getData().get(); Optional<Integer> code = msg.getData();
if (code == 200) { if (code.isPresent() && code.get() == 200) {
return new Response(ResponseCode.VALID); return new Response(ResponseCode.VALID);
} else { } else {
return new Response(ResponseCode.CREATED); return new Response(ResponseCode.CREATED);
} }
} else { } else {
return convertError(msg.getError().get()); return convertError(msg.getError());
} }
} }
@ -229,30 +229,34 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor {
response.setPayload(result.toString()); response.setPayload(result.toString());
return response; return response;
} else { } 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) { private Response convertGetAttributesResponse(GetAttributesResponse msg) {
if (msg.isSuccess()) { if (msg.isSuccess()) {
AttributesKVMsg payload = msg.getData().get(); Optional<AttributesKVMsg> payload = msg.getData();
if (payload.getClientAttributes().isEmpty() && payload.getSharedAttributes().isEmpty()) { if (!payload.isPresent() || (payload.get().getClientAttributes().isEmpty() && payload.get().getSharedAttributes().isEmpty())) {
return new Response(ResponseCode.NOT_FOUND); return new Response(ResponseCode.NOT_FOUND);
} else { } else {
Response response = new Response(ResponseCode.CONTENT); Response response = new Response(ResponseCode.CONTENT);
JsonObject result = JsonConverter.toJson(payload, false); JsonObject result = JsonConverter.toJson(payload.get(), false);
response.setPayload(result.toString()); response.setPayload(result.toString());
return response; return response;
} }
} else { } else {
return convertError(msg.getError().get()); return convertError(msg.getError());
} }
} }
private Response convertError(Exception exception) { private Response convertError(Optional<Exception> exception) {
log.warn("Converting exception: {}", exception.getMessage(), exception); if (exception.isPresent()) {
if (exception instanceof ProcessingTimeoutException) { log.warn("Converting exception: {}", exception.get().getMessage(), exception.get());
return new Response(ResponseCode.SERVICE_UNAVAILABLE); if (exception.get() instanceof ProcessingTimeoutException) {
return new Response(ResponseCode.SERVICE_UNAVAILABLE);
} else {
return new Response(ResponseCode.INTERNAL_SERVER_ERROR);
}
} else { } else {
return new Response(ResponseCode.INTERNAL_SERVER_ERROR); return new Response(ResponseCode.INTERNAL_SERVER_ERROR);
} }

4
transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DeviceEmulator.java

@ -80,7 +80,7 @@ public class DeviceEmulator {
Thread.sleep(1000); Thread.sleep(1000);
} }
} catch (Exception e) { } 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); }, mapper.writeValueAsString(response), MediaTypeRegistry.APPLICATION_JSON);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); log.error("Error occurred while processing COAP response", e);
} }
} }

11
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.auth.DeviceAuthService;
import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext; import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext;
import java.util.Optional;
import java.util.function.Consumer; import java.util.function.Consumer;
/** /**
@ -94,10 +95,14 @@ public class HttpSessionCtx extends DeviceAwareSessionContext {
} }
private <T> void reply(ResponseMsg<? extends T> msg, Consumer<T> f) { private <T> void reply(ResponseMsg<? extends T> msg, Consumer<T> f) {
if (!msg.getError().isPresent()) { Optional<Exception> msgError = msg.getError();
f.accept(msg.getData().get()); if (!msgError.isPresent()) {
Optional<? extends T> msgData = msg.getData();
if (msgData.isPresent()) {
f.accept(msgData.get());
}
} else { } else {
Exception e = msg.getError().get(); Exception e = msgError.get();
responseWriter.setResult(new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR)); responseWriter.setResult(new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR));
} }
} }

10
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.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.net.URL; import java.net.URL;
import java.security.KeyStore; import java.security.KeyStore;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
@ -69,12 +70,15 @@ public class MqttSslHandlerProvider {
TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore trustStore = KeyStore.getInstance(keyStoreType); 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); tmFactory.init(trustStore);
KeyStore ks = KeyStore.getInstance(keyStoreType); KeyStore ks = KeyStore.getInstance(keyStoreType);
try (InputStream ksFileInputStream = new FileInputStream(ksFile)) {
ks.load(new FileInputStream(ksFile), keyStorePassword.toCharArray()); ks.load(ksFileInputStream, keyStorePassword.toCharArray());
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, keyPassword.toCharArray()); kmf.init(ks, keyPassword.toCharArray());

14
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 STATUS_CODE_RESPONSE:
case GET_ATTRIBUTES_RESPONSE: case GET_ATTRIBUTES_RESPONSE:
ResponseMsg<?> responseMsg = (ResponseMsg) msg; ResponseMsg<?> responseMsg = (ResponseMsg) msg;
Optional<Exception> responseError = responseMsg.getError();
if (responseMsg.isSuccess()) { if (responseMsg.isSuccess()) {
MsgType requestMsgType = responseMsg.getRequestMsgType(); MsgType requestMsgType = responseMsg.getRequestMsgType();
Integer requestId = responseMsg.getRequestId(); Integer requestId = responseMsg.getRequestId();
@ -106,18 +107,21 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor {
result = MqttTransportHandler.createMqttPubAckMsg(requestId); result = MqttTransportHandler.createMqttPubAckMsg(requestId);
} else if (requestMsgType == MsgType.GET_ATTRIBUTES_REQUEST) { } else if (requestMsgType == MsgType.GET_ATTRIBUTES_REQUEST) {
GetAttributesResponse response = (GetAttributesResponse) msg; GetAttributesResponse response = (GetAttributesResponse) msg;
if (response.isSuccess()) { Optional<AttributesKVMsg> responseData = response.getData();
if (response.isSuccess() && responseData.isPresent()) {
result = createMqttPublishMsg(ctx, result = createMqttPublishMsg(ctx,
MqttTopics.DEVICE_ATTRIBUTES_RESPONSE_TOPIC_PREFIX + requestId, MqttTopics.DEVICE_ATTRIBUTES_RESPONSE_TOPIC_PREFIX + requestId,
response.getData().get(), true); responseData.get(), true);
} else { } else {
throw new AdaptorException(response.getError().get()); if (responseError.isPresent()) {
throw new AdaptorException(responseError.get());
}
} }
} }
} }
} else { } else {
if (responseMsg.getError().isPresent()) { if (responseError.isPresent()) {
throw new AdaptorException(responseMsg.getError().get()); throw new AdaptorException(responseError.get());
} }
} }
break; break;

25
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(); JsonObject result = new JsonObject();
result.addProperty("id", response.getRequestId()); result.addProperty("id", response.getRequestId());
result.addProperty("device", device.getName()); result.addProperty("device", device.getName());
if (response.getData().isPresent()) { Optional<AttributesKVMsg> responseData = response.getData();
AttributesKVMsg msg = response.getData().get(); if (responseData.isPresent()) {
AttributesKVMsg msg = responseData.get();
if (msg.getClientAttributes() != null) { if (msg.getClientAttributes() != null) {
msg.getClientAttributes().forEach(v -> addValueToJson(result, "value", v)); 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) { private void addValueToJson(JsonObject json, String name, KvEntry entry) {
switch (entry.getDataType()) { switch (entry.getDataType()) {
case BOOLEAN: case BOOLEAN:
json.addProperty(name, entry.getBooleanValue().get()); Optional<Boolean> booleanValue = entry.getBooleanValue();
if (booleanValue.isPresent()) {
json.addProperty(name, booleanValue.get());
}
break; break;
case STRING: case STRING:
json.addProperty(name, entry.getStrValue().get()); Optional<String> stringValue = entry.getStrValue();
if (stringValue.isPresent()) {
json.addProperty(name, stringValue.get());
}
break; break;
case DOUBLE: case DOUBLE:
json.addProperty(name, entry.getDoubleValue().get()); Optional<Double> doubleValue = entry.getDoubleValue();
if (doubleValue.isPresent()) {
json.addProperty(name, doubleValue.get());
}
break; break;
case LONG: case LONG:
json.addProperty(name, entry.getLongValue().get()); Optional<Long> longValue = entry.getLongValue();
if (longValue.isPresent()) {
json.addProperty(name, longValue.get());
}
break; break;
} }
} }

Loading…
Cancel
Save