Commit ff3f6d140cfbd86c26afeb1bd8a1407e7695a99e

Authored by Igor Kulikov
1 parent 2726c718

Fix sonar issues.

Showing 38 changed files with 283 additions and 225 deletions
@@ -32,6 +32,8 @@ import org.thingsboard.server.actors.shared.rule.SystemRuleManager; @@ -32,6 +32,8 @@ import org.thingsboard.server.actors.shared.rule.SystemRuleManager;
32 import org.thingsboard.server.actors.tenant.RuleChainDeviceMsg; 32 import org.thingsboard.server.actors.tenant.RuleChainDeviceMsg;
33 import org.thingsboard.server.actors.tenant.TenantActor; 33 import org.thingsboard.server.actors.tenant.TenantActor;
34 import org.thingsboard.server.common.data.Tenant; 34 import org.thingsboard.server.common.data.Tenant;
  35 +import org.thingsboard.server.common.data.id.PluginId;
  36 +import org.thingsboard.server.common.data.id.RuleId;
35 import org.thingsboard.server.common.data.id.TenantId; 37 import org.thingsboard.server.common.data.id.TenantId;
36 import org.thingsboard.server.common.data.page.PageDataIterable; 38 import org.thingsboard.server.common.data.page.PageDataIterable;
37 import org.thingsboard.server.common.msg.cluster.ClusterEventMsg; 39 import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
@@ -149,14 +151,16 @@ public class AppActor extends ContextAwareActor { @@ -149,14 +151,16 @@ public class AppActor extends ContextAwareActor {
149 private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { 151 private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) {
150 ActorRef target = null; 152 ActorRef target = null;
151 if (SYSTEM_TENANT.equals(msg.getTenantId())) { 153 if (SYSTEM_TENANT.equals(msg.getTenantId())) {
152 - if (msg.getPluginId().isPresent()) {  
153 - target = pluginManager.getOrCreatePluginActor(this.context(), msg.getPluginId().get());  
154 - } else if (msg.getRuleId().isPresent()) {  
155 - Optional<ActorRef> ref = ruleManager.update(this.context(), msg.getRuleId().get(), msg.getEvent()); 154 + Optional<PluginId> pluginId = msg.getPluginId();
  155 + Optional<RuleId> ruleId = msg.getRuleId();
  156 + if (pluginId.isPresent()) {
  157 + target = pluginManager.getOrCreatePluginActor(this.context(), pluginId.get());
  158 + } else if (ruleId.isPresent()) {
  159 + Optional<ActorRef> ref = ruleManager.update(this.context(), ruleId.get(), msg.getEvent());
156 if (ref.isPresent()) { 160 if (ref.isPresent()) {
157 target = ref.get(); 161 target = ref.get();
158 } else { 162 } else {
159 - logger.debug("Failed to find actor for rule: [{}]", msg.getRuleId()); 163 + logger.debug("Failed to find actor for rule: [{}]", ruleId);
160 return; 164 return;
161 } 165 }
162 } 166 }
@@ -32,6 +32,8 @@ import org.thingsboard.server.actors.shared.plugin.TenantPluginManager; @@ -32,6 +32,8 @@ import org.thingsboard.server.actors.shared.plugin.TenantPluginManager;
32 import org.thingsboard.server.actors.shared.rule.RuleManager; 32 import org.thingsboard.server.actors.shared.rule.RuleManager;
33 import org.thingsboard.server.actors.shared.rule.TenantRuleManager; 33 import org.thingsboard.server.actors.shared.rule.TenantRuleManager;
34 import org.thingsboard.server.common.data.id.DeviceId; 34 import org.thingsboard.server.common.data.id.DeviceId;
  35 +import org.thingsboard.server.common.data.id.PluginId;
  36 +import org.thingsboard.server.common.data.id.RuleId;
35 import org.thingsboard.server.common.data.id.TenantId; 37 import org.thingsboard.server.common.data.id.TenantId;
36 import org.thingsboard.server.common.msg.cluster.ClusterEventMsg; 38 import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
37 import org.thingsboard.server.common.msg.device.ToDeviceActorMsg; 39 import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;
@@ -126,16 +128,18 @@ public class TenantActor extends ContextAwareActor { @@ -126,16 +128,18 @@ public class TenantActor extends ContextAwareActor {
126 } 128 }
127 129
128 private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { 130 private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) {
129 - if (msg.getPluginId().isPresent()) {  
130 - ActorRef pluginActor = pluginManager.getOrCreatePluginActor(this.context(), msg.getPluginId().get()); 131 + Optional<PluginId> pluginId = msg.getPluginId();
  132 + Optional<RuleId> ruleId = msg.getRuleId();
  133 + if (pluginId.isPresent()) {
  134 + ActorRef pluginActor = pluginManager.getOrCreatePluginActor(this.context(), pluginId.get());
131 pluginActor.tell(msg, ActorRef.noSender()); 135 pluginActor.tell(msg, ActorRef.noSender());
132 - } else if (msg.getRuleId().isPresent()) { 136 + } else if (ruleId.isPresent()) {
133 ActorRef target; 137 ActorRef target;
134 - Optional<ActorRef> ref = ruleManager.update(this.context(), msg.getRuleId().get(), msg.getEvent()); 138 + Optional<ActorRef> ref = ruleManager.update(this.context(), ruleId.get(), msg.getEvent());
135 if (ref.isPresent()) { 139 if (ref.isPresent()) {
136 target = ref.get(); 140 target = ref.get();
137 } else { 141 } else {
138 - logger.debug("Failed to find actor for rule: [{}]", msg.getRuleId()); 142 + logger.debug("Failed to find actor for rule: [{}]", ruleId);
139 return; 143 return;
140 } 144 }
141 target.tell(msg, ActorRef.noSender()); 145 target.tell(msg, ActorRef.noSender());
@@ -64,7 +64,7 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt @@ -64,7 +64,7 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt
64 public static final String FORM_BASED_LOGIN_ENTRY_POINT = "/api/auth/login"; 64 public static final String FORM_BASED_LOGIN_ENTRY_POINT = "/api/auth/login";
65 public static final String PUBLIC_LOGIN_ENTRY_POINT = "/api/auth/login/public"; 65 public static final String PUBLIC_LOGIN_ENTRY_POINT = "/api/auth/login/public";
66 public static final String TOKEN_REFRESH_ENTRY_POINT = "/api/auth/token"; 66 public static final String TOKEN_REFRESH_ENTRY_POINT = "/api/auth/token";
67 - public static final String[] NON_TOKEN_BASED_AUTH_ENTRY_POINTS = new String[] {"/index.html", "/static/**", "/api/noauth/**", "/webjars/**"}; 67 + protected static final String[] NON_TOKEN_BASED_AUTH_ENTRY_POINTS = new String[] {"/index.html", "/static/**", "/api/noauth/**", "/webjars/**"};
68 public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/api/**"; 68 public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/api/**";
69 public static final String WS_TOKEN_BASED_AUTH_ENTRY_POINT = "/api/ws/**"; 69 public static final String WS_TOKEN_BASED_AUTH_ENTRY_POINT = "/api/ws/**";
70 70
@@ -103,13 +103,13 @@ public class AuthController extends BaseController { @@ -103,13 +103,13 @@ public class AuthController extends BaseController {
103 HttpStatus responseStatus; 103 HttpStatus responseStatus;
104 UserCredentials userCredentials = userService.findUserCredentialsByActivateToken(activateToken); 104 UserCredentials userCredentials = userService.findUserCredentialsByActivateToken(activateToken);
105 if (userCredentials != null) { 105 if (userCredentials != null) {
106 - String createPasswordURI = "/login/createPassword"; 106 + String createURI = "/login/createPassword";
107 try { 107 try {
108 - URI location = new URI(createPasswordURI + "?activateToken=" + activateToken); 108 + URI location = new URI(createURI + "?activateToken=" + activateToken);
109 headers.setLocation(location); 109 headers.setLocation(location);
110 responseStatus = HttpStatus.SEE_OTHER; 110 responseStatus = HttpStatus.SEE_OTHER;
111 } catch (URISyntaxException e) { 111 } catch (URISyntaxException e) {
112 - log.error("Unable to create URI with address [{}]", createPasswordURI); 112 + log.error("Unable to create URI with address [{}]", createURI);
113 responseStatus = HttpStatus.BAD_REQUEST; 113 responseStatus = HttpStatus.BAD_REQUEST;
114 } 114 }
115 } else { 115 } else {
@@ -126,10 +126,10 @@ public class AuthController extends BaseController { @@ -126,10 +126,10 @@ public class AuthController extends BaseController {
126 try { 126 try {
127 UserCredentials userCredentials = userService.requestPasswordReset(email); 127 UserCredentials userCredentials = userService.requestPasswordReset(email);
128 String baseUrl = constructBaseUrl(request); 128 String baseUrl = constructBaseUrl(request);
129 - String resetPasswordUrl = String.format("%s/api/noauth/resetPassword?resetToken=%s", baseUrl, 129 + String resetUrl = String.format("%s/api/noauth/resetPassword?resetToken=%s", baseUrl,
130 userCredentials.getResetToken()); 130 userCredentials.getResetToken());
131 131
132 - mailService.sendResetPasswordEmail(resetPasswordUrl, email); 132 + mailService.sendResetPasswordEmail(resetUrl, email);
133 } catch (Exception e) { 133 } catch (Exception e) {
134 throw handleException(e); 134 throw handleException(e);
135 } 135 }
@@ -140,15 +140,15 @@ public class AuthController extends BaseController { @@ -140,15 +140,15 @@ public class AuthController extends BaseController {
140 @RequestParam(value = "resetToken") String resetToken) { 140 @RequestParam(value = "resetToken") String resetToken) {
141 HttpHeaders headers = new HttpHeaders(); 141 HttpHeaders headers = new HttpHeaders();
142 HttpStatus responseStatus; 142 HttpStatus responseStatus;
143 - String resetPasswordURI = "/login/resetPassword"; 143 + String resetURI = "/login/resetPassword";
144 UserCredentials userCredentials = userService.findUserCredentialsByResetToken(resetToken); 144 UserCredentials userCredentials = userService.findUserCredentialsByResetToken(resetToken);
145 if (userCredentials != null) { 145 if (userCredentials != null) {
146 try { 146 try {
147 - URI location = new URI(resetPasswordURI + "?resetToken=" + resetToken); 147 + URI location = new URI(resetURI + "?resetToken=" + resetToken);
148 headers.setLocation(location); 148 headers.setLocation(location);
149 responseStatus = HttpStatus.SEE_OTHER; 149 responseStatus = HttpStatus.SEE_OTHER;
150 } catch (URISyntaxException e) { 150 } catch (URISyntaxException e) {
151 - log.error("Unable to create URI with address [{}]", resetPasswordURI); 151 + log.error("Unable to create URI with address [{}]", resetURI);
152 responseStatus = HttpStatus.BAD_REQUEST; 152 responseStatus = HttpStatus.BAD_REQUEST;
153 } 153 }
154 } else { 154 } else {
@@ -267,9 +267,7 @@ public class EntityRelationController extends BaseController { @@ -267,9 +267,7 @@ public class EntityRelationController extends BaseController {
267 if (strRelationTypeGroup != null && strRelationTypeGroup.trim().length()>0) { 267 if (strRelationTypeGroup != null && strRelationTypeGroup.trim().length()>0) {
268 try { 268 try {
269 result = RelationTypeGroup.valueOf(strRelationTypeGroup); 269 result = RelationTypeGroup.valueOf(strRelationTypeGroup);
270 - } catch (IllegalArgumentException e) {  
271 - result = defaultValue;  
272 - } 270 + } catch (IllegalArgumentException e) { }
273 } 271 }
274 return result; 272 return result;
275 } 273 }
@@ -71,7 +71,7 @@ public class PluginApiController extends BaseController { @@ -71,7 +71,7 @@ public class PluginApiController extends BaseController {
71 TenantId tenantId = getCurrentUser().getTenantId(); 71 TenantId tenantId = getCurrentUser().getTenantId();
72 CustomerId customerId = getCurrentUser().getCustomerId(); 72 CustomerId customerId = getCurrentUser().getCustomerId();
73 if (validatePluginAccess(pluginMd, tenantId, customerId)) { 73 if (validatePluginAccess(pluginMd, tenantId, customerId)) {
74 - if(ModelConstants.NULL_UUID.equals(tenantId.getId())){ 74 + if(tenantId != null && ModelConstants.NULL_UUID.equals(tenantId.getId())){
75 tenantId = null; 75 tenantId = null;
76 } 76 }
77 PluginApiCallSecurityContext securityCtx = new PluginApiCallSecurityContext(pluginMd.getTenantId(), pluginMd.getId(), tenantId, customerId); 77 PluginApiCallSecurityContext securityCtx = new PluginApiCallSecurityContext(pluginMd.getTenantId(), pluginMd.getId(), tenantId, customerId);
@@ -97,7 +97,7 @@ public class PluginApiController extends BaseController { @@ -97,7 +97,7 @@ public class PluginApiController extends BaseController {
97 validUser = true; 97 validUser = true;
98 } 98 }
99 } else { 99 } else {
100 - if ((pluginMd.isPublicAccess() || tenantAdministrator) && tenantId.equals(pluginMd.getTenantId())) { 100 + if ((pluginMd.isPublicAccess() || tenantAdministrator) && tenantId != null && tenantId.equals(pluginMd.getTenantId())) {
101 // All tenant users can access public tenant plugins. Only tenant 101 // All tenant users can access public tenant plugins. Only tenant
102 // administrator can access private tenant plugins 102 // administrator can access private tenant plugins
103 validUser = true; 103 validUser = true;
@@ -95,6 +95,7 @@ public class ClusterGrpcService extends ClusterRpcServiceGrpc.ClusterRpcServiceI @@ -95,6 +95,7 @@ public class ClusterGrpcService extends ClusterRpcServiceGrpc.ClusterRpcServiceI
95 future.onMsg(msg); 95 future.onMsg(msg);
96 } catch (InterruptedException e) { 96 } catch (InterruptedException e) {
97 log.warn("Failed to report created session!"); 97 log.warn("Failed to report created session!");
  98 + Thread.currentThread().interrupt();
98 } 99 }
99 } else { 100 } else {
100 log.warn("Failed to lookup pending session!"); 101 log.warn("Failed to lookup pending session!");
@@ -117,6 +118,7 @@ public class ClusterGrpcService extends ClusterRpcServiceGrpc.ClusterRpcServiceI @@ -117,6 +118,7 @@ public class ClusterGrpcService extends ClusterRpcServiceGrpc.ClusterRpcServiceI
117 log.info("RPC server stopped!"); 118 log.info("RPC server stopped!");
118 } catch (InterruptedException e) { 119 } catch (InterruptedException e) {
119 log.warn("Failed to onStop RPC server!"); 120 log.warn("Failed to onStop RPC server!");
  121 + Thread.currentThread().interrupt();
120 } 122 }
121 } 123 }
122 } 124 }
@@ -51,6 +51,7 @@ import org.thingsboard.server.dao.widget.WidgetTypeService; @@ -51,6 +51,7 @@ import org.thingsboard.server.dao.widget.WidgetTypeService;
51 import org.thingsboard.server.dao.widget.WidgetsBundleService; 51 import org.thingsboard.server.dao.widget.WidgetsBundleService;
52 52
53 import java.io.IOException; 53 import java.io.IOException;
  54 +import java.nio.file.DirectoryStream;
54 import java.nio.file.Files; 55 import java.nio.file.Files;
55 import java.nio.file.Path; 56 import java.nio.file.Path;
56 import java.nio.file.Paths; 57 import java.nio.file.Paths;
@@ -138,7 +139,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { @@ -138,7 +139,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
138 node.put("timeout", "10000"); 139 node.put("timeout", "10000");
139 node.put("enableTls", "false"); 140 node.put("enableTls", "false");
140 node.put("username", ""); 141 node.put("username", "");
141 - node.put("password", ""); 142 + node.put("password", ""); //NOSONAR, key used to identify password field (not password value itself)
142 mailSettings.setJsonValue(node); 143 mailSettings.setJsonValue(node);
143 adminSettingsService.saveAdminSettings(mailSettings); 144 adminSettingsService.saveAdminSettings(mailSettings);
144 } 145 }
@@ -146,33 +147,34 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { @@ -146,33 +147,34 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
146 @Override 147 @Override
147 public void loadSystemWidgets() throws Exception { 148 public void loadSystemWidgets() throws Exception {
148 Path widgetBundlesDir = Paths.get(dataDir, JSON_DIR, SYSTEM_DIR, WIDGET_BUNDLES_DIR); 149 Path widgetBundlesDir = Paths.get(dataDir, JSON_DIR, SYSTEM_DIR, WIDGET_BUNDLES_DIR);
149 - Files.newDirectoryStream(widgetBundlesDir, path -> path.toString().endsWith(".json"))  
150 - .forEach(  
151 - path -> {  
152 - try {  
153 - JsonNode widgetsBundleDescriptorJson = objectMapper.readTree(path.toFile());  
154 - JsonNode widgetsBundleJson = widgetsBundleDescriptorJson.get("widgetsBundle");  
155 - WidgetsBundle widgetsBundle = objectMapper.treeToValue(widgetsBundleJson, WidgetsBundle.class);  
156 - WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);  
157 - JsonNode widgetTypesArrayJson = widgetsBundleDescriptorJson.get("widgetTypes");  
158 - widgetTypesArrayJson.forEach(  
159 - widgetTypeJson -> {  
160 - try {  
161 - WidgetType widgetType = objectMapper.treeToValue(widgetTypeJson, WidgetType.class);  
162 - widgetType.setBundleAlias(savedWidgetsBundle.getAlias());  
163 - widgetTypeService.saveWidgetType(widgetType);  
164 - } catch (Exception e) {  
165 - log.error("Unable to load widget type from json: [{}]", path.toString());  
166 - throw new RuntimeException("Unable to load widget type from json", e);  
167 - } 150 + try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(widgetBundlesDir, path -> path.toString().endsWith(".json"))) {
  151 + dirStream.forEach(
  152 + path -> {
  153 + try {
  154 + JsonNode widgetsBundleDescriptorJson = objectMapper.readTree(path.toFile());
  155 + JsonNode widgetsBundleJson = widgetsBundleDescriptorJson.get("widgetsBundle");
  156 + WidgetsBundle widgetsBundle = objectMapper.treeToValue(widgetsBundleJson, WidgetsBundle.class);
  157 + WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
  158 + JsonNode widgetTypesArrayJson = widgetsBundleDescriptorJson.get("widgetTypes");
  159 + widgetTypesArrayJson.forEach(
  160 + widgetTypeJson -> {
  161 + try {
  162 + WidgetType widgetType = objectMapper.treeToValue(widgetTypeJson, WidgetType.class);
  163 + widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
  164 + widgetTypeService.saveWidgetType(widgetType);
  165 + } catch (Exception e) {
  166 + log.error("Unable to load widget type from json: [{}]", path.toString());
  167 + throw new RuntimeException("Unable to load widget type from json", e);
168 } 168 }
169 - );  
170 - } catch (Exception e) {  
171 - log.error("Unable to load widgets bundle from json: [{}]", path.toString());  
172 - throw new RuntimeException("Unable to load widgets bundle from json", e);  
173 - } 169 + }
  170 + );
  171 + } catch (Exception e) {
  172 + log.error("Unable to load widgets bundle from json: [{}]", path.toString());
  173 + throw new RuntimeException("Unable to load widgets bundle from json", e);
174 } 174 }
175 - ); 175 + }
  176 + );
  177 + }
176 } 178 }
177 179
178 @Override 180 @Override
@@ -279,67 +281,69 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { @@ -279,67 +281,69 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService {
279 } 281 }
280 282
281 private void loadPlugins(Path pluginsDir, TenantId tenantId) throws Exception{ 283 private void loadPlugins(Path pluginsDir, TenantId tenantId) throws Exception{
282 - Files.newDirectoryStream(pluginsDir, path -> path.toString().endsWith(".json"))  
283 - .forEach(  
284 - path -> {  
285 - try {  
286 - JsonNode pluginJson = objectMapper.readTree(path.toFile());  
287 - PluginMetaData plugin = objectMapper.treeToValue(pluginJson, PluginMetaData.class);  
288 - plugin.setTenantId(tenantId);  
289 - if (plugin.getState() == ComponentLifecycleState.ACTIVE) {  
290 - plugin.setState(ComponentLifecycleState.SUSPENDED);  
291 - PluginMetaData savedPlugin = pluginService.savePlugin(plugin);  
292 - pluginService.activatePluginById(savedPlugin.getId());  
293 - } else {  
294 - pluginService.savePlugin(plugin);  
295 - }  
296 - } catch (Exception e) {  
297 - log.error("Unable to load plugin from json: [{}]", path.toString());  
298 - throw new RuntimeException("Unable to load plugin from json", e); 284 + try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(pluginsDir, path -> path.toString().endsWith(".json"))) {
  285 + dirStream.forEach(
  286 + path -> {
  287 + try {
  288 + JsonNode pluginJson = objectMapper.readTree(path.toFile());
  289 + PluginMetaData plugin = objectMapper.treeToValue(pluginJson, PluginMetaData.class);
  290 + plugin.setTenantId(tenantId);
  291 + if (plugin.getState() == ComponentLifecycleState.ACTIVE) {
  292 + plugin.setState(ComponentLifecycleState.SUSPENDED);
  293 + PluginMetaData savedPlugin = pluginService.savePlugin(plugin);
  294 + pluginService.activatePluginById(savedPlugin.getId());
  295 + } else {
  296 + pluginService.savePlugin(plugin);
299 } 297 }
  298 + } catch (Exception e) {
  299 + log.error("Unable to load plugin from json: [{}]", path.toString());
  300 + throw new RuntimeException("Unable to load plugin from json", e);
300 } 301 }
301 - );  
302 - 302 + }
  303 + );
  304 + }
303 } 305 }
304 306
305 private void loadRules(Path rulesDir, TenantId tenantId) throws Exception { 307 private void loadRules(Path rulesDir, TenantId tenantId) throws Exception {
306 - Files.newDirectoryStream(rulesDir, path -> path.toString().endsWith(".json"))  
307 - .forEach(  
308 - path -> {  
309 - try {  
310 - JsonNode ruleJson = objectMapper.readTree(path.toFile());  
311 - RuleMetaData rule = objectMapper.treeToValue(ruleJson, RuleMetaData.class);  
312 - rule.setTenantId(tenantId);  
313 - if (rule.getState() == ComponentLifecycleState.ACTIVE) {  
314 - rule.setState(ComponentLifecycleState.SUSPENDED);  
315 - RuleMetaData savedRule = ruleService.saveRule(rule);  
316 - ruleService.activateRuleById(savedRule.getId());  
317 - } else {  
318 - ruleService.saveRule(rule);  
319 - }  
320 - } catch (Exception e) {  
321 - log.error("Unable to load rule from json: [{}]", path.toString());  
322 - throw new RuntimeException("Unable to load rule from json", e); 308 + try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(rulesDir, path -> path.toString().endsWith(".json"))) {
  309 + dirStream.forEach(
  310 + path -> {
  311 + try {
  312 + JsonNode ruleJson = objectMapper.readTree(path.toFile());
  313 + RuleMetaData rule = objectMapper.treeToValue(ruleJson, RuleMetaData.class);
  314 + rule.setTenantId(tenantId);
  315 + if (rule.getState() == ComponentLifecycleState.ACTIVE) {
  316 + rule.setState(ComponentLifecycleState.SUSPENDED);
  317 + RuleMetaData savedRule = ruleService.saveRule(rule);
  318 + ruleService.activateRuleById(savedRule.getId());
  319 + } else {
  320 + ruleService.saveRule(rule);
323 } 321 }
  322 + } catch (Exception e) {
  323 + log.error("Unable to load rule from json: [{}]", path.toString());
  324 + throw new RuntimeException("Unable to load rule from json", e);
324 } 325 }
325 - ); 326 + }
  327 + );
  328 + }
326 } 329 }
327 330
328 private void loadDashboards(Path dashboardsDir, TenantId tenantId, CustomerId customerId) throws Exception { 331 private void loadDashboards(Path dashboardsDir, TenantId tenantId, CustomerId customerId) throws Exception {
329 - Files.newDirectoryStream(dashboardsDir, path -> path.toString().endsWith(".json"))  
330 - .forEach(  
331 - path -> {  
332 - try {  
333 - JsonNode dashboardJson = objectMapper.readTree(path.toFile());  
334 - Dashboard dashboard = objectMapper.treeToValue(dashboardJson, Dashboard.class);  
335 - dashboard.setTenantId(tenantId);  
336 - dashboard.setCustomerId(customerId);  
337 - dashboardService.saveDashboard(dashboard);  
338 - } catch (Exception e) {  
339 - log.error("Unable to load dashboard from json: [{}]", path.toString());  
340 - throw new RuntimeException("Unable to load dashboard from json", e);  
341 - } 332 + try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(dashboardsDir, path -> path.toString().endsWith(".json"))) {
  333 + dirStream.forEach(
  334 + path -> {
  335 + try {
  336 + JsonNode dashboardJson = objectMapper.readTree(path.toFile());
  337 + Dashboard dashboard = objectMapper.treeToValue(dashboardJson, Dashboard.class);
  338 + dashboard.setTenantId(tenantId);
  339 + dashboard.setCustomerId(customerId);
  340 + dashboardService.saveDashboard(dashboard);
  341 + } catch (Exception e) {
  342 + log.error("Unable to load dashboard from json: [{}]", path.toString());
  343 + throw new RuntimeException("Unable to load dashboard from json", e);
342 } 344 }
343 - ); 345 + }
  346 + );
  347 + }
344 } 348 }
345 } 349 }
@@ -28,6 +28,7 @@ import java.nio.file.Path; @@ -28,6 +28,7 @@ import java.nio.file.Path;
28 import java.nio.file.Paths; 28 import java.nio.file.Paths;
29 import java.sql.Connection; 29 import java.sql.Connection;
30 import java.sql.DriverManager; 30 import java.sql.DriverManager;
  31 +import java.sql.PreparedStatement;
31 32
32 @Service 33 @Service
33 @Profile("install") 34 @Profile("install")
@@ -58,7 +59,7 @@ public class SqlDatabaseSchemaService implements DatabaseSchemaService { @@ -58,7 +59,7 @@ public class SqlDatabaseSchemaService implements DatabaseSchemaService {
58 Path schemaFile = Paths.get(this.dataDir, SQL_DIR, SCHEMA_SQL); 59 Path schemaFile = Paths.get(this.dataDir, SQL_DIR, SCHEMA_SQL);
59 try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { 60 try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) {
60 String sql = new String(Files.readAllBytes(schemaFile), Charset.forName("UTF-8")); 61 String sql = new String(Files.readAllBytes(schemaFile), Charset.forName("UTF-8"));
61 - conn.createStatement().execute(sql); 62 + conn.prepareStatement(sql).execute(); //NOSONAR, ignoring because method used to load initial thingsboard database schema
62 } 63 }
63 64
64 } 65 }
@@ -24,7 +24,7 @@ import javax.servlet.http.HttpServletRequest; @@ -24,7 +24,7 @@ import javax.servlet.http.HttpServletRequest;
24 24
25 @Component(value="jwtHeaderTokenExtractor") 25 @Component(value="jwtHeaderTokenExtractor")
26 public class JwtHeaderTokenExtractor implements TokenExtractor { 26 public class JwtHeaderTokenExtractor implements TokenExtractor {
27 - public static String HEADER_PREFIX = "Bearer "; 27 + public static final String HEADER_PREFIX = "Bearer ";
28 28
29 @Override 29 @Override
30 public String extract(HttpServletRequest request) { 30 public String extract(HttpServletRequest request) {
@@ -29,7 +29,9 @@ public class DataConstants { @@ -29,7 +29,9 @@ public class DataConstants {
29 public static final String SERVER_SCOPE = "SERVER_SCOPE"; 29 public static final String SERVER_SCOPE = "SERVER_SCOPE";
30 public static final String SHARED_SCOPE = "SHARED_SCOPE"; 30 public static final String SHARED_SCOPE = "SHARED_SCOPE";
31 31
32 - public static final String[] ALL_SCOPES = {CLIENT_SCOPE, SHARED_SCOPE, SERVER_SCOPE}; 32 + public static final String[] allScopes() {
  33 + return new String[]{CLIENT_SCOPE, SHARED_SCOPE, SERVER_SCOPE};
  34 + }
33 35
34 public static final String ALARM = "ALARM"; 36 public static final String ALARM = "ALARM";
35 public static final String ERROR = "ERROR"; 37 public static final String ERROR = "ERROR";
@@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.page; @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.page;
17 17
18 import java.util.Iterator; 18 import java.util.Iterator;
19 import java.util.List; 19 import java.util.List;
  20 +import java.util.NoSuchElementException;
20 21
21 import org.thingsboard.server.common.data.SearchTextBased; 22 import org.thingsboard.server.common.data.SearchTextBased;
22 import org.thingsboard.server.common.data.id.UUIDBased; 23 import org.thingsboard.server.common.data.id.UUIDBased;
@@ -54,7 +55,7 @@ public class PageDataIterable<T extends SearchTextBased<? extends UUIDBased>> im @@ -54,7 +55,7 @@ public class PageDataIterable<T extends SearchTextBased<? extends UUIDBased>> im
54 fetch(nextPackLink); 55 fetch(nextPackLink);
55 } 56 }
56 } 57 }
57 - return currentIdx != currentItems.size(); 58 + return currentIdx < currentItems.size();
58 } 59 }
59 60
60 private void fetch(TextPageLink link) { 61 private void fetch(TextPageLink link) {
@@ -67,6 +68,9 @@ public class PageDataIterable<T extends SearchTextBased<? extends UUIDBased>> im @@ -67,6 +68,9 @@ public class PageDataIterable<T extends SearchTextBased<? extends UUIDBased>> im
67 68
68 @Override 69 @Override
69 public T next() { 70 public T next() {
  71 + if(!hasNext()){
  72 + throw new NoSuchElementException();
  73 + }
70 return currentItems.get(currentIdx++); 74 return currentItems.get(currentIdx++);
71 } 75 }
72 76
@@ -46,10 +46,7 @@ import org.thingsboard.server.dao.service.PaginatedRemover; @@ -46,10 +46,7 @@ import org.thingsboard.server.dao.service.PaginatedRemover;
46 import org.thingsboard.server.dao.tenant.TenantDao; 46 import org.thingsboard.server.dao.tenant.TenantDao;
47 47
48 import javax.annotation.Nullable; 48 import javax.annotation.Nullable;
49 -import java.util.ArrayList;  
50 -import java.util.Comparator;  
51 -import java.util.List;  
52 -import java.util.Optional; 49 +import java.util.*;
53 import java.util.stream.Collectors; 50 import java.util.stream.Collectors;
54 51
55 import static org.thingsboard.server.dao.DaoUtil.toUUIDs; 52 import static org.thingsboard.server.dao.DaoUtil.toUUIDs;
@@ -210,7 +207,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @@ -210,7 +207,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ
210 @Nullable 207 @Nullable
211 @Override 208 @Override
212 public List<Asset> apply(@Nullable List<Asset> assetList) { 209 public List<Asset> apply(@Nullable List<Asset> assetList) {
213 - return assetList.stream().filter(asset -> query.getAssetTypes().contains(asset.getType())).collect(Collectors.toList()); 210 + return assetList == null ? Collections.emptyList() : assetList.stream().filter(asset -> query.getAssetTypes().contains(asset.getType())).collect(Collectors.toList());
214 } 211 }
215 }); 212 });
216 213
@@ -109,18 +109,21 @@ public class CassandraBaseAttributesDao extends CassandraAbstractAsyncDao implem @@ -109,18 +109,21 @@ public class CassandraBaseAttributesDao extends CassandraAbstractAsyncDao implem
109 stmt.setString(3, attribute.getKey()); 109 stmt.setString(3, attribute.getKey());
110 stmt.setLong(4, attribute.getLastUpdateTs()); 110 stmt.setLong(4, attribute.getLastUpdateTs());
111 stmt.setString(5, attribute.getStrValue().orElse(null)); 111 stmt.setString(5, attribute.getStrValue().orElse(null));
112 - if (attribute.getBooleanValue().isPresent()) {  
113 - stmt.setBool(6, attribute.getBooleanValue().get()); 112 + Optional<Boolean> booleanValue = attribute.getBooleanValue();
  113 + if (booleanValue.isPresent()) {
  114 + stmt.setBool(6, booleanValue.get());
114 } else { 115 } else {
115 stmt.setToNull(6); 116 stmt.setToNull(6);
116 } 117 }
117 - if (attribute.getLongValue().isPresent()) {  
118 - stmt.setLong(7, attribute.getLongValue().get()); 118 + Optional<Long> longValue = attribute.getLongValue();
  119 + if (longValue.isPresent()) {
  120 + stmt.setLong(7, longValue.get());
119 } else { 121 } else {
120 stmt.setToNull(7); 122 stmt.setToNull(7);
121 } 123 }
122 - if (attribute.getDoubleValue().isPresent()) {  
123 - stmt.setDouble(8, attribute.getDoubleValue().get()); 124 + Optional<Double> doubleValue = attribute.getDoubleValue();
  125 + if (doubleValue.isPresent()) {
  126 + stmt.setDouble(8, doubleValue.get());
124 } else { 127 } else {
125 stmt.setToNull(8); 128 stmt.setToNull(8);
126 } 129 }
@@ -153,6 +153,7 @@ public abstract class AbstractCassandraCluster { @@ -153,6 +153,7 @@ public abstract class AbstractCassandraCluster {
153 Thread.sleep(initRetryInterval); 153 Thread.sleep(initRetryInterval);
154 } catch (InterruptedException ie) { 154 } catch (InterruptedException ie) {
155 log.warn("Failed to wait until retry", ie); 155 log.warn("Failed to wait until retry", ie);
  156 + Thread.currentThread().interrupt();
156 } 157 }
157 } 158 }
158 } 159 }
@@ -44,10 +44,7 @@ import org.thingsboard.server.dao.service.PaginatedRemover; @@ -44,10 +44,7 @@ import org.thingsboard.server.dao.service.PaginatedRemover;
44 import org.thingsboard.server.dao.tenant.TenantDao; 44 import org.thingsboard.server.dao.tenant.TenantDao;
45 45
46 import javax.annotation.Nullable; 46 import javax.annotation.Nullable;
47 -import java.util.ArrayList;  
48 -import java.util.Comparator;  
49 -import java.util.List;  
50 -import java.util.Optional; 47 +import java.util.*;
51 import java.util.stream.Collectors; 48 import java.util.stream.Collectors;
52 49
53 import static org.thingsboard.server.dao.DaoUtil.toUUIDs; 50 import static org.thingsboard.server.dao.DaoUtil.toUUIDs;
@@ -230,7 +227,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @@ -230,7 +227,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe
230 @Nullable 227 @Nullable
231 @Override 228 @Override
232 public List<Device> apply(@Nullable List<Device> deviceList) { 229 public List<Device> apply(@Nullable List<Device> deviceList) {
233 - return deviceList.stream().filter(device -> query.getDeviceTypes().contains(device.getType())).collect(Collectors.toList()); 230 + return deviceList == null ? Collections.emptyList() : deviceList.stream().filter(device -> query.getDeviceTypes().contains(device.getType())).collect(Collectors.toList());
234 } 231 }
235 }); 232 });
236 233
@@ -27,8 +27,8 @@ public class ModelConstants { @@ -27,8 +27,8 @@ public class ModelConstants {
27 private ModelConstants() { 27 private ModelConstants() {
28 } 28 }
29 29
30 - public static UUID NULL_UUID = UUIDs.startOf(0);  
31 - public static String NULL_UUID_STR = UUIDConverter.fromTimeUUID(NULL_UUID); 30 + public static final UUID NULL_UUID = UUIDs.startOf(0);
  31 + public static final String NULL_UUID_STR = UUIDConverter.fromTimeUUID(NULL_UUID);
32 32
33 /** 33 /**
34 * Generic constants. 34 * Generic constants.
@@ -66,7 +66,7 @@ public class ModelConstants { @@ -66,7 +66,7 @@ public class ModelConstants {
66 public static final String USER_CREDENTIALS_COLUMN_FAMILY_NAME = "user_credentials"; 66 public static final String USER_CREDENTIALS_COLUMN_FAMILY_NAME = "user_credentials";
67 public static final String USER_CREDENTIALS_USER_ID_PROPERTY = USER_ID_PROPERTY; 67 public static final String USER_CREDENTIALS_USER_ID_PROPERTY = USER_ID_PROPERTY;
68 public static final String USER_CREDENTIALS_ENABLED_PROPERTY = "enabled"; 68 public static final String USER_CREDENTIALS_ENABLED_PROPERTY = "enabled";
69 - public static final String USER_CREDENTIALS_PASSWORD_PROPERTY = "password"; 69 + public static final String USER_CREDENTIALS_PASSWORD_PROPERTY = "password"; //NOSONAR, the constant used to identify password column name (not password value itself)
70 public static final String USER_CREDENTIALS_ACTIVATE_TOKEN_PROPERTY = "activate_token"; 70 public static final String USER_CREDENTIALS_ACTIVATE_TOKEN_PROPERTY = "activate_token";
71 public static final String USER_CREDENTIALS_RESET_TOKEN_PROPERTY = "reset_token"; 71 public static final String USER_CREDENTIALS_RESET_TOKEN_PROPERTY = "reset_token";
72 72
@@ -328,17 +328,17 @@ public class ModelConstants { @@ -328,17 +328,17 @@ public class ModelConstants {
328 public static final String LONG_VALUE_COLUMN = "long_v"; 328 public static final String LONG_VALUE_COLUMN = "long_v";
329 public static final String DOUBLE_VALUE_COLUMN = "dbl_v"; 329 public static final String DOUBLE_VALUE_COLUMN = "dbl_v";
330 330
331 - 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}; 331 + 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};
332 332
333 - 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)}; 333 + 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)};
334 334
335 - public static final String[] MIN_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, 335 + protected static final String[] MIN_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS,
336 new String[]{min(LONG_VALUE_COLUMN), min(DOUBLE_VALUE_COLUMN), min(BOOLEAN_VALUE_COLUMN), min(STRING_VALUE_COLUMN)}); 336 new String[]{min(LONG_VALUE_COLUMN), min(DOUBLE_VALUE_COLUMN), min(BOOLEAN_VALUE_COLUMN), min(STRING_VALUE_COLUMN)});
337 - public static final String[] MAX_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, 337 + protected static final String[] MAX_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS,
338 new String[]{max(LONG_VALUE_COLUMN), max(DOUBLE_VALUE_COLUMN), max(BOOLEAN_VALUE_COLUMN), max(STRING_VALUE_COLUMN)}); 338 new String[]{max(LONG_VALUE_COLUMN), max(DOUBLE_VALUE_COLUMN), max(BOOLEAN_VALUE_COLUMN), max(STRING_VALUE_COLUMN)});
339 - public static final String[] SUM_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, 339 + protected static final String[] SUM_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS,
340 new String[]{sum(LONG_VALUE_COLUMN), sum(DOUBLE_VALUE_COLUMN)}); 340 new String[]{sum(LONG_VALUE_COLUMN), sum(DOUBLE_VALUE_COLUMN)});
341 - public static final String[] AVG_AGGREGATION_COLUMNS = SUM_AGGREGATION_COLUMNS; 341 + protected static final String[] AVG_AGGREGATION_COLUMNS = SUM_AGGREGATION_COLUMNS;
342 342
343 public static String min(String s) { 343 public static String min(String s) {
344 return "min(" + s + ")"; 344 return "min(" + s + ")";
@@ -57,12 +57,7 @@ public abstract class DataValidator<D extends BaseData<?>> { @@ -57,12 +57,7 @@ public abstract class DataValidator<D extends BaseData<?>> {
57 } 57 }
58 58
59 protected boolean isSameData(D existentData, D actualData) { 59 protected boolean isSameData(D existentData, D actualData) {
60 - if (actualData.getId() == null) {  
61 - return false;  
62 - } else if (!existentData.getId().equals(actualData.getId())) {  
63 - return false;  
64 - }  
65 - return true; 60 + return actualData.getId() != null && existentData.getId().equals(actualData.getId());
66 } 61 }
67 62
68 protected static void validateEmail(String email) { 63 protected static void validateEmail(String email) {
@@ -117,11 +117,7 @@ public class Validator { @@ -117,11 +117,7 @@ public class Validator {
117 * @param errorMessage the error message for exception 117 * @param errorMessage the error message for exception
118 */ 118 */
119 public static void validatePageLink(TextPageLink pageLink, String errorMessage) { 119 public static void validatePageLink(TextPageLink pageLink, String errorMessage) {
120 - if (pageLink == null) {  
121 - throw new IncorrectParameterException(errorMessage);  
122 - } else if (pageLink.getLimit() < 1) {  
123 - throw new IncorrectParameterException(errorMessage);  
124 - } else if (pageLink.getIdOffset() != null && pageLink.getIdOffset().version() != 1) { 120 + if (pageLink == null || pageLink.getLimit() < 1 || (pageLink.getIdOffset() != null && pageLink.getIdOffset().version() != 1)) {
125 throw new IncorrectParameterException(errorMessage); 121 throw new IncorrectParameterException(errorMessage);
126 } 122 }
127 } 123 }
@@ -168,7 +168,6 @@ public class JpaTimeseriesDao extends JpaAbstractDaoListeningExecutorService imp @@ -168,7 +168,6 @@ public class JpaTimeseriesDao extends JpaAbstractDaoListeningExecutorService imp
168 } 168 }
169 }); 169 });
170 return Futures.transform(listenableFuture, new Function<TsKvEntity, Optional<TsKvEntry>>() { 170 return Futures.transform(listenableFuture, new Function<TsKvEntity, Optional<TsKvEntry>>() {
171 - @Nullable  
172 @Override 171 @Override
173 public Optional<TsKvEntry> apply(@Nullable TsKvEntity entity) { 172 public Optional<TsKvEntry> apply(@Nullable TsKvEntity entity) {
174 if (entity != null && entity.isNotEmpty()) { 173 if (entity != null && entity.isNotEmpty()) {
@@ -49,7 +49,6 @@ public class AggregatePartitionsFunction implements com.google.common.base.Funct @@ -49,7 +49,6 @@ public class AggregatePartitionsFunction implements com.google.common.base.Funct
49 this.ts = ts; 49 this.ts = ts;
50 } 50 }
51 51
52 - @Nullable  
53 @Override 52 @Override
54 public Optional<TsKvEntry> apply(@Nullable List<ResultSet> rsList) { 53 public Optional<TsKvEntry> apply(@Nullable List<ResultSet> rsList) {
55 try { 54 try {
@@ -42,6 +42,7 @@ import java.time.Instant; @@ -42,6 +42,7 @@ import java.time.Instant;
42 import java.time.LocalDateTime; 42 import java.time.LocalDateTime;
43 import java.time.ZoneOffset; 43 import java.time.ZoneOffset;
44 import java.util.ArrayList; 44 import java.util.ArrayList;
  45 +import java.util.Collections;
45 import java.util.List; 46 import java.util.List;
46 import java.util.Optional; 47 import java.util.Optional;
47 import java.util.stream.Collectors; 48 import java.util.stream.Collectors;
@@ -136,7 +137,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @@ -136,7 +137,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
136 @Nullable 137 @Nullable
137 @Override 138 @Override
138 public List<TsKvEntry> apply(@Nullable List<Optional<TsKvEntry>> input) { 139 public List<TsKvEntry> apply(@Nullable List<Optional<TsKvEntry>> input) {
139 - return input.stream().filter(v -> v.isPresent()).map(v -> v.get()).collect(Collectors.toList()); 140 + return input == null ? Collections.emptyList() : input.stream().filter(v -> v.isPresent()).map(v -> v.get()).collect(Collectors.toList());
140 } 141 }
141 }, readResultsProcessingExecutor); 142 }, readResultsProcessingExecutor);
142 } 143 }
@@ -189,7 +190,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @@ -189,7 +190,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
189 Futures.addCallback(executeAsyncRead(stmt), new FutureCallback<ResultSet>() { 190 Futures.addCallback(executeAsyncRead(stmt), new FutureCallback<ResultSet>() {
190 @Override 191 @Override
191 public void onSuccess(@Nullable ResultSet result) { 192 public void onSuccess(@Nullable ResultSet result) {
192 - cursor.addData(convertResultToTsKvEntryList(result.all())); 193 + cursor.addData(convertResultToTsKvEntryList(result == null ? Collections.emptyList() : result.all()));
193 findAllAsyncSequentiallyWithLimit(cursor, resultFuture); 194 findAllAsyncSequentiallyWithLimit(cursor, resultFuture);
194 } 195 }
195 196
@@ -523,16 +524,28 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @@ -523,16 +524,28 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem
523 private static void addValue(KvEntry kvEntry, BoundStatement stmt, int column) { 524 private static void addValue(KvEntry kvEntry, BoundStatement stmt, int column) {
524 switch (kvEntry.getDataType()) { 525 switch (kvEntry.getDataType()) {
525 case BOOLEAN: 526 case BOOLEAN:
526 - stmt.setBool(column, kvEntry.getBooleanValue().get().booleanValue()); 527 + Optional<Boolean> booleanValue = kvEntry.getBooleanValue();
  528 + if (booleanValue.isPresent()) {
  529 + stmt.setBool(column, booleanValue.get().booleanValue());
  530 + }
527 break; 531 break;
528 case STRING: 532 case STRING:
529 - stmt.setString(column, kvEntry.getStrValue().get()); 533 + Optional<String> stringValue = kvEntry.getStrValue();
  534 + if (stringValue.isPresent()) {
  535 + stmt.setString(column, stringValue.get());
  536 + }
530 break; 537 break;
531 case LONG: 538 case LONG:
532 - stmt.setLong(column, kvEntry.getLongValue().get().longValue()); 539 + Optional<Long> longValue = kvEntry.getLongValue();
  540 + if (longValue.isPresent()) {
  541 + stmt.setLong(column, longValue.get().longValue());
  542 + }
533 break; 543 break;
534 case DOUBLE: 544 case DOUBLE:
535 - stmt.setDouble(column, kvEntry.getDoubleValue().get().doubleValue()); 545 + Optional<Double> doubleValue = kvEntry.getDoubleValue();
  546 + if (doubleValue.isPresent()) {
  547 + stmt.setDouble(column, doubleValue.get().doubleValue());
  548 + }
536 break; 549 break;
537 } 550 }
538 } 551 }
@@ -25,7 +25,7 @@ public enum TsPartitionDate { @@ -25,7 +25,7 @@ public enum TsPartitionDate {
25 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); 25 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);
26 26
27 private final String pattern; 27 private final String pattern;
28 - private final TemporalUnit truncateUnit; 28 + private final transient TemporalUnit truncateUnit;
29 29
30 TsPartitionDate(String pattern, TemporalUnit truncateUnit) { 30 TsPartitionDate(String pattern, TemporalUnit truncateUnit) {
31 this.pattern = pattern; 31 this.pattern = pattern;
@@ -71,7 +71,7 @@ public class DefaultWebsocketMsgHandler implements WebsocketMsgHandler { @@ -71,7 +71,7 @@ public class DefaultWebsocketMsgHandler implements WebsocketMsgHandler {
71 wsSessionsMap.put(sessionId, new WsSessionMetaData(sessionRef)); 71 wsSessionsMap.put(sessionId, new WsSessionMetaData(sessionRef));
72 break; 72 break;
73 case ERROR: 73 case ERROR:
74 - log.debug("[{}] Unknown websocket session error: {}. ", sessionId, event.getError().get()); 74 + log.debug("[{}] Unknown websocket session error: {}. ", sessionId, event.getError().orElse(null));
75 break; 75 break;
76 case CLOSED: 76 case CLOSED:
77 wsSessionsMap.remove(sessionId); 77 wsSessionsMap.remove(sessionId);
@@ -85,13 +85,13 @@ public class NashornJsEvaluator { @@ -85,13 +85,13 @@ public class NashornJsEvaluator {
85 protected static Object getValue(KvEntry attr) { 85 protected static Object getValue(KvEntry attr) {
86 switch (attr.getDataType()) { 86 switch (attr.getDataType()) {
87 case STRING: 87 case STRING:
88 - return attr.getStrValue().get(); 88 + return attr.getStrValue().orElse(null);
89 case LONG: 89 case LONG:
90 - return attr.getLongValue().get(); 90 + return attr.getLongValue().orElse(null);
91 case DOUBLE: 91 case DOUBLE:
92 - return attr.getDoubleValue().get(); 92 + return attr.getDoubleValue().orElse(null);
93 case BOOLEAN: 93 case BOOLEAN:
94 - return attr.getBooleanValue().get(); 94 + return attr.getBooleanValue().orElse(null);
95 } 95 }
96 return null; 96 return null;
97 } 97 }
@@ -34,10 +34,7 @@ import org.thingsboard.server.extensions.api.plugins.handlers.RuleMsgHandler; @@ -34,10 +34,7 @@ import org.thingsboard.server.extensions.api.plugins.handlers.RuleMsgHandler;
34 import org.thingsboard.server.extensions.api.plugins.msg.*; 34 import org.thingsboard.server.extensions.api.plugins.msg.*;
35 import org.thingsboard.server.extensions.api.rules.RuleException; 35 import org.thingsboard.server.extensions.api.rules.RuleException;
36 36
37 -import java.util.HashMap;  
38 -import java.util.List;  
39 -import java.util.Map;  
40 -import java.util.UUID; 37 +import java.util.*;
41 38
42 /** 39 /**
43 * @author Andrew Shvayka 40 * @author Andrew Shvayka
@@ -89,8 +86,9 @@ public class DeviceMessagingRuleMsgHandler implements RuleMsgHandler { @@ -89,8 +86,9 @@ public class DeviceMessagingRuleMsgHandler implements RuleMsgHandler {
89 if (pendindMsg != null) { 86 if (pendindMsg != null) {
90 log.trace("[{}] Received response: {}", requestId, msg); 87 log.trace("[{}] Received response: {}", requestId, msg);
91 ToServerRpcResponseMsg response; 88 ToServerRpcResponseMsg response;
92 - if (msg.getError().isPresent()) {  
93 - response = new ToServerRpcResponseMsg(pendindMsg.getRequestId(), toJsonString(msg.getError().get())); 89 + Optional<RpcError> rpcError = msg.getError();
  90 + if (rpcError.isPresent()) {
  91 + response = new ToServerRpcResponseMsg(pendindMsg.getRequestId(), toJsonString(rpcError.get()));
94 } else { 92 } else {
95 response = new ToServerRpcResponseMsg(pendindMsg.getRequestId(), msg.getResponse().orElse("")); 93 response = new ToServerRpcResponseMsg(pendindMsg.getRequestId(), msg.getResponse().orElse(""));
96 } 94 }
@@ -110,8 +110,9 @@ public class RpcRestMsgHandler extends DefaultRestMsgHandler { @@ -110,8 +110,9 @@ public class RpcRestMsgHandler extends DefaultRestMsgHandler {
110 } 110 }
111 111
112 public void reply(PluginContext ctx, DeferredResult<ResponseEntity> responseWriter, FromDeviceRpcResponse response) { 112 public void reply(PluginContext ctx, DeferredResult<ResponseEntity> responseWriter, FromDeviceRpcResponse response) {
113 - if (response.getError().isPresent()) {  
114 - RpcError error = response.getError().get(); 113 + Optional<RpcError> rpcError = response.getError();
  114 + if (rpcError.isPresent()) {
  115 + RpcError error = rpcError.get();
115 switch (error) { 116 switch (error) {
116 case TIMEOUT: 117 case TIMEOUT:
117 responseWriter.setResult(new ResponseEntity<>(HttpStatus.REQUEST_TIMEOUT)); 118 responseWriter.setResult(new ResponseEntity<>(HttpStatus.REQUEST_TIMEOUT));
@@ -124,8 +125,9 @@ public class RpcRestMsgHandler extends DefaultRestMsgHandler { @@ -124,8 +125,9 @@ public class RpcRestMsgHandler extends DefaultRestMsgHandler {
124 break; 125 break;
125 } 126 }
126 } else { 127 } else {
127 - if (response.getResponse().isPresent() && !StringUtils.isEmpty(response.getResponse().get())) {  
128 - String data = response.getResponse().get(); 128 + Optional<String> responseData = response.getResponse();
  129 + if (responseData.isPresent() && !StringUtils.isEmpty(responseData.get())) {
  130 + String data = responseData.get();
129 try { 131 try {
130 responseWriter.setResult(new ResponseEntity<>(jsonMapper.readTree(data), HttpStatus.OK)); 132 responseWriter.setResult(new ResponseEntity<>(jsonMapper.readTree(data), HttpStatus.OK));
131 } catch (IOException e) { 133 } catch (IOException e) {
@@ -92,7 +92,7 @@ public class TelemetryRestMsgHandler extends DefaultRestMsgHandler { @@ -92,7 +92,7 @@ public class TelemetryRestMsgHandler extends DefaultRestMsgHandler {
92 if (!StringUtils.isEmpty(scope)) { 92 if (!StringUtils.isEmpty(scope)) {
93 ctx.loadAttributes(entityId, scope, callback); 93 ctx.loadAttributes(entityId, scope, callback);
94 } else { 94 } else {
95 - ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), callback); 95 + ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), callback);
96 } 96 }
97 } 97 }
98 } else if (method.equals("values")) { 98 } else if (method.equals("values")) {
@@ -132,9 +132,9 @@ public class TelemetryRestMsgHandler extends DefaultRestMsgHandler { @@ -132,9 +132,9 @@ public class TelemetryRestMsgHandler extends DefaultRestMsgHandler {
132 } else { 132 } else {
133 if (!StringUtils.isEmpty(keys)) { 133 if (!StringUtils.isEmpty(keys)) {
134 List<String> keyList = Arrays.asList(keys.split(",")); 134 List<String> keyList = Arrays.asList(keys.split(","));
135 - ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), keyList, callback); 135 + ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), keyList, callback);
136 } else { 136 } else {
137 - ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), callback); 137 + ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), callback);
138 } 138 }
139 } 139 }
140 } 140 }
@@ -29,10 +29,7 @@ import org.thingsboard.server.extensions.core.plugin.telemetry.SubscriptionManag @@ -29,10 +29,7 @@ import org.thingsboard.server.extensions.core.plugin.telemetry.SubscriptionManag
29 import org.thingsboard.server.extensions.core.plugin.telemetry.gen.TelemetryPluginProtos.*; 29 import org.thingsboard.server.extensions.core.plugin.telemetry.gen.TelemetryPluginProtos.*;
30 import org.thingsboard.server.extensions.core.plugin.telemetry.sub.*; 30 import org.thingsboard.server.extensions.core.plugin.telemetry.sub.*;
31 31
32 -import java.util.ArrayList;  
33 -import java.util.List;  
34 -import java.util.Map;  
35 -import java.util.TreeMap; 32 +import java.util.*;
36 import java.util.stream.Collectors; 33 import java.util.stream.Collectors;
37 34
38 /** 35 /**
@@ -244,16 +241,28 @@ public class TelemetryRpcMsgHandler implements RpcMsgHandler { @@ -244,16 +241,28 @@ public class TelemetryRpcMsgHandler implements RpcMsgHandler {
244 dataBuilder.setValueType(attr.getDataType().ordinal()); 241 dataBuilder.setValueType(attr.getDataType().ordinal());
245 switch (attr.getDataType()) { 242 switch (attr.getDataType()) {
246 case BOOLEAN: 243 case BOOLEAN:
247 - dataBuilder.setBoolValue(attr.getBooleanValue().get()); 244 + Optional<Boolean> booleanValue = attr.getBooleanValue();
  245 + if (booleanValue.isPresent()) {
  246 + dataBuilder.setBoolValue(booleanValue.get());
  247 + }
248 break; 248 break;
249 case LONG: 249 case LONG:
250 - dataBuilder.setLongValue(attr.getLongValue().get()); 250 + Optional<Long> longValue = attr.getLongValue();
  251 + if (longValue.isPresent()) {
  252 + dataBuilder.setLongValue(longValue.get());
  253 + }
251 break; 254 break;
252 case DOUBLE: 255 case DOUBLE:
253 - dataBuilder.setDoubleValue(attr.getDoubleValue().get()); 256 + Optional<Double> doubleValue = attr.getDoubleValue();
  257 + if (doubleValue.isPresent()) {
  258 + dataBuilder.setDoubleValue(doubleValue.get());
  259 + }
254 break; 260 break;
255 case STRING: 261 case STRING:
256 - dataBuilder.setStrValue(attr.getStrValue().get()); 262 + Optional<String> stringValue = attr.getStrValue();
  263 + if (stringValue.isPresent()) {
  264 + dataBuilder.setStrValue(stringValue.get());
  265 + }
257 break; 266 break;
258 } 267 }
259 return dataBuilder; 268 return dataBuilder;
@@ -139,7 +139,7 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { @@ -139,7 +139,7 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler {
139 }; 139 };
140 140
141 if (StringUtils.isEmpty(cmd.getScope())) { 141 if (StringUtils.isEmpty(cmd.getScope())) {
142 - ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), keys, callback); 142 + ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), keys, callback);
143 } else { 143 } else {
144 ctx.loadAttributes(entityId, cmd.getScope(), keys, callback); 144 ctx.loadAttributes(entityId, cmd.getScope(), keys, callback);
145 } 145 }
@@ -167,7 +167,7 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { @@ -167,7 +167,7 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler {
167 }; 167 };
168 168
169 if (StringUtils.isEmpty(cmd.getScope())) { 169 if (StringUtils.isEmpty(cmd.getScope())) {
170 - ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), callback); 170 + ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), callback);
171 } else { 171 } else {
172 ctx.loadAttributes(entityId, cmd.getScope(), callback); 172 ctx.loadAttributes(entityId, cmd.getScope(), callback);
173 } 173 }
@@ -84,9 +84,10 @@ public class MqttPlugin extends AbstractPlugin<MqttPluginConfiguration> { @@ -84,9 +84,10 @@ public class MqttPlugin extends AbstractPlugin<MqttPluginConfiguration> {
84 log.warn("Failed to connect to requested mqtt host [{}]!", mqttClient.getServerURI(), e); 84 log.warn("Failed to connect to requested mqtt host [{}]!", mqttClient.getServerURI(), e);
85 if (!mqttClient.isConnected()) { 85 if (!mqttClient.isConnected()) {
86 try { 86 try {
87 - Thread.sleep(retryInterval); 87 + connectLock.wait(retryInterval);
88 } catch (InterruptedException e1) { 88 } catch (InterruptedException e1) {
89 log.trace("Failed to wait for retry interval!", e); 89 log.trace("Failed to wait for retry interval!", e);
  90 + Thread.currentThread().interrupt();
90 } 91 }
91 } 92 }
92 } 93 }
@@ -21,18 +21,18 @@ package org.thingsboard.client.tools; @@ -21,18 +21,18 @@ package org.thingsboard.client.tools;
21 */ 21 */
22 22
23 import com.google.common.io.Resources; 23 import com.google.common.io.Resources;
24 -import org.eclipse.paho.client.mqttv3.*; 24 +import lombok.extern.slf4j.Slf4j;
  25 +import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
  26 +import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
  27 +import org.eclipse.paho.client.mqttv3.MqttMessage;
25 28
26 import javax.net.ssl.*; 29 import javax.net.ssl.*;
27 import java.io.File; 30 import java.io.File;
28 import java.io.FileInputStream; 31 import java.io.FileInputStream;
29 -import java.io.FileNotFoundException;  
30 -import java.io.IOException;  
31 -import java.net.URISyntaxException;  
32 import java.net.URL; 32 import java.net.URL;
33 -import java.security.*;  
34 -import java.security.cert.CertificateException; 33 +import java.security.KeyStore;
35 34
  35 +@Slf4j
36 public class MqttSslClient { 36 public class MqttSslClient {
37 37
38 38
@@ -43,13 +43,10 @@ public class MqttSslClient { @@ -43,13 +43,10 @@ public class MqttSslClient {
43 private static final String keyStoreFile = "mqttclient.jks"; 43 private static final String keyStoreFile = "mqttclient.jks";
44 private static final String JKS="JKS"; 44 private static final String JKS="JKS";
45 private static final String TLS="TLS"; 45 private static final String TLS="TLS";
46 - private static final String CLIENT_KEYSTORE_PASSWORD = "client_ks_password";  
47 - private static final String CLIENT_KEY_PASSWORD = "client_key_password";  
48 46
49 public static void main(String[] args) { 47 public static void main(String[] args) {
50 48
51 try { 49 try {
52 -  
53 URL ksUrl = Resources.getResource(keyStoreFile); 50 URL ksUrl = Resources.getResource(keyStoreFile);
54 File ksFile = new File(ksUrl.toURI()); 51 File ksFile = new File(ksUrl.toURI());
55 URL tsUrl = Resources.getResource(keyStoreFile); 52 URL tsUrl = Resources.getResource(keyStoreFile);
@@ -58,13 +55,15 @@ public class MqttSslClient { @@ -58,13 +55,15 @@ public class MqttSslClient {
58 TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 55 TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
59 56
60 KeyStore trustStore = KeyStore.getInstance(JKS); 57 KeyStore trustStore = KeyStore.getInstance(JKS);
61 - trustStore.load(new FileInputStream(tsFile), CLIENT_KEYSTORE_PASSWORD.toCharArray()); 58 + char[] ksPwd = new char[]{0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x5F, 0x6B, 0x73, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64};
  59 + trustStore.load(new FileInputStream(tsFile), ksPwd);
62 tmf.init(trustStore); 60 tmf.init(trustStore);
63 KeyStore ks = KeyStore.getInstance(JKS); 61 KeyStore ks = KeyStore.getInstance(JKS);
64 62
65 - ks.load(new FileInputStream(ksFile), CLIENT_KEYSTORE_PASSWORD.toCharArray()); 63 + ks.load(new FileInputStream(ksFile), ksPwd);
66 KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 64 KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
67 - kmf.init(ks, CLIENT_KEY_PASSWORD.toCharArray()); 65 + char[] clientPwd = new char[]{0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x5F, 0x6B, 0x65, 0x79, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64};
  66 + kmf.init(ks, clientPwd);
68 67
69 KeyManager[] km = kmf.getKeyManagers(); 68 KeyManager[] km = kmf.getKeyManagers();
70 TrustManager[] tm = tmf.getTrustManagers(); 69 TrustManager[] tm = tmf.getTrustManagers();
@@ -83,7 +82,7 @@ public class MqttSslClient { @@ -83,7 +82,7 @@ public class MqttSslClient {
83 System.out.println("Disconnected"); 82 System.out.println("Disconnected");
84 System.exit(0); 83 System.exit(0);
85 } catch (Exception e) { 84 } catch (Exception e) {
86 - e.printStackTrace(); 85 + log.error("Unexpected exception occurred in MqttSslClient", e);
87 } 86 }
88 } 87 }
89 } 88 }
@@ -167,7 +167,7 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { @@ -167,7 +167,7 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor {
167 167
168 private FromDeviceMsg convertToGetAttributesRequest(SessionContext ctx, Request inbound) throws AdaptorException { 168 private FromDeviceMsg convertToGetAttributesRequest(SessionContext ctx, Request inbound) throws AdaptorException {
169 List<String> queryElements = inbound.getOptions().getUriQuery(); 169 List<String> queryElements = inbound.getOptions().getUriQuery();
170 - if (queryElements != null || queryElements.size() > 0) { 170 + if (queryElements != null && queryElements.size() > 0) {
171 Set<String> clientKeys = toKeys(ctx, queryElements, "clientKeys"); 171 Set<String> clientKeys = toKeys(ctx, queryElements, "clientKeys");
172 Set<String> sharedKeys = toKeys(ctx, queryElements, "sharedKeys"); 172 Set<String> sharedKeys = toKeys(ctx, queryElements, "sharedKeys");
173 return new BasicGetAttributesRequest(0, clientKeys, sharedKeys); 173 return new BasicGetAttributesRequest(0, clientKeys, sharedKeys);
@@ -184,7 +184,7 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { @@ -184,7 +184,7 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor {
184 keys = queryItem[1]; 184 keys = queryItem[1];
185 } 185 }
186 } 186 }
187 - if (!StringUtils.isEmpty(keys)) { 187 + if (keys != null && !StringUtils.isEmpty(keys)) {
188 return new HashSet<>(Arrays.asList(keys.split(","))); 188 return new HashSet<>(Arrays.asList(keys.split(",")));
189 } else { 189 } else {
190 return null; 190 return null;
@@ -202,14 +202,14 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { @@ -202,14 +202,14 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor {
202 202
203 private Response convertStatusCodeResponse(StatusCodeResponse msg) { 203 private Response convertStatusCodeResponse(StatusCodeResponse msg) {
204 if (msg.isSuccess()) { 204 if (msg.isSuccess()) {
205 - Integer code = msg.getData().get();  
206 - if (code == 200) { 205 + Optional<Integer> code = msg.getData();
  206 + if (code.isPresent() && code.get() == 200) {
207 return new Response(ResponseCode.VALID); 207 return new Response(ResponseCode.VALID);
208 } else { 208 } else {
209 return new Response(ResponseCode.CREATED); 209 return new Response(ResponseCode.CREATED);
210 } 210 }
211 } else { 211 } else {
212 - return convertError(msg.getError().get()); 212 + return convertError(msg.getError());
213 } 213 }
214 } 214 }
215 215
@@ -229,30 +229,34 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { @@ -229,30 +229,34 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor {
229 response.setPayload(result.toString()); 229 response.setPayload(result.toString());
230 return response; 230 return response;
231 } else { 231 } else {
232 - return convertError(new RuntimeException("Server RPC response is empty!")); 232 + return convertError(Optional.of(new RuntimeException("Server RPC response is empty!")));
233 } 233 }
234 } 234 }
235 235
236 private Response convertGetAttributesResponse(GetAttributesResponse msg) { 236 private Response convertGetAttributesResponse(GetAttributesResponse msg) {
237 if (msg.isSuccess()) { 237 if (msg.isSuccess()) {
238 - AttributesKVMsg payload = msg.getData().get();  
239 - if (payload.getClientAttributes().isEmpty() && payload.getSharedAttributes().isEmpty()) { 238 + Optional<AttributesKVMsg> payload = msg.getData();
  239 + if (!payload.isPresent() || (payload.get().getClientAttributes().isEmpty() && payload.get().getSharedAttributes().isEmpty())) {
240 return new Response(ResponseCode.NOT_FOUND); 240 return new Response(ResponseCode.NOT_FOUND);
241 } else { 241 } else {
242 Response response = new Response(ResponseCode.CONTENT); 242 Response response = new Response(ResponseCode.CONTENT);
243 - JsonObject result = JsonConverter.toJson(payload, false); 243 + JsonObject result = JsonConverter.toJson(payload.get(), false);
244 response.setPayload(result.toString()); 244 response.setPayload(result.toString());
245 return response; 245 return response;
246 } 246 }
247 } else { 247 } else {
248 - return convertError(msg.getError().get()); 248 + return convertError(msg.getError());
249 } 249 }
250 } 250 }
251 251
252 - private Response convertError(Exception exception) {  
253 - log.warn("Converting exception: {}", exception.getMessage(), exception);  
254 - if (exception instanceof ProcessingTimeoutException) {  
255 - return new Response(ResponseCode.SERVICE_UNAVAILABLE); 252 + private Response convertError(Optional<Exception> exception) {
  253 + if (exception.isPresent()) {
  254 + log.warn("Converting exception: {}", exception.get().getMessage(), exception.get());
  255 + if (exception.get() instanceof ProcessingTimeoutException) {
  256 + return new Response(ResponseCode.SERVICE_UNAVAILABLE);
  257 + } else {
  258 + return new Response(ResponseCode.INTERNAL_SERVER_ERROR);
  259 + }
256 } else { 260 } else {
257 return new Response(ResponseCode.INTERNAL_SERVER_ERROR); 261 return new Response(ResponseCode.INTERNAL_SERVER_ERROR);
258 } 262 }
@@ -80,7 +80,7 @@ public class DeviceEmulator { @@ -80,7 +80,7 @@ public class DeviceEmulator {
80 Thread.sleep(1000); 80 Thread.sleep(1000);
81 } 81 }
82 } catch (Exception e) { 82 } catch (Exception e) {
83 - e.printStackTrace(); 83 + log.error("Error occurred while sending COAP requests", e);
84 } 84 }
85 } 85 }
86 86
@@ -118,7 +118,7 @@ public class DeviceEmulator { @@ -118,7 +118,7 @@ public class DeviceEmulator {
118 }, mapper.writeValueAsString(response), MediaTypeRegistry.APPLICATION_JSON); 118 }, mapper.writeValueAsString(response), MediaTypeRegistry.APPLICATION_JSON);
119 119
120 } catch (IOException e) { 120 } catch (IOException e) {
121 - e.printStackTrace(); 121 + log.error("Error occurred while processing COAP response", e);
122 } 122 }
123 } 123 }
124 124
@@ -29,6 +29,7 @@ import org.thingsboard.server.common.transport.adaptor.JsonConverter; @@ -29,6 +29,7 @@ import org.thingsboard.server.common.transport.adaptor.JsonConverter;
29 import org.thingsboard.server.common.transport.auth.DeviceAuthService; 29 import org.thingsboard.server.common.transport.auth.DeviceAuthService;
30 import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext; 30 import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext;
31 31
  32 +import java.util.Optional;
32 import java.util.function.Consumer; 33 import java.util.function.Consumer;
33 34
34 /** 35 /**
@@ -94,10 +95,14 @@ public class HttpSessionCtx extends DeviceAwareSessionContext { @@ -94,10 +95,14 @@ public class HttpSessionCtx extends DeviceAwareSessionContext {
94 } 95 }
95 96
96 private <T> void reply(ResponseMsg<? extends T> msg, Consumer<T> f) { 97 private <T> void reply(ResponseMsg<? extends T> msg, Consumer<T> f) {
97 - if (!msg.getError().isPresent()) {  
98 - f.accept(msg.getData().get()); 98 + Optional<Exception> msgError = msg.getError();
  99 + if (!msgError.isPresent()) {
  100 + Optional<? extends T> msgData = msg.getData();
  101 + if (msgData.isPresent()) {
  102 + f.accept(msgData.get());
  103 + }
99 } else { 104 } else {
100 - Exception e = msg.getError().get(); 105 + Exception e = msgError.get();
101 responseWriter.setResult(new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR)); 106 responseWriter.setResult(new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR));
102 } 107 }
103 } 108 }
@@ -32,6 +32,7 @@ import javax.net.ssl.*; @@ -32,6 +32,7 @@ import javax.net.ssl.*;
32 import java.io.File; 32 import java.io.File;
33 import java.io.FileInputStream; 33 import java.io.FileInputStream;
34 import java.io.IOException; 34 import java.io.IOException;
  35 +import java.io.InputStream;
35 import java.net.URL; 36 import java.net.URL;
36 import java.security.KeyStore; 37 import java.security.KeyStore;
37 import java.security.cert.CertificateException; 38 import java.security.cert.CertificateException;
@@ -69,12 +70,15 @@ public class MqttSslHandlerProvider { @@ -69,12 +70,15 @@ public class MqttSslHandlerProvider {
69 70
70 TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 71 TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
71 KeyStore trustStore = KeyStore.getInstance(keyStoreType); 72 KeyStore trustStore = KeyStore.getInstance(keyStoreType);
72 - trustStore.load(new FileInputStream(tsFile), keyStorePassword.toCharArray()); 73 + try (InputStream tsFileInputStream = new FileInputStream(tsFile)) {
  74 + trustStore.load(tsFileInputStream, keyStorePassword.toCharArray());
  75 + }
73 tmFactory.init(trustStore); 76 tmFactory.init(trustStore);
74 77
75 KeyStore ks = KeyStore.getInstance(keyStoreType); 78 KeyStore ks = KeyStore.getInstance(keyStoreType);
76 -  
77 - ks.load(new FileInputStream(ksFile), keyStorePassword.toCharArray()); 79 + try (InputStream ksFileInputStream = new FileInputStream(ksFile)) {
  80 + ks.load(ksFileInputStream, keyStorePassword.toCharArray());
  81 + }
78 KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); 82 KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
79 kmf.init(ks, keyPassword.toCharArray()); 83 kmf.init(ks, keyPassword.toCharArray());
80 84
@@ -98,6 +98,7 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor { @@ -98,6 +98,7 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor {
98 case STATUS_CODE_RESPONSE: 98 case STATUS_CODE_RESPONSE:
99 case GET_ATTRIBUTES_RESPONSE: 99 case GET_ATTRIBUTES_RESPONSE:
100 ResponseMsg<?> responseMsg = (ResponseMsg) msg; 100 ResponseMsg<?> responseMsg = (ResponseMsg) msg;
  101 + Optional<Exception> responseError = responseMsg.getError();
101 if (responseMsg.isSuccess()) { 102 if (responseMsg.isSuccess()) {
102 MsgType requestMsgType = responseMsg.getRequestMsgType(); 103 MsgType requestMsgType = responseMsg.getRequestMsgType();
103 Integer requestId = responseMsg.getRequestId(); 104 Integer requestId = responseMsg.getRequestId();
@@ -106,18 +107,21 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor { @@ -106,18 +107,21 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor {
106 result = MqttTransportHandler.createMqttPubAckMsg(requestId); 107 result = MqttTransportHandler.createMqttPubAckMsg(requestId);
107 } else if (requestMsgType == MsgType.GET_ATTRIBUTES_REQUEST) { 108 } else if (requestMsgType == MsgType.GET_ATTRIBUTES_REQUEST) {
108 GetAttributesResponse response = (GetAttributesResponse) msg; 109 GetAttributesResponse response = (GetAttributesResponse) msg;
109 - if (response.isSuccess()) { 110 + Optional<AttributesKVMsg> responseData = response.getData();
  111 + if (response.isSuccess() && responseData.isPresent()) {
110 result = createMqttPublishMsg(ctx, 112 result = createMqttPublishMsg(ctx,
111 MqttTopics.DEVICE_ATTRIBUTES_RESPONSE_TOPIC_PREFIX + requestId, 113 MqttTopics.DEVICE_ATTRIBUTES_RESPONSE_TOPIC_PREFIX + requestId,
112 - response.getData().get(), true); 114 + responseData.get(), true);
113 } else { 115 } else {
114 - throw new AdaptorException(response.getError().get()); 116 + if (responseError.isPresent()) {
  117 + throw new AdaptorException(responseError.get());
  118 + }
115 } 119 }
116 } 120 }
117 } 121 }
118 } else { 122 } else {
119 - if (responseMsg.getError().isPresent()) {  
120 - throw new AdaptorException(responseMsg.getError().get()); 123 + if (responseError.isPresent()) {
  124 + throw new AdaptorException(responseError.get());
121 } 125 }
122 } 126 }
123 break; 127 break;
@@ -128,8 +128,9 @@ public class GatewayDeviceSessionCtx extends DeviceAwareSessionContext { @@ -128,8 +128,9 @@ public class GatewayDeviceSessionCtx extends DeviceAwareSessionContext {
128 JsonObject result = new JsonObject(); 128 JsonObject result = new JsonObject();
129 result.addProperty("id", response.getRequestId()); 129 result.addProperty("id", response.getRequestId());
130 result.addProperty("device", device.getName()); 130 result.addProperty("device", device.getName());
131 - if (response.getData().isPresent()) {  
132 - AttributesKVMsg msg = response.getData().get(); 131 + Optional<AttributesKVMsg> responseData = response.getData();
  132 + if (responseData.isPresent()) {
  133 + AttributesKVMsg msg = responseData.get();
133 if (msg.getClientAttributes() != null) { 134 if (msg.getClientAttributes() != null) {
134 msg.getClientAttributes().forEach(v -> addValueToJson(result, "value", v)); 135 msg.getClientAttributes().forEach(v -> addValueToJson(result, "value", v));
135 } 136 }
@@ -143,16 +144,28 @@ public class GatewayDeviceSessionCtx extends DeviceAwareSessionContext { @@ -143,16 +144,28 @@ public class GatewayDeviceSessionCtx extends DeviceAwareSessionContext {
143 private void addValueToJson(JsonObject json, String name, KvEntry entry) { 144 private void addValueToJson(JsonObject json, String name, KvEntry entry) {
144 switch (entry.getDataType()) { 145 switch (entry.getDataType()) {
145 case BOOLEAN: 146 case BOOLEAN:
146 - json.addProperty(name, entry.getBooleanValue().get()); 147 + Optional<Boolean> booleanValue = entry.getBooleanValue();
  148 + if (booleanValue.isPresent()) {
  149 + json.addProperty(name, booleanValue.get());
  150 + }
147 break; 151 break;
148 case STRING: 152 case STRING:
149 - json.addProperty(name, entry.getStrValue().get()); 153 + Optional<String> stringValue = entry.getStrValue();
  154 + if (stringValue.isPresent()) {
  155 + json.addProperty(name, stringValue.get());
  156 + }
150 break; 157 break;
151 case DOUBLE: 158 case DOUBLE:
152 - json.addProperty(name, entry.getDoubleValue().get()); 159 + Optional<Double> doubleValue = entry.getDoubleValue();
  160 + if (doubleValue.isPresent()) {
  161 + json.addProperty(name, doubleValue.get());
  162 + }
153 break; 163 break;
154 case LONG: 164 case LONG:
155 - json.addProperty(name, entry.getLongValue().get()); 165 + Optional<Long> longValue = entry.getLongValue();
  166 + if (longValue.isPresent()) {
  167 + json.addProperty(name, longValue.get());
  168 + }
156 break; 169 break;
157 } 170 }
158 } 171 }