diff --git a/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java b/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java index 2b28d3990d..d2d4dce90d 100644 --- a/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/app/AppActor.java @@ -32,6 +32,8 @@ import org.thingsboard.server.actors.shared.rule.SystemRuleManager; import org.thingsboard.server.actors.tenant.RuleChainDeviceMsg; import org.thingsboard.server.actors.tenant.TenantActor; import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.id.PluginId; +import org.thingsboard.server.common.data.id.RuleId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageDataIterable; import org.thingsboard.server.common.msg.cluster.ClusterEventMsg; @@ -149,14 +151,16 @@ public class AppActor extends ContextAwareActor { private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { ActorRef target = null; if (SYSTEM_TENANT.equals(msg.getTenantId())) { - if (msg.getPluginId().isPresent()) { - target = pluginManager.getOrCreatePluginActor(this.context(), msg.getPluginId().get()); - } else if (msg.getRuleId().isPresent()) { - Optional ref = ruleManager.update(this.context(), msg.getRuleId().get(), msg.getEvent()); + Optional pluginId = msg.getPluginId(); + Optional ruleId = msg.getRuleId(); + if (pluginId.isPresent()) { + target = pluginManager.getOrCreatePluginActor(this.context(), pluginId.get()); + } else if (ruleId.isPresent()) { + Optional ref = ruleManager.update(this.context(), ruleId.get(), msg.getEvent()); if (ref.isPresent()) { target = ref.get(); } else { - logger.debug("Failed to find actor for rule: [{}]", msg.getRuleId()); + logger.debug("Failed to find actor for rule: [{}]", ruleId); return; } } diff --git a/application/src/main/java/org/thingsboard/server/actors/plugin/PluginProcessingContext.java b/application/src/main/java/org/thingsboard/server/actors/plugin/PluginProcessingContext.java index 8f65fc687d..bc5893c4a9 100644 --- a/application/src/main/java/org/thingsboard/server/actors/plugin/PluginProcessingContext.java +++ b/application/src/main/java/org/thingsboard/server/actors/plugin/PluginProcessingContext.java @@ -272,130 +272,150 @@ public final class PluginProcessingContext implements PluginContext { private void validate(EntityId entityId, ValidationCallback callback) { if (securityCtx.isPresent()) { final PluginApiCallSecurityContext ctx = securityCtx.get(); - if (ctx.isTenantAdmin() || ctx.isCustomerUser() || ctx.isSystemAdmin()) { - switch (entityId.getEntityType()) { - case DEVICE: - if (ctx.isSystemAdmin()) { - callback.onSuccess(this, Boolean.FALSE); - } else { - ListenableFuture deviceFuture = pluginCtx.deviceService.findDeviceByIdAsync(new DeviceId(entityId.getId())); - Futures.addCallback(deviceFuture, getCallback(callback, device -> { - if (device == null) { - return Boolean.FALSE; - } else { - if (!device.getTenantId().equals(ctx.getTenantId())) { - return Boolean.FALSE; - } else if (ctx.isCustomerUser() && !device.getCustomerId().equals(ctx.getCustomerId())) { - return Boolean.FALSE; - } else { - return Boolean.TRUE; - } - } - })); - } - return; - case ASSET: - if (ctx.isSystemAdmin()) { - callback.onSuccess(this, Boolean.FALSE); - } else { - ListenableFuture assetFuture = pluginCtx.assetService.findAssetByIdAsync(new AssetId(entityId.getId())); - Futures.addCallback(assetFuture, getCallback(callback, asset -> { - if (asset == null) { - return Boolean.FALSE; - } else { - if (!asset.getTenantId().equals(ctx.getTenantId())) { - return Boolean.FALSE; - } else if (ctx.isCustomerUser() && !asset.getCustomerId().equals(ctx.getCustomerId())) { - return Boolean.FALSE; - } else { - return Boolean.TRUE; - } - } - })); - } - return; - case RULE: - if (ctx.isCustomerUser()) { - callback.onSuccess(this, Boolean.FALSE); - } else { - ListenableFuture ruleFuture = pluginCtx.ruleService.findRuleByIdAsync(new RuleId(entityId.getId())); - Futures.addCallback(ruleFuture, getCallback(callback, rule -> { - if (rule == null) { - return Boolean.FALSE; - } else { - if (ctx.isTenantAdmin() && !rule.getTenantId().equals(ctx.getTenantId())) { - return Boolean.FALSE; - } else if (ctx.isSystemAdmin() && !rule.getTenantId().isNullUid()) { - return Boolean.FALSE; - } else { - return Boolean.TRUE; - } - } - })); - } - return; - case PLUGIN: - if (ctx.isCustomerUser()) { - callback.onSuccess(this, Boolean.FALSE); - } else { - ListenableFuture pluginFuture = pluginCtx.pluginService.findPluginByIdAsync(new PluginId(entityId.getId())); - Futures.addCallback(pluginFuture, getCallback(callback, plugin -> { - if (plugin == null) { - return Boolean.FALSE; - } else { - if (ctx.isTenantAdmin() && !plugin.getTenantId().equals(ctx.getTenantId())) { - return Boolean.FALSE; - } else if (ctx.isSystemAdmin() && !plugin.getTenantId().isNullUid()) { - return Boolean.FALSE; - } else { - return Boolean.TRUE; - } - } - })); - } - return; - case CUSTOMER: - if (ctx.isSystemAdmin()) { - callback.onSuccess(this, Boolean.FALSE); - } else { - ListenableFuture customerFuture = pluginCtx.customerService.findCustomerByIdAsync(new CustomerId(entityId.getId())); - Futures.addCallback(customerFuture, getCallback(callback, customer -> { - if (customer == null) { - return Boolean.FALSE; - } else { - if (!customer.getTenantId().equals(ctx.getTenantId())) { - return Boolean.FALSE; - } else if (ctx.isCustomerUser() && !customer.getId().equals(ctx.getCustomerId())) { - return Boolean.FALSE; - } else { - return Boolean.TRUE; - } - } - })); - } - return; - case TENANT: - if (ctx.isCustomerUser()) { - callback.onSuccess(this, Boolean.FALSE); - } else if (ctx.isSystemAdmin()) { - callback.onSuccess(this, Boolean.TRUE); - } else { - ListenableFuture tenantFuture = pluginCtx.tenantService.findTenantByIdAsync(new TenantId(entityId.getId())); - Futures.addCallback(tenantFuture, getCallback(callback, tenant -> tenant != null && tenant.getId().equals(ctx.getTenantId()))); - } - return; - default: - //TODO: add support of other entities - throw new IllegalStateException("Not Implemented!"); - } - } else { - callback.onSuccess(this, Boolean.FALSE); + switch (entityId.getEntityType()) { + case DEVICE: + validateDevice(ctx, entityId, callback); + return; + case ASSET: + validateAsset(ctx, entityId, callback); + return; + case RULE: + validateRule(ctx, entityId, callback); + return; + case PLUGIN: + validatePlugin(ctx, entityId, callback); + return; + case CUSTOMER: + validateCustomer(ctx, entityId, callback); + return; + case TENANT: + validateTenant(ctx, entityId, callback); + return; + default: + //TODO: add support of other entities + throw new IllegalStateException("Not Implemented!"); } } else { callback.onSuccess(this, Boolean.TRUE); } } + private void validateDevice(final PluginApiCallSecurityContext ctx, EntityId entityId, ValidationCallback callback) { + if (ctx.isSystemAdmin()) { + callback.onSuccess(this, Boolean.FALSE); + } else { + ListenableFuture deviceFuture = pluginCtx.deviceService.findDeviceByIdAsync(new DeviceId(entityId.getId())); + Futures.addCallback(deviceFuture, getCallback(callback, device -> { + if (device == null) { + return Boolean.FALSE; + } else { + if (!device.getTenantId().equals(ctx.getTenantId())) { + return Boolean.FALSE; + } else if (ctx.isCustomerUser() && !device.getCustomerId().equals(ctx.getCustomerId())) { + return Boolean.FALSE; + } else { + return Boolean.TRUE; + } + } + })); + } + } + + private void validateAsset(final PluginApiCallSecurityContext ctx, EntityId entityId, ValidationCallback callback) { + if (ctx.isSystemAdmin()) { + callback.onSuccess(this, Boolean.FALSE); + } else { + ListenableFuture assetFuture = pluginCtx.assetService.findAssetByIdAsync(new AssetId(entityId.getId())); + Futures.addCallback(assetFuture, getCallback(callback, asset -> { + if (asset == null) { + return Boolean.FALSE; + } else { + if (!asset.getTenantId().equals(ctx.getTenantId())) { + return Boolean.FALSE; + } else if (ctx.isCustomerUser() && !asset.getCustomerId().equals(ctx.getCustomerId())) { + return Boolean.FALSE; + } else { + return Boolean.TRUE; + } + } + })); + } + } + + private void validateRule(final PluginApiCallSecurityContext ctx, EntityId entityId, ValidationCallback callback) { + if (ctx.isCustomerUser()) { + callback.onSuccess(this, Boolean.FALSE); + } else { + ListenableFuture ruleFuture = pluginCtx.ruleService.findRuleByIdAsync(new RuleId(entityId.getId())); + Futures.addCallback(ruleFuture, getCallback(callback, rule -> { + if (rule == null) { + return Boolean.FALSE; + } else { + if (ctx.isTenantAdmin() && !rule.getTenantId().equals(ctx.getTenantId())) { + return Boolean.FALSE; + } else if (ctx.isSystemAdmin() && !rule.getTenantId().isNullUid()) { + return Boolean.FALSE; + } else { + return Boolean.TRUE; + } + } + })); + } + } + + private void validatePlugin(final PluginApiCallSecurityContext ctx, EntityId entityId, ValidationCallback callback) { + if (ctx.isCustomerUser()) { + callback.onSuccess(this, Boolean.FALSE); + } else { + ListenableFuture pluginFuture = pluginCtx.pluginService.findPluginByIdAsync(new PluginId(entityId.getId())); + Futures.addCallback(pluginFuture, getCallback(callback, plugin -> { + if (plugin == null) { + return Boolean.FALSE; + } else { + if (ctx.isTenantAdmin() && !plugin.getTenantId().equals(ctx.getTenantId())) { + return Boolean.FALSE; + } else if (ctx.isSystemAdmin() && !plugin.getTenantId().isNullUid()) { + return Boolean.FALSE; + } else { + return Boolean.TRUE; + } + } + })); + } + } + + private void validateCustomer(final PluginApiCallSecurityContext ctx, EntityId entityId, ValidationCallback callback) { + if (ctx.isSystemAdmin()) { + callback.onSuccess(this, Boolean.FALSE); + } else { + ListenableFuture customerFuture = pluginCtx.customerService.findCustomerByIdAsync(new CustomerId(entityId.getId())); + Futures.addCallback(customerFuture, getCallback(callback, customer -> { + if (customer == null) { + return Boolean.FALSE; + } else { + if (!customer.getTenantId().equals(ctx.getTenantId())) { + return Boolean.FALSE; + } else if (ctx.isCustomerUser() && !customer.getId().equals(ctx.getCustomerId())) { + return Boolean.FALSE; + } else { + return Boolean.TRUE; + } + } + })); + } + } + + private void validateTenant(final PluginApiCallSecurityContext ctx, EntityId entityId, ValidationCallback callback) { + if (ctx.isCustomerUser()) { + callback.onSuccess(this, Boolean.FALSE); + } else if (ctx.isSystemAdmin()) { + callback.onSuccess(this, Boolean.TRUE); + } else { + ListenableFuture tenantFuture = pluginCtx.tenantService.findTenantByIdAsync(new TenantId(entityId.getId())); + Futures.addCallback(tenantFuture, getCallback(callback, tenant -> tenant != null && tenant.getId().equals(ctx.getTenantId()))); + } + } + @Override public ListenableFuture> findByFromAndType(EntityId from, String relationType) { return this.pluginCtx.relationService.findByFromAndType(from, relationType, RelationTypeGroup.COMMON); diff --git a/application/src/main/java/org/thingsboard/server/actors/plugin/RuleToPluginMsgWrapper.java b/application/src/main/java/org/thingsboard/server/actors/plugin/RuleToPluginMsgWrapper.java index 1ddf6068d6..b4463d4d31 100644 --- a/application/src/main/java/org/thingsboard/server/actors/plugin/RuleToPluginMsgWrapper.java +++ b/application/src/main/java/org/thingsboard/server/actors/plugin/RuleToPluginMsgWrapper.java @@ -59,7 +59,7 @@ public class RuleToPluginMsgWrapper implements ToPluginActorMsg, RuleAwareMsg { } - public RuleToPluginMsg getMsg() { + public RuleToPluginMsg getMsg() { return msg; } diff --git a/application/src/main/java/org/thingsboard/server/actors/rpc/BasicRpcSessionListener.java b/application/src/main/java/org/thingsboard/server/actors/rpc/BasicRpcSessionListener.java index 5d0c009b19..6250897b0c 100644 --- a/application/src/main/java/org/thingsboard/server/actors/rpc/BasicRpcSessionListener.java +++ b/application/src/main/java/org/thingsboard/server/actors/rpc/BasicRpcSessionListener.java @@ -45,6 +45,7 @@ import java.util.UUID; @Slf4j public class BasicRpcSessionListener implements GrpcSessionListener { + public static final String SESSION_RECEIVED_SESSION_ACTOR_MSG = "{} session [{}] received session actor msg {}"; private final ActorSystemContext context; private final ActorService service; private final ActorRef manager; @@ -93,25 +94,25 @@ public class BasicRpcSessionListener implements GrpcSessionListener { @Override public void onToDeviceSessionActorRpcMsg(GrpcSession session, ClusterAPIProtos.ToDeviceSessionActorRpcMessage msg) { - log.trace("{} session [{}] received session actor msg {}", getType(session), session.getRemoteServer(), msg); + log.trace(SESSION_RECEIVED_SESSION_ACTOR_MSG, getType(session), session.getRemoteServer(), msg); service.onMsg((ToDeviceSessionActorMsg) deserialize(msg.getData().toByteArray())); } @Override public void onToDeviceRpcRequestRpcMsg(GrpcSession session, ClusterAPIProtos.ToDeviceRpcRequestRpcMessage msg) { - log.trace("{} session [{}] received session actor msg {}", getType(session), session.getRemoteServer(), msg); + log.trace(SESSION_RECEIVED_SESSION_ACTOR_MSG, getType(session), session.getRemoteServer(), msg); service.onMsg(deserialize(session.getRemoteServer(), msg)); } @Override public void onFromDeviceRpcResponseRpcMsg(GrpcSession session, ClusterAPIProtos.ToPluginRpcResponseRpcMessage msg) { - log.trace("{} session [{}] received session actor msg {}", getType(session), session.getRemoteServer(), msg); + log.trace(SESSION_RECEIVED_SESSION_ACTOR_MSG, getType(session), session.getRemoteServer(), msg); service.onMsg(deserialize(session.getRemoteServer(), msg)); } @Override public void onToAllNodesRpcMessage(GrpcSession session, ClusterAPIProtos.ToAllNodesRpcMessage msg) { - log.trace("{} session [{}] received session actor msg {}", getType(session), session.getRemoteServer(), msg); + log.trace(SESSION_RECEIVED_SESSION_ACTOR_MSG, getType(session), session.getRemoteServer(), msg); service.onMsg((ToAllNodesMsg) deserialize(msg.getData().toByteArray())); } diff --git a/application/src/main/java/org/thingsboard/server/actors/rule/RuleActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/rule/RuleActorMessageProcessor.java index 5704b123cf..c695ec8316 100644 --- a/application/src/main/java/org/thingsboard/server/actors/rule/RuleActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/rule/RuleActorMessageProcessor.java @@ -322,7 +322,7 @@ class RuleActorMessageProcessor extends ComponentMsgProcessor { @Override public void onClusterEventMsg(ClusterEventMsg msg) throws Exception { - + //Do nothing } private void stopAction() { diff --git a/application/src/main/java/org/thingsboard/server/actors/service/ComponentActor.java b/application/src/main/java/org/thingsboard/server/actors/service/ComponentActor.java index eecee80042..970436a425 100644 --- a/application/src/main/java/org/thingsboard/server/actors/service/ComponentActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/service/ComponentActor.java @@ -104,6 +104,9 @@ public abstract class ComponentActor implements Creator { private static final long serialVersionUID = 1L; - protected final ActorSystemContext context; + protected final transient ActorSystemContext context; public ContextBasedCreator(ActorSystemContext context) { super(); diff --git a/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java b/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java index 7bc254b237..77ef40f8ef 100644 --- a/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java +++ b/application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java @@ -202,7 +202,7 @@ public class DefaultActorService implements ActorService { @Override public void onServerUpdated(ServerInstance server) { - + //Do nothing } @Override diff --git a/application/src/main/java/org/thingsboard/server/actors/session/ASyncMsgProcessor.java b/application/src/main/java/org/thingsboard/server/actors/session/ASyncMsgProcessor.java index b451d773f5..051c5d73c9 100644 --- a/application/src/main/java/org/thingsboard/server/actors/session/ASyncMsgProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/session/ASyncMsgProcessor.java @@ -77,6 +77,8 @@ class ASyncMsgProcessor extends AbstractSessionActorMsgProcessor { case UNSUBSCRIBE_RPC_COMMANDS_REQUEST: subscribedToRpcCommands = false; break; + default: + break; } currentTargetServer = forwardToAppActor(ctx, pendingMsg); } @@ -94,6 +96,8 @@ class ASyncMsgProcessor extends AbstractSessionActorMsgProcessor { pendingMap.remove(responseMsg.getRequestId()); } break; + default: + break; } sessionCtx.onMsg(new BasicSessionActorToAdaptorMsg(this.sessionCtx, msg)); } else { @@ -109,6 +113,7 @@ class ASyncMsgProcessor extends AbstractSessionActorMsgProcessor { // TODO Auto-generated method stub } + @Override protected void cleanupSession(ActorContext ctx) { toDeviceMsg(new SessionCloseMsg()).ifPresent(m -> forwardToAppActor(ctx, m)); } diff --git a/application/src/main/java/org/thingsboard/server/actors/shared/plugin/TenantPluginManager.java b/application/src/main/java/org/thingsboard/server/actors/shared/plugin/TenantPluginManager.java index dde1af69d8..1df39ecdd5 100644 --- a/application/src/main/java/org/thingsboard/server/actors/shared/plugin/TenantPluginManager.java +++ b/application/src/main/java/org/thingsboard/server/actors/shared/plugin/TenantPluginManager.java @@ -31,6 +31,7 @@ public class TenantPluginManager extends PluginManager { this.tenantId = tenantId; } + @Override public void init(ActorContext context) { if (systemContext.isTenantComponentsInitEnabled()) { super.init(context); diff --git a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java index e6f3d09f3d..26bd188e7b 100644 --- a/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java +++ b/application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java @@ -32,6 +32,8 @@ import org.thingsboard.server.actors.shared.plugin.TenantPluginManager; import org.thingsboard.server.actors.shared.rule.RuleManager; import org.thingsboard.server.actors.shared.rule.TenantRuleManager; import org.thingsboard.server.common.data.id.DeviceId; +import org.thingsboard.server.common.data.id.PluginId; +import org.thingsboard.server.common.data.id.RuleId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.msg.cluster.ClusterEventMsg; import org.thingsboard.server.common.msg.device.ToDeviceActorMsg; @@ -126,16 +128,18 @@ public class TenantActor extends ContextAwareActor { } private void onComponentLifecycleMsg(ComponentLifecycleMsg msg) { - if (msg.getPluginId().isPresent()) { - ActorRef pluginActor = pluginManager.getOrCreatePluginActor(this.context(), msg.getPluginId().get()); + Optional pluginId = msg.getPluginId(); + Optional ruleId = msg.getRuleId(); + if (pluginId.isPresent()) { + ActorRef pluginActor = pluginManager.getOrCreatePluginActor(this.context(), pluginId.get()); pluginActor.tell(msg, ActorRef.noSender()); - } else if (msg.getRuleId().isPresent()) { + } else if (ruleId.isPresent()) { ActorRef target; - Optional ref = ruleManager.update(this.context(), msg.getRuleId().get(), msg.getEvent()); + Optional ref = ruleManager.update(this.context(), ruleId.get(), msg.getEvent()); if (ref.isPresent()) { target = ref.get(); } else { - logger.debug("Failed to find actor for rule: [{}]", msg.getRuleId()); + logger.debug("Failed to find actor for rule: [{}]", ruleId); return; } target.tell(msg, ActorRef.noSender()); diff --git a/application/src/main/java/org/thingsboard/server/config/MvcCorsProperties.java b/application/src/main/java/org/thingsboard/server/config/MvcCorsProperties.java index 62b4ec266f..0b024deaa4 100644 --- a/application/src/main/java/org/thingsboard/server/config/MvcCorsProperties.java +++ b/application/src/main/java/org/thingsboard/server/config/MvcCorsProperties.java @@ -33,6 +33,7 @@ public class MvcCorsProperties { private Map mappings = new HashMap<>(); public MvcCorsProperties() { + super(); } public Map getMappings() { diff --git a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java index 5b5f2c8c6f..639579863a 100644 --- a/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java +++ b/application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java @@ -64,7 +64,7 @@ public class ThingsboardSecurityConfiguration extends WebSecurityConfigurerAdapt public static final String FORM_BASED_LOGIN_ENTRY_POINT = "/api/auth/login"; public static final String PUBLIC_LOGIN_ENTRY_POINT = "/api/auth/login/public"; public static final String TOKEN_REFRESH_ENTRY_POINT = "/api/auth/token"; - public static final String[] NON_TOKEN_BASED_AUTH_ENTRY_POINTS = new String[] {"/index.html", "/static/**", "/api/noauth/**", "/webjars/**"}; + protected static final String[] NON_TOKEN_BASED_AUTH_ENTRY_POINTS = new String[] {"/index.html", "/static/**", "/api/noauth/**", "/webjars/**"}; public static final String TOKEN_BASED_AUTH_ENTRY_POINT = "/api/**"; public static final String WS_TOKEN_BASED_AUTH_ENTRY_POINT = "/api/ws/**"; diff --git a/application/src/main/java/org/thingsboard/server/config/WebSocketConfiguration.java b/application/src/main/java/org/thingsboard/server/config/WebSocketConfiguration.java index 2e7c71bffa..35d17732fe 100644 --- a/application/src/main/java/org/thingsboard/server/config/WebSocketConfiguration.java +++ b/application/src/main/java/org/thingsboard/server/config/WebSocketConfiguration.java @@ -76,6 +76,7 @@ public class WebSocketConfiguration implements WebSocketConfigurer { @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) { + //Do nothing } }); } diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java index 3b21611138..988de17a88 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java @@ -30,13 +30,16 @@ import org.thingsboard.server.exception.ThingsboardException; @RequestMapping("/api") public class AlarmController extends BaseController { + public static final String ALARM_ID = "alarmId"; + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}", method = RequestMethod.GET) @ResponseBody - public Alarm getAlarmById(@PathVariable("alarmId") String strAlarmId) throws ThingsboardException { - checkParameter("alarmId", strAlarmId); + public Alarm getAlarmById(@PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { + checkParameter(ALARM_ID, strAlarmId); try { AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); + return checkAlarmId(alarmId); } catch (Exception e) { throw handleException(e); @@ -46,8 +49,8 @@ public class AlarmController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/info/{alarmId}", method = RequestMethod.GET) @ResponseBody - public AlarmInfo getAlarmInfoById(@PathVariable("alarmId") String strAlarmId) throws ThingsboardException { - checkParameter("alarmId", strAlarmId); + public AlarmInfo getAlarmInfoById(@PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { + checkParameter(ALARM_ID, strAlarmId); try { AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); return checkAlarmInfoId(alarmId); @@ -71,8 +74,8 @@ public class AlarmController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}/ack", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) - public void ackAlarm(@PathVariable("alarmId") String strAlarmId) throws ThingsboardException { - checkParameter("alarmId", strAlarmId); + public void ackAlarm(@PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { + checkParameter(ALARM_ID, strAlarmId); try { AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); checkAlarmId(alarmId); @@ -85,8 +88,8 @@ public class AlarmController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/alarm/{alarmId}/clear", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) - public void clearAlarm(@PathVariable("alarmId") String strAlarmId) throws ThingsboardException { - checkParameter("alarmId", strAlarmId); + public void clearAlarm(@PathVariable(ALARM_ID) String strAlarmId) throws ThingsboardException { + checkParameter(ALARM_ID, strAlarmId); try { AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); checkAlarmId(alarmId); diff --git a/application/src/main/java/org/thingsboard/server/controller/AssetController.java b/application/src/main/java/org/thingsboard/server/controller/AssetController.java index 2e17fab218..194b7d89d4 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AssetController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AssetController.java @@ -43,11 +43,13 @@ import java.util.stream.Collectors; @RequestMapping("/api") public class AssetController extends BaseController { + public static final String ASSET_ID = "assetId"; + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/asset/{assetId}", method = RequestMethod.GET) @ResponseBody - public Asset getAssetById(@PathVariable("assetId") String strAssetId) throws ThingsboardException { - checkParameter("assetId", strAssetId); + public Asset getAssetById(@PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { + checkParameter(ASSET_ID, strAssetId); try { AssetId assetId = new AssetId(toUUID(strAssetId)); return checkAssetId(assetId); @@ -80,8 +82,8 @@ public class AssetController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/asset/{assetId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteAsset(@PathVariable("assetId") String strAssetId) throws ThingsboardException { - checkParameter("assetId", strAssetId); + public void deleteAsset(@PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { + checkParameter(ASSET_ID, strAssetId); try { AssetId assetId = new AssetId(toUUID(strAssetId)); checkAssetId(assetId); @@ -95,9 +97,9 @@ public class AssetController extends BaseController { @RequestMapping(value = "/customer/{customerId}/asset/{assetId}", method = RequestMethod.POST) @ResponseBody public Asset assignAssetToCustomer(@PathVariable("customerId") String strCustomerId, - @PathVariable("assetId") String strAssetId) throws ThingsboardException { + @PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { checkParameter("customerId", strCustomerId); - checkParameter("assetId", strAssetId); + checkParameter(ASSET_ID, strAssetId); try { CustomerId customerId = new CustomerId(toUUID(strCustomerId)); checkCustomerId(customerId); @@ -114,8 +116,8 @@ public class AssetController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/asset/{assetId}", method = RequestMethod.DELETE) @ResponseBody - public Asset unassignAssetFromCustomer(@PathVariable("assetId") String strAssetId) throws ThingsboardException { - checkParameter("assetId", strAssetId); + public Asset unassignAssetFromCustomer(@PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { + checkParameter(ASSET_ID, strAssetId); try { AssetId assetId = new AssetId(toUUID(strAssetId)); Asset asset = checkAssetId(assetId); @@ -131,8 +133,8 @@ public class AssetController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/public/asset/{assetId}", method = RequestMethod.POST) @ResponseBody - public Asset assignAssetToPublicCustomer(@PathVariable("assetId") String strAssetId) throws ThingsboardException { - checkParameter("assetId", strAssetId); + public Asset assignAssetToPublicCustomer(@PathVariable(ASSET_ID) String strAssetId) throws ThingsboardException { + checkParameter(ASSET_ID, strAssetId); try { AssetId assetId = new AssetId(toUUID(strAssetId)); Asset asset = checkAssetId(assetId); diff --git a/application/src/main/java/org/thingsboard/server/controller/AuthController.java b/application/src/main/java/org/thingsboard/server/controller/AuthController.java index 204c670ef5..0246e07bb6 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AuthController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AuthController.java @@ -60,9 +60,6 @@ public class AuthController extends BaseController { @Autowired private RefreshTokenRepository refreshTokenRepository; - @Autowired - private UserService userService; - @Autowired private MailService mailService; @@ -103,13 +100,13 @@ public class AuthController extends BaseController { HttpStatus responseStatus; UserCredentials userCredentials = userService.findUserCredentialsByActivateToken(activateToken); if (userCredentials != null) { - String createPasswordURI = "/login/createPassword"; + String createURI = "/login/createPassword"; try { - URI location = new URI(createPasswordURI + "?activateToken=" + activateToken); + URI location = new URI(createURI + "?activateToken=" + activateToken); headers.setLocation(location); responseStatus = HttpStatus.SEE_OTHER; } catch (URISyntaxException e) { - log.error("Unable to create URI with address [{}]", createPasswordURI); + log.error("Unable to create URI with address [{}]", createURI); responseStatus = HttpStatus.BAD_REQUEST; } } else { @@ -126,10 +123,10 @@ public class AuthController extends BaseController { try { UserCredentials userCredentials = userService.requestPasswordReset(email); String baseUrl = constructBaseUrl(request); - String resetPasswordUrl = String.format("%s/api/noauth/resetPassword?resetToken=%s", baseUrl, + String resetUrl = String.format("%s/api/noauth/resetPassword?resetToken=%s", baseUrl, userCredentials.getResetToken()); - mailService.sendResetPasswordEmail(resetPasswordUrl, email); + mailService.sendResetPasswordEmail(resetUrl, email); } catch (Exception e) { throw handleException(e); } @@ -140,15 +137,15 @@ public class AuthController extends BaseController { @RequestParam(value = "resetToken") String resetToken) { HttpHeaders headers = new HttpHeaders(); HttpStatus responseStatus; - String resetPasswordURI = "/login/resetPassword"; + String resetURI = "/login/resetPassword"; UserCredentials userCredentials = userService.findUserCredentialsByResetToken(resetToken); if (userCredentials != null) { try { - URI location = new URI(resetPasswordURI + "?resetToken=" + resetToken); + URI location = new URI(resetURI + "?resetToken=" + resetToken); headers.setLocation(location); responseStatus = HttpStatus.SEE_OTHER; } catch (URISyntaxException e) { - log.error("Unable to create URI with address [{}]", resetPasswordURI); + log.error("Unable to create URI with address [{}]", resetURI); responseStatus = HttpStatus.BAD_REQUEST; } } else { diff --git a/application/src/main/java/org/thingsboard/server/controller/BaseController.java b/application/src/main/java/org/thingsboard/server/controller/BaseController.java index 1040f3a892..16ba93eca8 100644 --- a/application/src/main/java/org/thingsboard/server/controller/BaseController.java +++ b/application/src/main/java/org/thingsboard/server/controller/BaseController.java @@ -70,6 +70,8 @@ import static org.thingsboard.server.dao.service.Validator.validateId; @Slf4j public abstract class BaseController { + public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; + public static final String YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION = "You don't have permission to perform this operation!"; @Autowired private ThingsboardErrorResponseHandler errorResponseHandler; @@ -209,11 +211,11 @@ public abstract class BaseController { } void checkTenantId(TenantId tenantId) throws ThingsboardException { - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); SecurityUser authUser = getCurrentUser(); if (authUser.getAuthority() != Authority.SYS_ADMIN && (authUser.getTenantId() == null || !authUser.getTenantId().equals(tenantId))) { - throw new ThingsboardException("You don't have permission to perform this operation!", + throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, ThingsboardErrorCode.PERMISSION_DENIED); } } @@ -229,7 +231,7 @@ public abstract class BaseController { if (authUser.getAuthority() == Authority.SYS_ADMIN || (authUser.getAuthority() != Authority.TENANT_ADMIN && (authUser.getCustomerId() == null || !authUser.getCustomerId().equals(customerId)))) { - throw new ThingsboardException("You don't have permission to perform this operation!", + throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, ThingsboardErrorCode.PERMISSION_DENIED); } Customer customer = customerService.findCustomerById(customerId); @@ -382,7 +384,7 @@ public abstract class BaseController { if (widgetsBundle.getTenantId() != null && !widgetsBundle.getTenantId().getId().equals(ModelConstants.NULL_UUID)) { checkTenantId(widgetsBundle.getTenantId()); } else if (modify && getCurrentUser().getAuthority() != Authority.SYS_ADMIN) { - throw new ThingsboardException("You don't have permission to perform this operation!", + throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, ThingsboardErrorCode.PERMISSION_DENIED); } } @@ -403,7 +405,7 @@ public abstract class BaseController { if (widgetType.getTenantId() != null && !widgetType.getTenantId().getId().equals(ModelConstants.NULL_UUID)) { checkTenantId(widgetType.getTenantId()); } else if (modify && getCurrentUser().getAuthority() != Authority.SYS_ADMIN) { - throw new ThingsboardException("You don't have permission to perform this operation!", + throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, ThingsboardErrorCode.PERMISSION_DENIED); } } @@ -437,7 +439,7 @@ public abstract class BaseController { SecurityUser authUser = getCurrentUser(); if (authUser.getAuthority() == Authority.CUSTOMER_USER) { if (dashboard.getCustomerId() == null || dashboard.getCustomerId().getId().equals(ModelConstants.NULL_UUID)) { - throw new ThingsboardException("You don't have permission to perform this operation!", + throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, ThingsboardErrorCode.PERMISSION_DENIED); } } @@ -480,11 +482,11 @@ public abstract class BaseController { checkNotNull(plugin); SecurityUser authUser = getCurrentUser(); TenantId tenantId = plugin.getTenantId(); - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); if (authUser.getAuthority() != Authority.SYS_ADMIN) { if (authUser.getTenantId() == null || !tenantId.getId().equals(ModelConstants.NULL_UUID) && !authUser.getTenantId().equals(tenantId)) { - throw new ThingsboardException("You don't have permission to perform this operation!", + throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, ThingsboardErrorCode.PERMISSION_DENIED); } else if (tenantId.getId().equals(ModelConstants.NULL_UUID)) { @@ -508,11 +510,11 @@ public abstract class BaseController { checkNotNull(rule); SecurityUser authUser = getCurrentUser(); TenantId tenantId = rule.getTenantId(); - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); if (authUser.getAuthority() != Authority.SYS_ADMIN) { if (authUser.getTenantId() == null || !tenantId.getId().equals(ModelConstants.NULL_UUID) && !authUser.getTenantId().equals(tenantId)) { - throw new ThingsboardException("You don't have permission to perform this operation!", + throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, ThingsboardErrorCode.PERMISSION_DENIED); } diff --git a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java index ec1149656b..c54973f0bc 100644 --- a/application/src/main/java/org/thingsboard/server/controller/CustomerController.java +++ b/application/src/main/java/org/thingsboard/server/controller/CustomerController.java @@ -32,11 +32,14 @@ import org.thingsboard.server.exception.ThingsboardException; @RequestMapping("/api") public class CustomerController extends BaseController { + public static final String CUSTOMER_ID = "customerId"; + public static final String IS_PUBLIC = "isPublic"; + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/customer/{customerId}", method = RequestMethod.GET) @ResponseBody - public Customer getCustomerById(@PathVariable("customerId") String strCustomerId) throws ThingsboardException { - checkParameter("customerId", strCustomerId); + public Customer getCustomerById(@PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException { + checkParameter(CUSTOMER_ID, strCustomerId); try { CustomerId customerId = new CustomerId(toUUID(strCustomerId)); return checkCustomerId(customerId); @@ -48,15 +51,15 @@ public class CustomerController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/customer/{customerId}/shortInfo", method = RequestMethod.GET) @ResponseBody - public JsonNode getShortCustomerInfoById(@PathVariable("customerId") String strCustomerId) throws ThingsboardException { - checkParameter("customerId", strCustomerId); + public JsonNode getShortCustomerInfoById(@PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException { + checkParameter(CUSTOMER_ID, strCustomerId); try { CustomerId customerId = new CustomerId(toUUID(strCustomerId)); Customer customer = checkCustomerId(customerId); ObjectMapper objectMapper = new ObjectMapper(); ObjectNode infoObject = objectMapper.createObjectNode(); infoObject.put("title", customer.getTitle()); - infoObject.put("isPublic", customer.isPublic()); + infoObject.put(IS_PUBLIC, customer.isPublic()); return infoObject; } catch (Exception e) { throw handleException(e); @@ -66,8 +69,8 @@ public class CustomerController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/customer/{customerId}/title", method = RequestMethod.GET, produces = "application/text") @ResponseBody - public String getCustomerTitleById(@PathVariable("customerId") String strCustomerId) throws ThingsboardException { - checkParameter("customerId", strCustomerId); + public String getCustomerTitleById(@PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException { + checkParameter(CUSTOMER_ID, strCustomerId); try { CustomerId customerId = new CustomerId(toUUID(strCustomerId)); Customer customer = checkCustomerId(customerId); @@ -92,8 +95,8 @@ public class CustomerController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/{customerId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteCustomer(@PathVariable("customerId") String strCustomerId) throws ThingsboardException { - checkParameter("customerId", strCustomerId); + public void deleteCustomer(@PathVariable(CUSTOMER_ID) String strCustomerId) throws ThingsboardException { + checkParameter(CUSTOMER_ID, strCustomerId); try { CustomerId customerId = new CustomerId(toUUID(strCustomerId)); checkCustomerId(customerId); diff --git a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java index 2a6416ce98..7bc05d71d6 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DashboardController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DashboardController.java @@ -34,6 +34,8 @@ import org.thingsboard.server.exception.ThingsboardException; @RequestMapping("/api") public class DashboardController extends BaseController { + public static final String DASHBOARD_ID = "dashboardId"; + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/dashboard/serverTime", method = RequestMethod.GET) @ResponseBody @@ -44,8 +46,8 @@ public class DashboardController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/dashboard/info/{dashboardId}", method = RequestMethod.GET) @ResponseBody - public DashboardInfo getDashboardInfoById(@PathVariable("dashboardId") String strDashboardId) throws ThingsboardException { - checkParameter("dashboardId", strDashboardId); + public DashboardInfo getDashboardInfoById(@PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { + checkParameter(DASHBOARD_ID, strDashboardId); try { DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); return checkDashboardInfoId(dashboardId); @@ -57,8 +59,8 @@ public class DashboardController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/dashboard/{dashboardId}", method = RequestMethod.GET) @ResponseBody - public Dashboard getDashboardById(@PathVariable("dashboardId") String strDashboardId) throws ThingsboardException { - checkParameter("dashboardId", strDashboardId); + public Dashboard getDashboardById(@PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { + checkParameter(DASHBOARD_ID, strDashboardId); try { DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); return checkDashboardId(dashboardId); @@ -82,8 +84,8 @@ public class DashboardController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/dashboard/{dashboardId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteDashboard(@PathVariable("dashboardId") String strDashboardId) throws ThingsboardException { - checkParameter("dashboardId", strDashboardId); + public void deleteDashboard(@PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { + checkParameter(DASHBOARD_ID, strDashboardId); try { DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); checkDashboardId(dashboardId); @@ -97,9 +99,9 @@ public class DashboardController extends BaseController { @RequestMapping(value = "/customer/{customerId}/dashboard/{dashboardId}", method = RequestMethod.POST) @ResponseBody public Dashboard assignDashboardToCustomer(@PathVariable("customerId") String strCustomerId, - @PathVariable("dashboardId") String strDashboardId) throws ThingsboardException { + @PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { checkParameter("customerId", strCustomerId); - checkParameter("dashboardId", strDashboardId); + checkParameter(DASHBOARD_ID, strDashboardId); try { CustomerId customerId = new CustomerId(toUUID(strCustomerId)); checkCustomerId(customerId); @@ -116,8 +118,8 @@ public class DashboardController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/dashboard/{dashboardId}", method = RequestMethod.DELETE) @ResponseBody - public Dashboard unassignDashboardFromCustomer(@PathVariable("dashboardId") String strDashboardId) throws ThingsboardException { - checkParameter("dashboardId", strDashboardId); + public Dashboard unassignDashboardFromCustomer(@PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { + checkParameter(DASHBOARD_ID, strDashboardId); try { DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); Dashboard dashboard = checkDashboardId(dashboardId); @@ -133,8 +135,8 @@ public class DashboardController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/public/dashboard/{dashboardId}", method = RequestMethod.POST) @ResponseBody - public Dashboard assignDashboardToPublicCustomer(@PathVariable("dashboardId") String strDashboardId) throws ThingsboardException { - checkParameter("dashboardId", strDashboardId); + public Dashboard assignDashboardToPublicCustomer(@PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { + checkParameter(DASHBOARD_ID, strDashboardId); try { DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); Dashboard dashboard = checkDashboardId(dashboardId); diff --git a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java index fac841d938..eeb10c8c83 100644 --- a/application/src/main/java/org/thingsboard/server/controller/DeviceController.java +++ b/application/src/main/java/org/thingsboard/server/controller/DeviceController.java @@ -44,11 +44,13 @@ import java.util.stream.Collectors; @RequestMapping("/api") public class DeviceController extends BaseController { + public static final String DEVICE_ID = "deviceId"; + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/device/{deviceId}", method = RequestMethod.GET) @ResponseBody - public Device getDeviceById(@PathVariable("deviceId") String strDeviceId) throws ThingsboardException { - checkParameter("deviceId", strDeviceId); + public Device getDeviceById(@PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { + checkParameter(DEVICE_ID, strDeviceId); try { DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); return checkDeviceId(deviceId); @@ -88,8 +90,8 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/device/{deviceId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteDevice(@PathVariable("deviceId") String strDeviceId) throws ThingsboardException { - checkParameter("deviceId", strDeviceId); + public void deleteDevice(@PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { + checkParameter(DEVICE_ID, strDeviceId); try { DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); checkDeviceId(deviceId); @@ -103,9 +105,9 @@ public class DeviceController extends BaseController { @RequestMapping(value = "/customer/{customerId}/device/{deviceId}", method = RequestMethod.POST) @ResponseBody public Device assignDeviceToCustomer(@PathVariable("customerId") String strCustomerId, - @PathVariable("deviceId") String strDeviceId) throws ThingsboardException { + @PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { checkParameter("customerId", strCustomerId); - checkParameter("deviceId", strDeviceId); + checkParameter(DEVICE_ID, strDeviceId); try { CustomerId customerId = new CustomerId(toUUID(strCustomerId)); checkCustomerId(customerId); @@ -122,8 +124,8 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/device/{deviceId}", method = RequestMethod.DELETE) @ResponseBody - public Device unassignDeviceFromCustomer(@PathVariable("deviceId") String strDeviceId) throws ThingsboardException { - checkParameter("deviceId", strDeviceId); + public Device unassignDeviceFromCustomer(@PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { + checkParameter(DEVICE_ID, strDeviceId); try { DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); Device device = checkDeviceId(deviceId); @@ -139,8 +141,8 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/customer/public/device/{deviceId}", method = RequestMethod.POST) @ResponseBody - public Device assignDeviceToPublicCustomer(@PathVariable("deviceId") String strDeviceId) throws ThingsboardException { - checkParameter("deviceId", strDeviceId); + public Device assignDeviceToPublicCustomer(@PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { + checkParameter(DEVICE_ID, strDeviceId); try { DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); Device device = checkDeviceId(deviceId); @@ -154,8 +156,8 @@ public class DeviceController extends BaseController { @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/device/{deviceId}/credentials", method = RequestMethod.GET) @ResponseBody - public DeviceCredentials getDeviceCredentialsByDeviceId(@PathVariable("deviceId") String strDeviceId) throws ThingsboardException { - checkParameter("deviceId", strDeviceId); + public DeviceCredentials getDeviceCredentialsByDeviceId(@PathVariable(DEVICE_ID) String strDeviceId) throws ThingsboardException { + checkParameter(DEVICE_ID, strDeviceId); try { DeviceId deviceId = new DeviceId(toUUID(strDeviceId)); checkDeviceId(deviceId); diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java b/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java index f21f6d9af8..ec7be1276a 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java @@ -34,6 +34,12 @@ import java.util.List; @RequestMapping("/api") public class EntityRelationController extends BaseController { + public static final String TO_TYPE = "toType"; + public static final String FROM_ID = "fromId"; + public static final String FROM_TYPE = "fromType"; + public static final String RELATION_TYPE = "relationType"; + public static final String TO_ID = "toId"; + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/relation", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) @@ -45,32 +51,32 @@ public class EntityRelationController extends BaseController { if (relation.getTypeGroup() == null) { relation.setTypeGroup(RelationTypeGroup.COMMON); } - relationService.saveRelation(relation).get(); + relationService.saveRelation(relation); } catch (Exception e) { throw handleException(e); } } @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/relation", method = RequestMethod.DELETE, params = {"fromId", "fromType", "relationType", "toId", "toType"}) + @RequestMapping(value = "/relation", method = RequestMethod.DELETE, params = {FROM_ID, FROM_TYPE, RELATION_TYPE, TO_ID, TO_TYPE}) @ResponseStatus(value = HttpStatus.OK) - public void deleteRelation(@RequestParam("fromId") String strFromId, - @RequestParam("fromType") String strFromType, - @RequestParam("relationType") String strRelationType, + public void deleteRelation(@RequestParam(FROM_ID) String strFromId, + @RequestParam(FROM_TYPE) String strFromType, + @RequestParam(RELATION_TYPE) String strRelationType, @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup, - @RequestParam("toId") String strToId, @RequestParam("toType") String strToType) throws ThingsboardException { - checkParameter("fromId", strFromId); - checkParameter("fromType", strFromType); - checkParameter("relationType", strRelationType); - checkParameter("toId", strToId); - checkParameter("toType", strToType); + @RequestParam(TO_ID) String strToId, @RequestParam(TO_TYPE) String strToType) throws ThingsboardException { + checkParameter(FROM_ID, strFromId); + checkParameter(FROM_TYPE, strFromType); + checkParameter(RELATION_TYPE, strRelationType); + checkParameter(TO_ID, strToId); + checkParameter(TO_TYPE, strToType); EntityId fromId = EntityIdFactory.getByTypeAndId(strFromType, strFromId); EntityId toId = EntityIdFactory.getByTypeAndId(strToType, strToId); checkEntityId(fromId); checkEntityId(toId); RelationTypeGroup relationTypeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); try { - Boolean found = relationService.deleteRelation(fromId, toId, strRelationType, relationTypeGroup).get(); + Boolean found = relationService.deleteRelation(fromId, toId, strRelationType, relationTypeGroup); if (!found) { throw new ThingsboardException("Requested item wasn't found!", ThingsboardErrorCode.ITEM_NOT_FOUND); } @@ -89,26 +95,26 @@ public class EntityRelationController extends BaseController { EntityId entityId = EntityIdFactory.getByTypeAndId(strType, strId); checkEntityId(entityId); try { - relationService.deleteEntityRelations(entityId).get(); + relationService.deleteEntityRelations(entityId); } catch (Exception e) { throw handleException(e); } } @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/relation", method = RequestMethod.GET, params = {"fromId", "fromType", "relationType", "toId", "toType"}) + @RequestMapping(value = "/relation", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE, RELATION_TYPE, TO_ID, TO_TYPE}) @ResponseBody - public EntityRelation getRelation(@RequestParam("fromId") String strFromId, - @RequestParam("fromType") String strFromType, - @RequestParam("relationType") String strRelationType, - @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup, - @RequestParam("toId") String strToId, @RequestParam("toType") String strToType) throws ThingsboardException { + public EntityRelation getRelation(@RequestParam(FROM_ID) String strFromId, + @RequestParam(FROM_TYPE) String strFromType, + @RequestParam(RELATION_TYPE) String strRelationType, + @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup, + @RequestParam(TO_ID) String strToId, @RequestParam(TO_TYPE) String strToType) throws ThingsboardException { try { - checkParameter("fromId", strFromId); - checkParameter("fromType", strFromType); - checkParameter("relationType", strRelationType); - checkParameter("toId", strToId); - checkParameter("toType", strToType); + checkParameter(FROM_ID, strFromId); + checkParameter(FROM_TYPE, strFromType); + checkParameter(RELATION_TYPE, strRelationType); + checkParameter(TO_ID, strToId); + checkParameter(TO_TYPE, strToType); EntityId fromId = EntityIdFactory.getByTypeAndId(strFromType, strFromId); EntityId toId = EntityIdFactory.getByTypeAndId(strToType, strToId); checkEntityId(fromId); @@ -121,13 +127,13 @@ public class EntityRelationController extends BaseController { } @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {"fromId", "fromType"}) + @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE}) @ResponseBody - public List findByFrom(@RequestParam("fromId") String strFromId, - @RequestParam("fromType") String strFromType, + public List findByFrom(@RequestParam(FROM_ID) String strFromId, + @RequestParam(FROM_TYPE) String strFromType, @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { - checkParameter("fromId", strFromId); - checkParameter("fromType", strFromType); + checkParameter(FROM_ID, strFromId); + checkParameter(FROM_TYPE, strFromType); EntityId entityId = EntityIdFactory.getByTypeAndId(strFromType, strFromId); checkEntityId(entityId); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); @@ -139,13 +145,13 @@ public class EntityRelationController extends BaseController { } @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {"fromId", "fromType"}) + @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE}) @ResponseBody - public List findInfoByFrom(@RequestParam("fromId") String strFromId, - @RequestParam("fromType") String strFromType, + public List findInfoByFrom(@RequestParam(FROM_ID) String strFromId, + @RequestParam(FROM_TYPE) String strFromType, @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { - checkParameter("fromId", strFromId); - checkParameter("fromType", strFromType); + checkParameter(FROM_ID, strFromId); + checkParameter(FROM_TYPE, strFromType); EntityId entityId = EntityIdFactory.getByTypeAndId(strFromType, strFromId); checkEntityId(entityId); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); @@ -157,15 +163,15 @@ public class EntityRelationController extends BaseController { } @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {"fromId", "fromType", "relationType"}) + @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {FROM_ID, FROM_TYPE, RELATION_TYPE}) @ResponseBody - public List findByFrom(@RequestParam("fromId") String strFromId, - @RequestParam("fromType") String strFromType, - @RequestParam("relationType") String strRelationType, + public List findByFrom(@RequestParam(FROM_ID) String strFromId, + @RequestParam(FROM_TYPE) String strFromType, + @RequestParam(RELATION_TYPE) String strRelationType, @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { - checkParameter("fromId", strFromId); - checkParameter("fromType", strFromType); - checkParameter("relationType", strRelationType); + checkParameter(FROM_ID, strFromId); + checkParameter(FROM_TYPE, strFromType); + checkParameter(RELATION_TYPE, strRelationType); EntityId entityId = EntityIdFactory.getByTypeAndId(strFromType, strFromId); checkEntityId(entityId); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); @@ -177,13 +183,13 @@ public class EntityRelationController extends BaseController { } @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {"toId", "toType"}) + @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {TO_ID, TO_TYPE}) @ResponseBody - public List findByTo(@RequestParam("toId") String strToId, - @RequestParam("toType") String strToType, + public List findByTo(@RequestParam(TO_ID) String strToId, + @RequestParam(TO_TYPE) String strToType, @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { - checkParameter("toId", strToId); - checkParameter("toType", strToType); + checkParameter(TO_ID, strToId); + checkParameter(TO_TYPE, strToType); EntityId entityId = EntityIdFactory.getByTypeAndId(strToType, strToId); checkEntityId(entityId); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); @@ -195,13 +201,13 @@ public class EntityRelationController extends BaseController { } @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {"toId", "toType"}) + @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {TO_ID, TO_TYPE}) @ResponseBody - public List findInfoByTo(@RequestParam("toId") String strToId, - @RequestParam("toType") String strToType, + public List findInfoByTo(@RequestParam(TO_ID) String strToId, + @RequestParam(TO_TYPE) String strToType, @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { - checkParameter("toId", strToId); - checkParameter("toType", strToType); + checkParameter(TO_ID, strToId); + checkParameter(TO_TYPE, strToType); EntityId entityId = EntityIdFactory.getByTypeAndId(strToType, strToId); checkEntityId(entityId); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); @@ -213,15 +219,15 @@ public class EntityRelationController extends BaseController { } @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") - @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {"toId", "toType", "relationType"}) + @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {TO_ID, TO_TYPE, RELATION_TYPE}) @ResponseBody - public List findByTo(@RequestParam("toId") String strToId, - @RequestParam("toType") String strToType, - @RequestParam("relationType") String strRelationType, + public List findByTo(@RequestParam(TO_ID) String strToId, + @RequestParam(TO_TYPE) String strToType, + @RequestParam(RELATION_TYPE) String strRelationType, @RequestParam(value = "relationTypeGroup", required = false) String strRelationTypeGroup) throws ThingsboardException { - checkParameter("toId", strToId); - checkParameter("toType", strToType); - checkParameter("relationType", strRelationType); + checkParameter(TO_ID, strToId); + checkParameter(TO_TYPE, strToType); + checkParameter(RELATION_TYPE, strRelationType); EntityId entityId = EntityIdFactory.getByTypeAndId(strToType, strToId); checkEntityId(entityId); RelationTypeGroup typeGroup = parseRelationTypeGroup(strRelationTypeGroup, RelationTypeGroup.COMMON); @@ -267,9 +273,7 @@ public class EntityRelationController extends BaseController { if (strRelationTypeGroup != null && strRelationTypeGroup.trim().length()>0) { try { result = RelationTypeGroup.valueOf(strRelationTypeGroup); - } catch (IllegalArgumentException e) { - result = defaultValue; - } + } catch (IllegalArgumentException e) { } } return result; } diff --git a/application/src/main/java/org/thingsboard/server/controller/PluginController.java b/application/src/main/java/org/thingsboard/server/controller/PluginController.java index 5dd14ccf15..191fc6b861 100644 --- a/application/src/main/java/org/thingsboard/server/controller/PluginController.java +++ b/application/src/main/java/org/thingsboard/server/controller/PluginController.java @@ -34,11 +34,13 @@ import java.util.List; @RequestMapping("/api") public class PluginController extends BaseController { + public static final String PLUGIN_ID = "pluginId"; + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/plugin/{pluginId}", method = RequestMethod.GET) @ResponseBody - public PluginMetaData getPluginById(@PathVariable("pluginId") String strPluginId) throws ThingsboardException { - checkParameter("pluginId", strPluginId); + public PluginMetaData getPluginById(@PathVariable(PLUGIN_ID) String strPluginId) throws ThingsboardException { + checkParameter(PLUGIN_ID, strPluginId); try { PluginId pluginId = new PluginId(toUUID(strPluginId)); return checkPlugin(pluginService.findPluginById(pluginId)); @@ -78,8 +80,8 @@ public class PluginController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/plugin/{pluginId}/activate", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) - public void activatePluginById(@PathVariable("pluginId") String strPluginId) throws ThingsboardException { - checkParameter("pluginId", strPluginId); + public void activatePluginById(@PathVariable(PLUGIN_ID) String strPluginId) throws ThingsboardException { + checkParameter(PLUGIN_ID, strPluginId); try { PluginId pluginId = new PluginId(toUUID(strPluginId)); PluginMetaData plugin = checkPlugin(pluginService.findPluginById(pluginId)); @@ -93,8 +95,8 @@ public class PluginController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/plugin/{pluginId}/suspend", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) - public void suspendPluginById(@PathVariable("pluginId") String strPluginId) throws ThingsboardException { - checkParameter("pluginId", strPluginId); + public void suspendPluginById(@PathVariable(PLUGIN_ID) String strPluginId) throws ThingsboardException { + checkParameter(PLUGIN_ID, strPluginId); try { PluginId pluginId = new PluginId(toUUID(strPluginId)); PluginMetaData plugin = checkPlugin(pluginService.findPluginById(pluginId)); @@ -180,8 +182,8 @@ public class PluginController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/plugin/{pluginId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deletePlugin(@PathVariable("pluginId") String strPluginId) throws ThingsboardException { - checkParameter("pluginId", strPluginId); + public void deletePlugin(@PathVariable(PLUGIN_ID) String strPluginId) throws ThingsboardException { + checkParameter(PLUGIN_ID, strPluginId); try { PluginId pluginId = new PluginId(toUUID(strPluginId)); PluginMetaData plugin = checkPlugin(pluginService.findPluginById(pluginId)); diff --git a/application/src/main/java/org/thingsboard/server/controller/RuleController.java b/application/src/main/java/org/thingsboard/server/controller/RuleController.java index a2082eceb4..84d1c8f92e 100644 --- a/application/src/main/java/org/thingsboard/server/controller/RuleController.java +++ b/application/src/main/java/org/thingsboard/server/controller/RuleController.java @@ -34,11 +34,13 @@ import java.util.List; @RequestMapping("/api") public class RuleController extends BaseController { + public static final String RULE_ID = "ruleId"; + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/rule/{ruleId}", method = RequestMethod.GET) @ResponseBody - public RuleMetaData getRuleById(@PathVariable("ruleId") String strRuleId) throws ThingsboardException { - checkParameter("ruleId", strRuleId); + public RuleMetaData getRuleById(@PathVariable(RULE_ID) String strRuleId) throws ThingsboardException { + checkParameter(RULE_ID, strRuleId); try { RuleId ruleId = new RuleId(toUUID(strRuleId)); return checkRule(ruleService.findRuleById(ruleId)); @@ -80,8 +82,8 @@ public class RuleController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/rule/{ruleId}/activate", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) - public void activateRuleById(@PathVariable("ruleId") String strRuleId) throws ThingsboardException { - checkParameter("ruleId", strRuleId); + public void activateRuleById(@PathVariable(RULE_ID) String strRuleId) throws ThingsboardException { + checkParameter(RULE_ID, strRuleId); try { RuleId ruleId = new RuleId(toUUID(strRuleId)); RuleMetaData rule = checkRule(ruleService.findRuleById(ruleId)); @@ -95,8 +97,8 @@ public class RuleController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/rule/{ruleId}/suspend", method = RequestMethod.POST) @ResponseStatus(value = HttpStatus.OK) - public void suspendRuleById(@PathVariable("ruleId") String strRuleId) throws ThingsboardException { - checkParameter("ruleId", strRuleId); + public void suspendRuleById(@PathVariable(RULE_ID) String strRuleId) throws ThingsboardException { + checkParameter(RULE_ID, strRuleId); try { RuleId ruleId = new RuleId(toUUID(strRuleId)); RuleMetaData rule = checkRule(ruleService.findRuleById(ruleId)); @@ -178,8 +180,8 @@ public class RuleController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/rule/{ruleId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteRule(@PathVariable("ruleId") String strRuleId) throws ThingsboardException { - checkParameter("ruleId", strRuleId); + public void deleteRule(@PathVariable(RULE_ID) String strRuleId) throws ThingsboardException { + checkParameter(RULE_ID, strRuleId); try { RuleId ruleId = new RuleId(toUUID(strRuleId)); RuleMetaData rule = checkRule(ruleService.findRuleById(ruleId)); diff --git a/application/src/main/java/org/thingsboard/server/controller/UserController.java b/application/src/main/java/org/thingsboard/server/controller/UserController.java index f80c7c6a31..05fca0b1d0 100644 --- a/application/src/main/java/org/thingsboard/server/controller/UserController.java +++ b/application/src/main/java/org/thingsboard/server/controller/UserController.java @@ -38,19 +38,22 @@ import javax.servlet.http.HttpServletRequest; @RequestMapping("/api") public class UserController extends BaseController { + public static final String USER_ID = "userId"; + public static final String YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION = "You don't have permission to perform this operation!"; + public static final String ACTIVATE_URL_PATTERN = "%s/api/noauth/activate?activateToken=%s"; @Autowired private MailService mailService; @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/user/{userId}", method = RequestMethod.GET) @ResponseBody - public User getUserById(@PathVariable("userId") String strUserId) throws ThingsboardException { - checkParameter("userId", strUserId); + public User getUserById(@PathVariable(USER_ID) String strUserId) throws ThingsboardException { + checkParameter(USER_ID, strUserId); try { UserId userId = new UserId(toUUID(strUserId)); SecurityUser authUser = getCurrentUser(); if (authUser.getAuthority() == Authority.CUSTOMER_USER && !authUser.getId().equals(userId)) { - throw new ThingsboardException("You don't have permission to perform this operation!", + throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, ThingsboardErrorCode.PERMISSION_DENIED); } return checkUserId(userId); @@ -68,7 +71,7 @@ public class UserController extends BaseController { try { SecurityUser authUser = getCurrentUser(); if (authUser.getAuthority() == Authority.CUSTOMER_USER && !authUser.getId().equals(user.getId())) { - throw new ThingsboardException("You don't have permission to perform this operation!", + throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, ThingsboardErrorCode.PERMISSION_DENIED); } boolean sendEmail = user.getId() == null && sendActivationMail; @@ -79,7 +82,7 @@ public class UserController extends BaseController { if (sendEmail) { UserCredentials userCredentials = userService.findUserCredentialsByUserId(savedUser.getId()); String baseUrl = constructBaseUrl(request); - String activateUrl = String.format("%s/api/noauth/activate?activateToken=%s", baseUrl, + String activateUrl = String.format(ACTIVATE_URL_PATTERN, baseUrl, userCredentials.getActivateToken()); String email = savedUser.getEmail(); try { @@ -106,7 +109,7 @@ public class UserController extends BaseController { UserCredentials userCredentials = userService.findUserCredentialsByUserId(user.getId()); if (!userCredentials.isEnabled()) { String baseUrl = constructBaseUrl(request); - String activateUrl = String.format("%s/api/noauth/activate?activateToken=%s", baseUrl, + String activateUrl = String.format(ACTIVATE_URL_PATTERN, baseUrl, userCredentials.getActivateToken()); mailService.sendActivationEmail(activateUrl, email); } else { @@ -121,21 +124,21 @@ public class UserController extends BaseController { @RequestMapping(value = "/user/{userId}/activationLink", method = RequestMethod.GET, produces = "text/plain") @ResponseBody public String getActivationLink( - @PathVariable("userId") String strUserId, + @PathVariable(USER_ID) String strUserId, HttpServletRequest request) throws ThingsboardException { - checkParameter("userId", strUserId); + checkParameter(USER_ID, strUserId); try { UserId userId = new UserId(toUUID(strUserId)); SecurityUser authUser = getCurrentUser(); if (authUser.getAuthority() == Authority.CUSTOMER_USER && !authUser.getId().equals(userId)) { - throw new ThingsboardException("You don't have permission to perform this operation!", + throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, ThingsboardErrorCode.PERMISSION_DENIED); } User user = checkUserId(userId); UserCredentials userCredentials = userService.findUserCredentialsByUserId(user.getId()); if (!userCredentials.isEnabled()) { String baseUrl = constructBaseUrl(request); - String activateUrl = String.format("%s/api/noauth/activate?activateToken=%s", baseUrl, + String activateUrl = String.format(ACTIVATE_URL_PATTERN, baseUrl, userCredentials.getActivateToken()); return activateUrl; } else { @@ -149,8 +152,8 @@ public class UserController extends BaseController { @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") @RequestMapping(value = "/user/{userId}", method = RequestMethod.DELETE) @ResponseStatus(value = HttpStatus.OK) - public void deleteUser(@PathVariable("userId") String strUserId) throws ThingsboardException { - checkParameter("userId", strUserId); + public void deleteUser(@PathVariable(USER_ID) String strUserId) throws ThingsboardException { + checkParameter(USER_ID, strUserId); try { UserId userId = new UserId(toUUID(strUserId)); checkUserId(userId); diff --git a/application/src/main/java/org/thingsboard/server/controller/plugin/PluginApiController.java b/application/src/main/java/org/thingsboard/server/controller/plugin/PluginApiController.java index 9ddac86610..1789da6f28 100644 --- a/application/src/main/java/org/thingsboard/server/controller/plugin/PluginApiController.java +++ b/application/src/main/java/org/thingsboard/server/controller/plugin/PluginApiController.java @@ -47,12 +47,6 @@ import javax.servlet.http.HttpServletRequest; @Slf4j public class PluginApiController extends BaseController { - @Autowired - private ActorService actorService; - - @Autowired - private PluginService pluginService; - @SuppressWarnings("rawtypes") @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") @RequestMapping(value = "/{pluginToken}/**") @@ -71,7 +65,7 @@ public class PluginApiController extends BaseController { TenantId tenantId = getCurrentUser().getTenantId(); CustomerId customerId = getCurrentUser().getCustomerId(); if (validatePluginAccess(pluginMd, tenantId, customerId)) { - if(ModelConstants.NULL_UUID.equals(tenantId.getId())){ + if(tenantId != null && ModelConstants.NULL_UUID.equals(tenantId.getId())){ tenantId = null; } PluginApiCallSecurityContext securityCtx = new PluginApiCallSecurityContext(pluginMd.getTenantId(), pluginMd.getId(), tenantId, customerId); @@ -97,7 +91,7 @@ public class PluginApiController extends BaseController { validUser = true; } } else { - if ((pluginMd.isPublicAccess() || tenantAdministrator) && tenantId.equals(pluginMd.getTenantId())) { + if ((pluginMd.isPublicAccess() || tenantAdministrator) && tenantId != null && tenantId.equals(pluginMd.getTenantId())) { // All tenant users can access public tenant plugins. Only tenant // administrator can access private tenant plugins validUser = true; diff --git a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java index 6ebe3c98ef..577c0c5c00 100644 --- a/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java +++ b/application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java @@ -28,7 +28,6 @@ import org.thingsboard.server.service.install.DatabaseSchemaService; import org.thingsboard.server.service.install.DatabaseUpgradeService; import org.thingsboard.server.service.install.SystemDataLoaderService; -import java.nio.file.Files; import java.nio.file.Paths; @Service @@ -69,7 +68,7 @@ public class ThingsboardInstallService { log.info("Starting ThingsBoard Upgrade from version {} ...", upgradeFromVersion); switch (upgradeFromVersion) { - case "1.2.3": + case "1.2.3": //NOSONAR, Need to execute gradual upgrade starting from upgradeFromVersion log.info("Upgrading ThingsBoard from version 1.2.3 to 1.3.0 ..."); databaseUpgradeService.upgradeDatabase(upgradeFromVersion); @@ -115,7 +114,7 @@ public class ThingsboardInstallService { if (this.dataDir == null) { throw new RuntimeException("'install.data_dir' property should specified!"); } - if (!Files.isDirectory(Paths.get(this.dataDir))) { + if (!Paths.get(this.dataDir).toFile().isDirectory()) { throw new RuntimeException("'install.data_dir' property value is not a valid directory!"); } diff --git a/application/src/main/java/org/thingsboard/server/service/cluster/discovery/DummyDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/cluster/discovery/DummyDiscoveryService.java index 3448f5d043..af35af6e4c 100644 --- a/application/src/main/java/org/thingsboard/server/service/cluster/discovery/DummyDiscoveryService.java +++ b/application/src/main/java/org/thingsboard/server/service/cluster/discovery/DummyDiscoveryService.java @@ -45,12 +45,12 @@ public class DummyDiscoveryService implements DiscoveryService { @Override public void publishCurrentServer() { - + //Do nothing } @Override public void unpublishCurrentServer() { - + //Do nothing } @Override diff --git a/application/src/main/java/org/thingsboard/server/service/cluster/discovery/ZkDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/cluster/discovery/ZkDiscoveryService.java index ac5d61195a..a08fb77805 100644 --- a/application/src/main/java/org/thingsboard/server/service/cluster/discovery/ZkDiscoveryService.java +++ b/application/src/main/java/org/thingsboard/server/service/cluster/discovery/ZkDiscoveryService.java @@ -202,6 +202,8 @@ public class ZkDiscoveryService implements DiscoveryService, PathChildrenCacheLi case CHILD_REMOVED: listeners.forEach(listener -> listener.onServerRemoved(instance)); break; + default: + break; } } } diff --git a/application/src/main/java/org/thingsboard/server/service/cluster/rpc/ClusterGrpcService.java b/application/src/main/java/org/thingsboard/server/service/cluster/rpc/ClusterGrpcService.java index f8dea4d6e8..b22fd7e380 100644 --- a/application/src/main/java/org/thingsboard/server/service/cluster/rpc/ClusterGrpcService.java +++ b/application/src/main/java/org/thingsboard/server/service/cluster/rpc/ClusterGrpcService.java @@ -95,6 +95,7 @@ public class ClusterGrpcService extends ClusterRpcServiceGrpc.ClusterRpcServiceI future.onMsg(msg); } catch (InterruptedException e) { log.warn("Failed to report created session!"); + Thread.currentThread().interrupt(); } } else { log.warn("Failed to lookup pending session!"); @@ -117,6 +118,7 @@ public class ClusterGrpcService extends ClusterRpcServiceGrpc.ClusterRpcServiceI log.info("RPC server stopped!"); } catch (InterruptedException e) { log.warn("Failed to onStop RPC server!"); + Thread.currentThread().interrupt(); } } } diff --git a/application/src/main/java/org/thingsboard/server/service/cluster/rpc/GrpcSession.java b/application/src/main/java/org/thingsboard/server/service/cluster/rpc/GrpcSession.java index 68639748c5..ded34cecfa 100644 --- a/application/src/main/java/org/thingsboard/server/service/cluster/rpc/GrpcSession.java +++ b/application/src/main/java/org/thingsboard/server/service/cluster/rpc/GrpcSession.java @@ -29,7 +29,7 @@ import java.util.UUID; */ @Data @Slf4j -final public class GrpcSession implements Closeable { +public final class GrpcSession implements Closeable { private final UUID sessionId; private final boolean client; private final GrpcSessionListener listener; @@ -59,36 +59,14 @@ final public class GrpcSession implements Closeable { this.inputStream = new StreamObserver() { @Override public void onNext(ClusterAPIProtos.ToRpcServerMessage msg) { - if (!connected) { - if (msg.hasConnectMsg()) { - connected = true; - ClusterAPIProtos.ServerAddress rpcAddress = msg.getConnectMsg().getServerAddress(); - remoteServer = new ServerAddress(rpcAddress.getHost(), rpcAddress.getPort()); - listener.onConnected(GrpcSession.this); - } + if (!connected && msg.hasConnectMsg()) { + connected = true; + ClusterAPIProtos.ServerAddress rpcAddress = msg.getConnectMsg().getServerAddress(); + remoteServer = new ServerAddress(rpcAddress.getHost(), rpcAddress.getPort()); + listener.onConnected(GrpcSession.this); } if (connected) { - if (msg.hasToPluginRpcMsg()) { - listener.onToPluginRpcMsg(GrpcSession.this, msg.getToPluginRpcMsg()); - } - if (msg.hasToDeviceActorRpcMsg()) { - listener.onToDeviceActorRpcMsg(GrpcSession.this, msg.getToDeviceActorRpcMsg()); - } - if (msg.hasToDeviceSessionActorRpcMsg()) { - listener.onToDeviceSessionActorRpcMsg(GrpcSession.this, msg.getToDeviceSessionActorRpcMsg()); - } - if (msg.hasToDeviceActorNotificationRpcMsg()) { - listener.onToDeviceActorNotificationRpcMsg(GrpcSession.this, msg.getToDeviceActorNotificationRpcMsg()); - } - if (msg.hasToDeviceRpcRequestRpcMsg()) { - listener.onToDeviceRpcRequestRpcMsg(GrpcSession.this, msg.getToDeviceRpcRequestRpcMsg()); - } - if (msg.hasToPluginRpcResponseRpcMsg()) { - listener.onFromDeviceRpcResponseRpcMsg(GrpcSession.this, msg.getToPluginRpcResponseRpcMsg()); - } - if (msg.hasToAllNodesRpcMsg()) { - listener.onToAllNodesRpcMessage(GrpcSession.this, msg.getToAllNodesRpcMsg()); - } + handleToRpcServerMessage(msg); } } @@ -105,6 +83,30 @@ final public class GrpcSession implements Closeable { }; } + private void handleToRpcServerMessage(ClusterAPIProtos.ToRpcServerMessage msg) { + if (msg.hasToPluginRpcMsg()) { + listener.onToPluginRpcMsg(GrpcSession.this, msg.getToPluginRpcMsg()); + } + if (msg.hasToDeviceActorRpcMsg()) { + listener.onToDeviceActorRpcMsg(GrpcSession.this, msg.getToDeviceActorRpcMsg()); + } + if (msg.hasToDeviceSessionActorRpcMsg()) { + listener.onToDeviceSessionActorRpcMsg(GrpcSession.this, msg.getToDeviceSessionActorRpcMsg()); + } + if (msg.hasToDeviceActorNotificationRpcMsg()) { + listener.onToDeviceActorNotificationRpcMsg(GrpcSession.this, msg.getToDeviceActorNotificationRpcMsg()); + } + if (msg.hasToDeviceRpcRequestRpcMsg()) { + listener.onToDeviceRpcRequestRpcMsg(GrpcSession.this, msg.getToDeviceRpcRequestRpcMsg()); + } + if (msg.hasToPluginRpcResponseRpcMsg()) { + listener.onFromDeviceRpcResponseRpcMsg(GrpcSession.this, msg.getToPluginRpcResponseRpcMsg()); + } + if (msg.hasToAllNodesRpcMsg()) { + listener.onToAllNodesRpcMessage(GrpcSession.this, msg.getToAllNodesRpcMsg()); + } + } + public void initOutputStream() { if (client) { listener.onConnected(GrpcSession.this); diff --git a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java index 1b6d5fd7fd..a8f9fc3e2e 100644 --- a/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java +++ b/application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java @@ -79,78 +79,83 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe private List persist(Set filterDefs, ComponentType type) { List result = new ArrayList<>(); for (BeanDefinition def : filterDefs) { - ComponentDescriptor scannedComponent = new ComponentDescriptor(); - String clazzName = def.getBeanClassName(); - try { - scannedComponent.setType(type); - Class clazz = Class.forName(clazzName); - String descriptorResourceName; - switch (type) { - case FILTER: - Filter filterAnnotation = clazz.getAnnotation(Filter.class); - scannedComponent.setName(filterAnnotation.name()); - scannedComponent.setScope(filterAnnotation.scope()); - descriptorResourceName = filterAnnotation.descriptor(); - break; - case PROCESSOR: - Processor processorAnnotation = clazz.getAnnotation(Processor.class); - scannedComponent.setName(processorAnnotation.name()); - scannedComponent.setScope(processorAnnotation.scope()); - descriptorResourceName = processorAnnotation.descriptor(); - break; - case ACTION: - Action actionAnnotation = clazz.getAnnotation(Action.class); - scannedComponent.setName(actionAnnotation.name()); - scannedComponent.setScope(actionAnnotation.scope()); - descriptorResourceName = actionAnnotation.descriptor(); - break; - case PLUGIN: - Plugin pluginAnnotation = clazz.getAnnotation(Plugin.class); - scannedComponent.setName(pluginAnnotation.name()); - scannedComponent.setScope(pluginAnnotation.scope()); - descriptorResourceName = pluginAnnotation.descriptor(); - for (Class actionClazz : pluginAnnotation.actions()) { - ComponentDescriptor actionComponent = getComponent(actionClazz.getName()) - .orElseThrow(() -> { - log.error("Can't initialize plugin {}, due to missing action {}!", def.getBeanClassName(), actionClazz.getName()); - return new ClassNotFoundException("Action: " + actionClazz.getName() + "is missing!"); - }); - if (actionComponent.getType() != ComponentType.ACTION) { - log.error("Plugin {} action {} has wrong component type!", def.getBeanClassName(), actionClazz.getName(), actionComponent.getType()); - throw new RuntimeException("Plugin " + def.getBeanClassName() + "action " + actionClazz.getName() + " has wrong component type!"); - } - } - scannedComponent.setActions(Arrays.stream(pluginAnnotation.actions()).map(action -> action.getName()).collect(Collectors.joining(","))); - break; - default: - throw new RuntimeException(type + " is not supported yet!"); - } - scannedComponent.setConfigurationDescriptor(mapper.readTree( - Resources.toString(Resources.getResource(descriptorResourceName), Charsets.UTF_8))); - scannedComponent.setClazz(clazzName); - log.info("Processing scanned component: {}", scannedComponent); - } catch (Exception e) { - log.error("Can't initialize component {}, due to {}", def.getBeanClassName(), e.getMessage(), e); - throw new RuntimeException(e); - } - ComponentDescriptor persistedComponent = componentDescriptorService.findByClazz(clazzName); - if (persistedComponent == null) { - log.info("Persisting new component: {}", scannedComponent); - scannedComponent = componentDescriptorService.saveComponent(scannedComponent); - } else if (scannedComponent.equals(persistedComponent)) { - log.info("Component is already persisted: {}", persistedComponent); - scannedComponent = persistedComponent; - } else { - log.info("Component {} will be updated to {}", persistedComponent, scannedComponent); - componentDescriptorService.deleteByClazz(persistedComponent.getClazz()); - scannedComponent.setId(persistedComponent.getId()); - scannedComponent = componentDescriptorService.saveComponent(scannedComponent); - } + ComponentDescriptor scannedComponent = scanAndPersistComponent(def, type); result.add(scannedComponent); } return result; } + private ComponentDescriptor scanAndPersistComponent(BeanDefinition def, ComponentType type) { + ComponentDescriptor scannedComponent = new ComponentDescriptor(); + String clazzName = def.getBeanClassName(); + try { + scannedComponent.setType(type); + Class clazz = Class.forName(clazzName); + String descriptorResourceName; + switch (type) { + case FILTER: + Filter filterAnnotation = clazz.getAnnotation(Filter.class); + scannedComponent.setName(filterAnnotation.name()); + scannedComponent.setScope(filterAnnotation.scope()); + descriptorResourceName = filterAnnotation.descriptor(); + break; + case PROCESSOR: + Processor processorAnnotation = clazz.getAnnotation(Processor.class); + scannedComponent.setName(processorAnnotation.name()); + scannedComponent.setScope(processorAnnotation.scope()); + descriptorResourceName = processorAnnotation.descriptor(); + break; + case ACTION: + Action actionAnnotation = clazz.getAnnotation(Action.class); + scannedComponent.setName(actionAnnotation.name()); + scannedComponent.setScope(actionAnnotation.scope()); + descriptorResourceName = actionAnnotation.descriptor(); + break; + case PLUGIN: + Plugin pluginAnnotation = clazz.getAnnotation(Plugin.class); + scannedComponent.setName(pluginAnnotation.name()); + scannedComponent.setScope(pluginAnnotation.scope()); + descriptorResourceName = pluginAnnotation.descriptor(); + for (Class actionClazz : pluginAnnotation.actions()) { + ComponentDescriptor actionComponent = getComponent(actionClazz.getName()) + .orElseThrow(() -> { + log.error("Can't initialize plugin {}, due to missing action {}!", def.getBeanClassName(), actionClazz.getName()); + return new ClassNotFoundException("Action: " + actionClazz.getName() + "is missing!"); + }); + if (actionComponent.getType() != ComponentType.ACTION) { + log.error("Plugin {} action {} has wrong component type!", def.getBeanClassName(), actionClazz.getName(), actionComponent.getType()); + throw new RuntimeException("Plugin " + def.getBeanClassName() + "action " + actionClazz.getName() + " has wrong component type!"); + } + } + scannedComponent.setActions(Arrays.stream(pluginAnnotation.actions()).map(action -> action.getName()).collect(Collectors.joining(","))); + break; + default: + throw new RuntimeException(type + " is not supported yet!"); + } + scannedComponent.setConfigurationDescriptor(mapper.readTree( + Resources.toString(Resources.getResource(descriptorResourceName), Charsets.UTF_8))); + scannedComponent.setClazz(clazzName); + log.info("Processing scanned component: {}", scannedComponent); + } catch (Exception e) { + log.error("Can't initialize component {}, due to {}", def.getBeanClassName(), e.getMessage(), e); + throw new RuntimeException(e); + } + ComponentDescriptor persistedComponent = componentDescriptorService.findByClazz(clazzName); + if (persistedComponent == null) { + log.info("Persisting new component: {}", scannedComponent); + scannedComponent = componentDescriptorService.saveComponent(scannedComponent); + } else if (scannedComponent.equals(persistedComponent)) { + log.info("Component is already persisted: {}", persistedComponent); + scannedComponent = persistedComponent; + } else { + log.info("Component {} will be updated to {}", persistedComponent, scannedComponent); + componentDescriptorService.deleteByClazz(persistedComponent.getClazz()); + scannedComponent.setId(persistedComponent.getId()); + scannedComponent = componentDescriptorService.saveComponent(scannedComponent); + } + return scannedComponent; + } + private Set getBeanDefinitions(Class componentType) { ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false); scanner.addIncludeFilter(new AnnotationTypeFilter(componentType)); diff --git a/application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseUpgradeService.java index 83f1435378..5abc789446 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseUpgradeService.java @@ -40,6 +40,12 @@ import java.util.List; public class CassandraDatabaseUpgradeService implements DatabaseUpgradeService { private static final String SCHEMA_UPDATE_CQL = "schema_update.cql"; + public static final String DEVICE = "device"; + public static final String TENANT_ID = "tenant_id"; + public static final String CUSTOMER_ID = "customer_id"; + public static final String SEARCH_TEXT = "search_text"; + public static final String ADDITIONAL_INFO = "additional_info"; + public static final String ASSET = "asset"; @Value("${install.data_dir}") private String dataDir; @@ -63,22 +69,22 @@ public class CassandraDatabaseUpgradeService implements DatabaseUpgradeService { KeyspaceMetadata ks = cluster.getCluster().getMetadata().getKeyspace(cluster.getKeyspaceName()); log.info("Dumping devices ..."); - Path devicesDump = CassandraDbHelper.dumpCfIfExists(ks, cluster.getSession(), "device", - new String[]{"id", "tenant_id", "customer_id", "name", "search_text", "additional_info", "type"}, + Path devicesDump = CassandraDbHelper.dumpCfIfExists(ks, cluster.getSession(), DEVICE, + new String[]{"id", TENANT_ID, CUSTOMER_ID, "name", SEARCH_TEXT, ADDITIONAL_INFO, "type"}, new String[]{"", "", "", "", "", "", "default"}, "tb-devices"); log.info("Devices dumped."); log.info("Dumping assets ..."); - Path assetsDump = CassandraDbHelper.dumpCfIfExists(ks, cluster.getSession(), "asset", - new String[]{"id", "tenant_id", "customer_id", "name", "search_text", "additional_info", "type"}, + Path assetsDump = CassandraDbHelper.dumpCfIfExists(ks, cluster.getSession(), ASSET, + new String[]{"id", TENANT_ID, CUSTOMER_ID, "name", SEARCH_TEXT, ADDITIONAL_INFO, "type"}, new String[]{"", "", "", "", "", "", "default"}, "tb-assets"); log.info("Assets dumped."); log.info("Dumping relations ..."); Path relationsDump = CassandraDbHelper.dumpCfIfExists(ks, cluster.getSession(), "relation", - new String[]{"from_id", "from_type", "to_id", "to_type", "relation_type", "additional_info", "relation_type_group"}, + new String[]{"from_id", "from_type", "to_id", "to_type", "relation_type", ADDITIONAL_INFO, "relation_type_group"}, new String[]{"", "", "", "", "", "", "COMMON"}, "tb-relations"); log.info("Relations dumped."); @@ -92,15 +98,15 @@ public class CassandraDatabaseUpgradeService implements DatabaseUpgradeService { log.info("Restoring devices ..."); if (devicesDump != null) { - CassandraDbHelper.loadCf(ks, cluster.getSession(), "device", - new String[]{"id", "tenant_id", "customer_id", "name", "search_text", "additional_info", "type"}, devicesDump); + CassandraDbHelper.loadCf(ks, cluster.getSession(), DEVICE, + new String[]{"id", TENANT_ID, CUSTOMER_ID, "name", SEARCH_TEXT, ADDITIONAL_INFO, "type"}, devicesDump); Files.deleteIfExists(devicesDump); } log.info("Devices restored."); log.info("Dumping device types ..."); - Path deviceTypesDump = CassandraDbHelper.dumpCfIfExists(ks, cluster.getSession(), "device", - new String[]{"tenant_id", "type"}, + Path deviceTypesDump = CassandraDbHelper.dumpCfIfExists(ks, cluster.getSession(), DEVICE, + new String[]{TENANT_ID, "type"}, new String[]{"", ""}, "tb-device-types"); if (deviceTypesDump != null) { @@ -110,22 +116,22 @@ public class CassandraDatabaseUpgradeService implements DatabaseUpgradeService { log.info("Loading device types ..."); if (deviceTypesDump != null) { CassandraDbHelper.loadCf(ks, cluster.getSession(), "entity_subtype", - new String[]{"tenant_id", "type", "entity_type"}, deviceTypesDump); + new String[]{TENANT_ID, "type", "entity_type"}, deviceTypesDump); Files.deleteIfExists(deviceTypesDump); } log.info("Device types loaded."); log.info("Restoring assets ..."); if (assetsDump != null) { - CassandraDbHelper.loadCf(ks, cluster.getSession(), "asset", - new String[]{"id", "tenant_id", "customer_id", "name", "search_text", "additional_info", "type"}, assetsDump); + CassandraDbHelper.loadCf(ks, cluster.getSession(), ASSET, + new String[]{"id", TENANT_ID, CUSTOMER_ID, "name", SEARCH_TEXT, ADDITIONAL_INFO, "type"}, assetsDump); Files.deleteIfExists(assetsDump); } log.info("Assets restored."); log.info("Dumping asset types ..."); - Path assetTypesDump = CassandraDbHelper.dumpCfIfExists(ks, cluster.getSession(), "asset", - new String[]{"tenant_id", "type"}, + Path assetTypesDump = CassandraDbHelper.dumpCfIfExists(ks, cluster.getSession(), ASSET, + new String[]{TENANT_ID, "type"}, new String[]{"", ""}, "tb-asset-types"); if (assetTypesDump != null) { @@ -135,7 +141,7 @@ public class CassandraDatabaseUpgradeService implements DatabaseUpgradeService { log.info("Loading asset types ..."); if (assetTypesDump != null) { CassandraDbHelper.loadCf(ks, cluster.getSession(), "entity_subtype", - new String[]{"tenant_id", "type", "entity_type"}, assetTypesDump); + new String[]{TENANT_ID, "type", "entity_type"}, assetTypesDump); Files.deleteIfExists(assetTypesDump); } log.info("Asset types loaded."); @@ -143,7 +149,7 @@ public class CassandraDatabaseUpgradeService implements DatabaseUpgradeService { log.info("Restoring relations ..."); if (relationsDump != null) { CassandraDbHelper.loadCf(ks, cluster.getSession(), "relation", - new String[]{"from_id", "from_type", "to_id", "to_type", "relation_type", "additional_info", "relation_type_group"}, relationsDump); + new String[]{"from_id", "from_type", "to_id", "to_type", "relation_type", ADDITIONAL_INFO, "relation_type_group"}, relationsDump); Files.deleteIfExists(relationsDump); } log.info("Relations restored."); diff --git a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java index 1da39ab4f7..4e81f94419 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java @@ -51,6 +51,7 @@ import org.thingsboard.server.dao.widget.WidgetTypeService; import org.thingsboard.server.dao.widget.WidgetsBundleService; import java.io.IOException; +import java.nio.file.DirectoryStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -69,6 +70,9 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { private static final String DASHBOARDS_DIR = "dashboards"; private static final ObjectMapper objectMapper = new ObjectMapper(); + public static final String JSON_EXT = ".json"; + public static final String CUSTOMER_CRED = "customer"; + public static final String DEFAULT_DEVICE_TYPE = "default"; @Value("${install.data_dir}") private String dataDir; @@ -138,7 +142,7 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { node.put("timeout", "10000"); node.put("enableTls", "false"); node.put("username", ""); - node.put("password", ""); + node.put("password", ""); //NOSONAR, key used to identify password field (not password value itself) mailSettings.setJsonValue(node); adminSettingsService.saveAdminSettings(mailSettings); } @@ -146,33 +150,34 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { @Override public void loadSystemWidgets() throws Exception { Path widgetBundlesDir = Paths.get(dataDir, JSON_DIR, SYSTEM_DIR, WIDGET_BUNDLES_DIR); - Files.newDirectoryStream(widgetBundlesDir, path -> path.toString().endsWith(".json")) - .forEach( - path -> { - try { - JsonNode widgetsBundleDescriptorJson = objectMapper.readTree(path.toFile()); - JsonNode widgetsBundleJson = widgetsBundleDescriptorJson.get("widgetsBundle"); - WidgetsBundle widgetsBundle = objectMapper.treeToValue(widgetsBundleJson, WidgetsBundle.class); - WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); - JsonNode widgetTypesArrayJson = widgetsBundleDescriptorJson.get("widgetTypes"); - widgetTypesArrayJson.forEach( - widgetTypeJson -> { - try { - WidgetType widgetType = objectMapper.treeToValue(widgetTypeJson, WidgetType.class); - widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); - widgetTypeService.saveWidgetType(widgetType); - } catch (Exception e) { - log.error("Unable to load widget type from json: [{}]", path.toString()); - throw new RuntimeException("Unable to load widget type from json", e); - } + try (DirectoryStream dirStream = Files.newDirectoryStream(widgetBundlesDir, path -> path.toString().endsWith(JSON_EXT))) { + dirStream.forEach( + path -> { + try { + JsonNode widgetsBundleDescriptorJson = objectMapper.readTree(path.toFile()); + JsonNode widgetsBundleJson = widgetsBundleDescriptorJson.get("widgetsBundle"); + WidgetsBundle widgetsBundle = objectMapper.treeToValue(widgetsBundleJson, WidgetsBundle.class); + WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); + JsonNode widgetTypesArrayJson = widgetsBundleDescriptorJson.get("widgetTypes"); + widgetTypesArrayJson.forEach( + widgetTypeJson -> { + try { + WidgetType widgetType = objectMapper.treeToValue(widgetTypeJson, WidgetType.class); + widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); + widgetTypeService.saveWidgetType(widgetType); + } catch (Exception e) { + log.error("Unable to load widget type from json: [{}]", path.toString()); + throw new RuntimeException("Unable to load widget type from json", e); } - ); - } catch (Exception e) { - log.error("Unable to load widgets bundle from json: [{}]", path.toString()); - throw new RuntimeException("Unable to load widgets bundle from json", e); - } + } + ); + } catch (Exception e) { + log.error("Unable to load widgets bundle from json: [{}]", path.toString()); + throw new RuntimeException("Unable to load widgets bundle from json", e); } - ); + } + ); + } } @Override @@ -206,21 +211,21 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { customerC.setTenantId(demoTenant.getId()); customerC.setTitle("Customer C"); customerC = customerService.saveCustomer(customerC); - createUser(Authority.CUSTOMER_USER, demoTenant.getId(), customerA.getId(), "customer@thingsboard.org", "customer"); - createUser(Authority.CUSTOMER_USER, demoTenant.getId(), customerA.getId(), "customerA@thingsboard.org", "customer"); - createUser(Authority.CUSTOMER_USER, demoTenant.getId(), customerB.getId(), "customerB@thingsboard.org", "customer"); - createUser(Authority.CUSTOMER_USER, demoTenant.getId(), customerC.getId(), "customerC@thingsboard.org", "customer"); - - createDevice(demoTenant.getId(), customerA.getId(), "default", "Test Device A1", "A1_TEST_TOKEN", null); - createDevice(demoTenant.getId(), customerA.getId(), "default", "Test Device A2", "A2_TEST_TOKEN", null); - createDevice(demoTenant.getId(), customerA.getId(), "default", "Test Device A3", "A3_TEST_TOKEN", null); - createDevice(demoTenant.getId(), customerB.getId(), "default", "Test Device B1", "B1_TEST_TOKEN", null); - createDevice(demoTenant.getId(), customerC.getId(), "default", "Test Device C1", "C1_TEST_TOKEN", null); - - createDevice(demoTenant.getId(), null, "default", "DHT11 Demo Device", "DHT11_DEMO_TOKEN", "Demo device that is used in sample " + + createUser(Authority.CUSTOMER_USER, demoTenant.getId(), customerA.getId(), "customer@thingsboard.org", CUSTOMER_CRED); + createUser(Authority.CUSTOMER_USER, demoTenant.getId(), customerA.getId(), "customerA@thingsboard.org", CUSTOMER_CRED); + createUser(Authority.CUSTOMER_USER, demoTenant.getId(), customerB.getId(), "customerB@thingsboard.org", CUSTOMER_CRED); + createUser(Authority.CUSTOMER_USER, demoTenant.getId(), customerC.getId(), "customerC@thingsboard.org", CUSTOMER_CRED); + + createDevice(demoTenant.getId(), customerA.getId(), DEFAULT_DEVICE_TYPE, "Test Device A1", "A1_TEST_TOKEN", null); + createDevice(demoTenant.getId(), customerA.getId(), DEFAULT_DEVICE_TYPE, "Test Device A2", "A2_TEST_TOKEN", null); + createDevice(demoTenant.getId(), customerA.getId(), DEFAULT_DEVICE_TYPE, "Test Device A3", "A3_TEST_TOKEN", null); + createDevice(demoTenant.getId(), customerB.getId(), DEFAULT_DEVICE_TYPE, "Test Device B1", "B1_TEST_TOKEN", null); + createDevice(demoTenant.getId(), customerC.getId(), DEFAULT_DEVICE_TYPE, "Test Device C1", "C1_TEST_TOKEN", null); + + createDevice(demoTenant.getId(), null, DEFAULT_DEVICE_TYPE, "DHT11 Demo Device", "DHT11_DEMO_TOKEN", "Demo device that is used in sample " + "applications that upload data from DHT11 temperature and humidity sensor"); - createDevice(demoTenant.getId(), null, "default", "Raspberry Pi Demo Device", "RASPBERRY_PI_DEMO_TOKEN", "Demo device that is used in " + + createDevice(demoTenant.getId(), null, DEFAULT_DEVICE_TYPE, "Raspberry Pi Demo Device", "RASPBERRY_PI_DEMO_TOKEN", "Demo device that is used in " + "Raspberry Pi GPIO control sample application"); loadPlugins(Paths.get(dataDir, JSON_DIR, DEMO_DIR, PLUGINS_DIR), demoTenant.getId()); @@ -279,67 +284,69 @@ public class DefaultSystemDataLoaderService implements SystemDataLoaderService { } private void loadPlugins(Path pluginsDir, TenantId tenantId) throws Exception{ - Files.newDirectoryStream(pluginsDir, path -> path.toString().endsWith(".json")) - .forEach( - path -> { - try { - JsonNode pluginJson = objectMapper.readTree(path.toFile()); - PluginMetaData plugin = objectMapper.treeToValue(pluginJson, PluginMetaData.class); - plugin.setTenantId(tenantId); - if (plugin.getState() == ComponentLifecycleState.ACTIVE) { - plugin.setState(ComponentLifecycleState.SUSPENDED); - PluginMetaData savedPlugin = pluginService.savePlugin(plugin); - pluginService.activatePluginById(savedPlugin.getId()); - } else { - pluginService.savePlugin(plugin); - } - } catch (Exception e) { - log.error("Unable to load plugin from json: [{}]", path.toString()); - throw new RuntimeException("Unable to load plugin from json", e); + try (DirectoryStream dirStream = Files.newDirectoryStream(pluginsDir, path -> path.toString().endsWith(JSON_EXT))) { + dirStream.forEach( + path -> { + try { + JsonNode pluginJson = objectMapper.readTree(path.toFile()); + PluginMetaData plugin = objectMapper.treeToValue(pluginJson, PluginMetaData.class); + plugin.setTenantId(tenantId); + if (plugin.getState() == ComponentLifecycleState.ACTIVE) { + plugin.setState(ComponentLifecycleState.SUSPENDED); + PluginMetaData savedPlugin = pluginService.savePlugin(plugin); + pluginService.activatePluginById(savedPlugin.getId()); + } else { + pluginService.savePlugin(plugin); } + } catch (Exception e) { + log.error("Unable to load plugin from json: [{}]", path.toString()); + throw new RuntimeException("Unable to load plugin from json", e); } - ); - + } + ); + } } private void loadRules(Path rulesDir, TenantId tenantId) throws Exception { - Files.newDirectoryStream(rulesDir, path -> path.toString().endsWith(".json")) - .forEach( - path -> { - try { - JsonNode ruleJson = objectMapper.readTree(path.toFile()); - RuleMetaData rule = objectMapper.treeToValue(ruleJson, RuleMetaData.class); - rule.setTenantId(tenantId); - if (rule.getState() == ComponentLifecycleState.ACTIVE) { - rule.setState(ComponentLifecycleState.SUSPENDED); - RuleMetaData savedRule = ruleService.saveRule(rule); - ruleService.activateRuleById(savedRule.getId()); - } else { - ruleService.saveRule(rule); - } - } catch (Exception e) { - log.error("Unable to load rule from json: [{}]", path.toString()); - throw new RuntimeException("Unable to load rule from json", e); + try (DirectoryStream dirStream = Files.newDirectoryStream(rulesDir, path -> path.toString().endsWith(JSON_EXT))) { + dirStream.forEach( + path -> { + try { + JsonNode ruleJson = objectMapper.readTree(path.toFile()); + RuleMetaData rule = objectMapper.treeToValue(ruleJson, RuleMetaData.class); + rule.setTenantId(tenantId); + if (rule.getState() == ComponentLifecycleState.ACTIVE) { + rule.setState(ComponentLifecycleState.SUSPENDED); + RuleMetaData savedRule = ruleService.saveRule(rule); + ruleService.activateRuleById(savedRule.getId()); + } else { + ruleService.saveRule(rule); } + } catch (Exception e) { + log.error("Unable to load rule from json: [{}]", path.toString()); + throw new RuntimeException("Unable to load rule from json", e); } - ); + } + ); + } } private void loadDashboards(Path dashboardsDir, TenantId tenantId, CustomerId customerId) throws Exception { - Files.newDirectoryStream(dashboardsDir, path -> path.toString().endsWith(".json")) - .forEach( - path -> { - try { - JsonNode dashboardJson = objectMapper.readTree(path.toFile()); - Dashboard dashboard = objectMapper.treeToValue(dashboardJson, Dashboard.class); - dashboard.setTenantId(tenantId); - dashboard.setCustomerId(customerId); - dashboardService.saveDashboard(dashboard); - } catch (Exception e) { - log.error("Unable to load dashboard from json: [{}]", path.toString()); - throw new RuntimeException("Unable to load dashboard from json", e); - } + try (DirectoryStream dirStream = Files.newDirectoryStream(dashboardsDir, path -> path.toString().endsWith(JSON_EXT))) { + dirStream.forEach( + path -> { + try { + JsonNode dashboardJson = objectMapper.readTree(path.toFile()); + Dashboard dashboard = objectMapper.treeToValue(dashboardJson, Dashboard.class); + dashboard.setTenantId(tenantId); + dashboard.setCustomerId(customerId); + dashboardService.saveDashboard(dashboard); + } catch (Exception e) { + log.error("Unable to load dashboard from json: [{}]", path.toString()); + throw new RuntimeException("Unable to load dashboard from json", e); } - ); + } + ); + } } } diff --git a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseSchemaService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseSchemaService.java index 9d22776996..e0d6264b72 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseSchemaService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseSchemaService.java @@ -28,6 +28,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.sql.Connection; import java.sql.DriverManager; +import java.sql.PreparedStatement; @Service @Profile("install") @@ -58,7 +59,7 @@ public class SqlDatabaseSchemaService implements DatabaseSchemaService { Path schemaFile = Paths.get(this.dataDir, SQL_DIR, SCHEMA_SQL); try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword)) { String sql = new String(Files.readAllBytes(schemaFile), Charset.forName("UTF-8")); - conn.createStatement().execute(sql); + conn.prepareStatement(sql).execute(); //NOSONAR, ignoring because method used to load initial thingsboard database schema } } diff --git a/application/src/main/java/org/thingsboard/server/service/install/cql/CQLStatementsParser.java b/application/src/main/java/org/thingsboard/server/service/install/cql/CQLStatementsParser.java index 6caa76754f..c68ebf3d29 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/cql/CQLStatementsParser.java +++ b/application/src/main/java/org/thingsboard/server/service/install/cql/CQLStatementsParser.java @@ -44,7 +44,7 @@ public class CQLStatementsParser { public CQLStatementsParser(Path cql) throws IOException { try { List lines = Files.readAllLines(cql); - StringBuffer t = new StringBuffer(); + StringBuilder t = new StringBuilder(); for (String l : lines) { t.append(l.trim()); t.append('\n'); @@ -68,36 +68,14 @@ public class CQLStatementsParser { private void parseStatements() { this.statements = new ArrayList<>(); - StringBuffer statementUnderConstruction = new StringBuffer(); + StringBuilder statementUnderConstruction = new StringBuilder(); char c; while ((c = getChar()) != 0) { switch (state) { case DEFAULT: - if (c == '/' && peekAhead() == '/') { - state = State.INSINGLELINECOMMENT; - advance(); - } else if (c == '-' && peekAhead() == '-') { - state = State.INSINGLELINECOMMENT; - advance(); - } else if (c == '/' && peekAhead() == '*') { - state = State.INMULTILINECOMMENT; - advance(); - } else if (c == '\n') { - statementUnderConstruction.append(' '); - } else { - statementUnderConstruction.append(c); - if (c == '\"') { - state = State.INQUOTESTRING; - } else if (c == '\'') { - state = State.INSQUOTESTRING; - } else if (c == ';') { - statements.add(statementUnderConstruction.toString().trim()); - statementUnderConstruction.setLength(0); - } - } + processDefaultState(c, statementUnderConstruction); break; - case INSINGLELINECOMMENT: if (c == '\n') { state = State.DEFAULT; @@ -112,25 +90,10 @@ public class CQLStatementsParser { break; case INQUOTESTRING: - statementUnderConstruction.append(c); - if (c == '"') { - if (peekAhead() == '"') { - statementUnderConstruction.append(getChar()); - } else { - state = State.DEFAULT; - } - } + processInQuoteStringState(c, statementUnderConstruction); break; - case INSQUOTESTRING: - statementUnderConstruction.append(c); - if (c == '\'') { - if (peekAhead() == '\'') { - statementUnderConstruction.append(getChar()); - } else { - state = State.DEFAULT; - } - } + processInSQuoteStringState(c, statementUnderConstruction); break; } @@ -141,6 +104,50 @@ public class CQLStatementsParser { } } + private void processDefaultState(char c, StringBuilder statementUnderConstruction) { + if ((c == '/' && peekAhead() == '/') || (c == '-' && peekAhead() == '-')) { + state = State.INSINGLELINECOMMENT; + advance(); + } else if (c == '/' && peekAhead() == '*') { + state = State.INMULTILINECOMMENT; + advance(); + } else if (c == '\n') { + statementUnderConstruction.append(' '); + } else { + statementUnderConstruction.append(c); + if (c == '\"') { + state = State.INQUOTESTRING; + } else if (c == '\'') { + state = State.INSQUOTESTRING; + } else if (c == ';') { + statements.add(statementUnderConstruction.toString().trim()); + statementUnderConstruction.setLength(0); + } + } + } + + private void processInQuoteStringState(char c, StringBuilder statementUnderConstruction) { + statementUnderConstruction.append(c); + if (c == '"') { + if (peekAhead() == '"') { + statementUnderConstruction.append(getChar()); + } else { + state = State.DEFAULT; + } + } + } + + private void processInSQuoteStringState(char c, StringBuilder statementUnderConstruction) { + statementUnderConstruction.append(c); + if (c == '\'') { + if (peekAhead() == '\'') { + statementUnderConstruction.append(getChar()); + } else { + state = State.DEFAULT; + } + } + } + private char getChar() { if (pos < text.length()) return text.charAt(pos++); diff --git a/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java b/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java index f4dfb096e3..c069ba637f 100644 --- a/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java +++ b/application/src/main/java/org/thingsboard/server/service/mail/DefaultMailService.java @@ -44,6 +44,9 @@ import java.util.Properties; @Slf4j public class DefaultMailService implements MailService { + public static final String MAIL_PROP = "mail."; + public static final String TARGET_EMAIL = "targetEmail"; + public static final String UTF_8 = "UTF-8"; @Autowired private MessageSource messages; @@ -89,11 +92,11 @@ public class DefaultMailService implements MailService { Properties javaMailProperties = new Properties(); String protocol = jsonConfig.get("smtpProtocol").asText(); javaMailProperties.put("mail.transport.protocol", protocol); - javaMailProperties.put("mail." + protocol + ".host", jsonConfig.get("smtpHost").asText()); - javaMailProperties.put("mail." + protocol + ".port", jsonConfig.get("smtpPort").asText()); - javaMailProperties.put("mail." + protocol + ".timeout", jsonConfig.get("timeout").asText()); - javaMailProperties.put("mail." + protocol + ".auth", String.valueOf(StringUtils.isNotEmpty(jsonConfig.get("username").asText()))); - javaMailProperties.put("mail." + protocol + ".starttls.enable", jsonConfig.get("enableTls")); + javaMailProperties.put(MAIL_PROP + protocol + ".host", jsonConfig.get("smtpHost").asText()); + javaMailProperties.put(MAIL_PROP + protocol + ".port", jsonConfig.get("smtpPort").asText()); + javaMailProperties.put(MAIL_PROP + protocol + ".timeout", jsonConfig.get("timeout").asText()); + javaMailProperties.put(MAIL_PROP + protocol + ".auth", String.valueOf(StringUtils.isNotEmpty(jsonConfig.get("username").asText()))); + javaMailProperties.put(MAIL_PROP + protocol + ".starttls.enable", jsonConfig.get("enableTls")); return javaMailProperties; } @@ -117,10 +120,10 @@ public class DefaultMailService implements MailService { String subject = messages.getMessage("test.message.subject", null, Locale.US); Map model = new HashMap(); - model.put("targetEmail", email); + model.put(TARGET_EMAIL, email); String message = VelocityEngineUtils.mergeTemplateIntoString(this.engine, - "test.vm", "UTF-8", model); + "test.vm", UTF_8, model); sendMail(testMailSender, mailFrom, email, subject, message); } @@ -132,10 +135,10 @@ public class DefaultMailService implements MailService { Map model = new HashMap(); model.put("activationLink", activationLink); - model.put("targetEmail", email); + model.put(TARGET_EMAIL, email); String message = VelocityEngineUtils.mergeTemplateIntoString(this.engine, - "activation.vm", "UTF-8", model); + "activation.vm", UTF_8, model); sendMail(mailSender, mailFrom, email, subject, message); } @@ -147,10 +150,10 @@ public class DefaultMailService implements MailService { Map model = new HashMap(); model.put("loginLink", loginLink); - model.put("targetEmail", email); + model.put(TARGET_EMAIL, email); String message = VelocityEngineUtils.mergeTemplateIntoString(this.engine, - "account.activated.vm", "UTF-8", model); + "account.activated.vm", UTF_8, model); sendMail(mailSender, mailFrom, email, subject, message); } @@ -162,10 +165,10 @@ public class DefaultMailService implements MailService { Map model = new HashMap(); model.put("passwordResetLink", passwordResetLink); - model.put("targetEmail", email); + model.put(TARGET_EMAIL, email); String message = VelocityEngineUtils.mergeTemplateIntoString(this.engine, - "reset.password.vm", "UTF-8", model); + "reset.password.vm", UTF_8, model); sendMail(mailSender, mailFrom, email, subject, message); } @@ -177,10 +180,10 @@ public class DefaultMailService implements MailService { Map model = new HashMap(); model.put("loginLink", loginLink); - model.put("targetEmail", email); + model.put(TARGET_EMAIL, email); String message = VelocityEngineUtils.mergeTemplateIntoString(this.engine, - "password.was.reset.vm", "UTF-8", model); + "password.was.reset.vm", UTF_8, model); sendMail(mailSender, mailFrom, email, subject, message); } @@ -191,7 +194,7 @@ public class DefaultMailService implements MailService { String subject, String message) throws ThingsboardException { try { MimeMessage mimeMsg = mailSender.createMimeMessage(); - MimeMessageHelper helper = new MimeMessageHelper(mimeMsg, "UTF-8"); + MimeMessageHelper helper = new MimeMessageHelper(mimeMsg, UTF_8); helper.setFrom(mailFrom); helper.setTo(email); helper.setSubject(subject); diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java index 9f261715d7..a0237123bd 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/RefreshTokenProcessingFilter.java @@ -16,6 +16,7 @@ package org.thingsboard.server.service.security.auth.jwt; import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,8 +38,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +@Slf4j public class RefreshTokenProcessingFilter extends AbstractAuthenticationProcessingFilter { - private static Logger logger = LoggerFactory.getLogger(RefreshTokenProcessingFilter.class); private final AuthenticationSuccessHandler successHandler; private final AuthenticationFailureHandler failureHandler; @@ -57,8 +58,8 @@ public class RefreshTokenProcessingFilter extends AbstractAuthenticationProcessi public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { if (!HttpMethod.POST.name().equals(request.getMethod())) { - if(logger.isDebugEnabled()) { - logger.debug("Authentication method not supported. Request method: " + request.getMethod()); + if(log.isDebugEnabled()) { + log.debug("Authentication method not supported. Request method: " + request.getMethod()); } throw new AuthMethodNotSupportedException("Authentication method not supported"); } diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java index 321792ab99..d16bd35c3b 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/jwt/extractor/JwtHeaderTokenExtractor.java @@ -24,7 +24,7 @@ import javax.servlet.http.HttpServletRequest; @Component(value="jwtHeaderTokenExtractor") public class JwtHeaderTokenExtractor implements TokenExtractor { - public static String HEADER_PREFIX = "Bearer "; + public static final String HEADER_PREFIX = "Bearer "; @Override public String extract(HttpServletRequest request) { diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java index c32b1f221e..c3c5f11ac5 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestLoginProcessingFilter.java @@ -16,6 +16,7 @@ package org.thingsboard.server.service.security.auth.rest; import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,8 +38,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +@Slf4j public class RestLoginProcessingFilter extends AbstractAuthenticationProcessingFilter { - private static Logger logger = LoggerFactory.getLogger(RestLoginProcessingFilter.class); private final AuthenticationSuccessHandler successHandler; private final AuthenticationFailureHandler failureHandler; @@ -57,8 +58,8 @@ public class RestLoginProcessingFilter extends AbstractAuthenticationProcessingF public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { if (!HttpMethod.POST.name().equals(request.getMethod())) { - if(logger.isDebugEnabled()) { - logger.debug("Authentication method not supported. Request method: " + request.getMethod()); + if(log.isDebugEnabled()) { + log.debug("Authentication method not supported. Request method: " + request.getMethod()); } throw new AuthMethodNotSupportedException("Authentication method not supported"); } diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java index 3a3b7cb2f1..707653fad4 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/rest/RestPublicLoginProcessingFilter.java @@ -16,6 +16,7 @@ package org.thingsboard.server.service.security.auth.rest; import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -37,8 +38,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +@Slf4j public class RestPublicLoginProcessingFilter extends AbstractAuthenticationProcessingFilter { - private static Logger logger = LoggerFactory.getLogger(RestPublicLoginProcessingFilter.class); private final AuthenticationSuccessHandler successHandler; private final AuthenticationFailureHandler failureHandler; @@ -57,8 +58,8 @@ public class RestPublicLoginProcessingFilter extends AbstractAuthenticationProce public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { if (!HttpMethod.POST.name().equals(request.getMethod())) { - if(logger.isDebugEnabled()) { - logger.debug("Authentication method not supported. Request method: " + request.getMethod()); + if(log.isDebugEnabled()) { + log.debug("Authentication method not supported. Request method: " + request.getMethod()); } throw new AuthMethodNotSupportedException("Authentication method not supported"); } diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/SecurityUser.java b/application/src/main/java/org/thingsboard/server/service/security/model/SecurityUser.java index 0839695261..7980ff04d8 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/SecurityUser.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/SecurityUser.java @@ -46,7 +46,7 @@ public class SecurityUser extends User { this.userPrincipal = userPrincipal; } - public Collection getAuthorities() { + public Collection getAuthorities() { if (authorities == null) { authorities = Stream.of(SecurityUser.this.getAuthority()) .map(authority -> new SimpleGrantedAuthority(authority.name())) diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/UserPrincipal.java b/application/src/main/java/org/thingsboard/server/service/security/model/UserPrincipal.java index 6f23783c0b..76e3185221 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/UserPrincipal.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/UserPrincipal.java @@ -16,7 +16,9 @@ package org.thingsboard.server.service.security.model; -public class UserPrincipal { +import java.io.Serializable; + +public class UserPrincipal implements Serializable { private final Type type; private final String value; diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/token/AccessJwtToken.java b/application/src/main/java/org/thingsboard/server/service/security/model/token/AccessJwtToken.java index 194a6c9d90..7484af873c 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/token/AccessJwtToken.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/token/AccessJwtToken.java @@ -21,7 +21,7 @@ import io.jsonwebtoken.Claims; public final class AccessJwtToken implements JwtToken { private final String rawToken; @JsonIgnore - private Claims claims; + private transient Claims claims; protected AccessJwtToken(final String token, Claims claims) { this.rawToken = token; diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtToken.java b/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtToken.java index e200088f44..e52a93d9b5 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtToken.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/token/JwtToken.java @@ -15,6 +15,8 @@ */ package org.thingsboard.server.service.security.model.token; -public interface JwtToken { +import java.io.Serializable; + +public interface JwtToken extends Serializable { String getToken(); } diff --git a/application/src/main/java/org/thingsboard/server/service/security/model/token/RawAccessJwtToken.java b/application/src/main/java/org/thingsboard/server/service/security/model/token/RawAccessJwtToken.java index 301cfd3d29..61aff2e23c 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/model/token/RawAccessJwtToken.java +++ b/application/src/main/java/org/thingsboard/server/service/security/model/token/RawAccessJwtToken.java @@ -21,7 +21,12 @@ import org.slf4j.LoggerFactory; import org.springframework.security.authentication.BadCredentialsException; import org.thingsboard.server.service.security.exception.JwtExpiredTokenException; -public class RawAccessJwtToken implements JwtToken { +import java.io.Serializable; + +public class RawAccessJwtToken implements JwtToken, Serializable { + + private static final long serialVersionUID = -797397445703066079L; + private static Logger logger = LoggerFactory.getLogger(RawAccessJwtToken.class); private String token; diff --git a/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java b/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java index 0856b8a168..273b775aa0 100644 --- a/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java +++ b/application/src/main/java/org/thingsboard/server/service/update/DefaultUpdateService.java @@ -27,6 +27,7 @@ import org.thingsboard.server.service.update.model.UpdateMessage; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -71,25 +72,34 @@ public class DefaultUpdateService implements UpdateService { if (version == null) { version = "unknown"; } - Path instanceIdPath = Paths.get(INSTANCE_ID_FILE); - if (Files.exists(instanceIdPath)) { - byte[] data = Files.readAllBytes(instanceIdPath); - if (data != null && data.length > 0) { - try { - instanceId = UUID.fromString(new String(data)); - } catch (IllegalArgumentException e) { - } - } - } - if (instanceId == null) { - instanceId = UUID.randomUUID(); - Files.write(instanceIdPath, instanceId.toString().getBytes()); - } + instanceId = parseInstanceId(); checkUpdatesFuture = scheduler.scheduleAtFixedRate(checkUpdatesRunnable, 0, 1, TimeUnit.HOURS); - } catch (Exception e) {} + } catch (Exception e) { + //Do nothing + } } } + private UUID parseInstanceId() throws IOException { + UUID result = null; + Path instanceIdPath = Paths.get(INSTANCE_ID_FILE); + if (instanceIdPath.toFile().exists()) { + byte[] data = Files.readAllBytes(instanceIdPath); + if (data != null && data.length > 0) { + try { + result = UUID.fromString(new String(data)); + } catch (IllegalArgumentException e) { + //Do nothing + } + } + } + if (result == null) { + result = UUID.randomUUID(); + Files.write(instanceIdPath, result.toString().getBytes()); + } + return result; + } + @PreDestroy private void destroy() { try { @@ -97,26 +107,25 @@ public class DefaultUpdateService implements UpdateService { checkUpdatesFuture.cancel(true); } scheduler.shutdownNow(); - } catch (Exception e) {} + } catch (Exception e) { + //Do nothing + } } - Runnable checkUpdatesRunnable = new Runnable() { - @Override - public void run() { - try { - log.trace("Executing check update method for instanceId [{}], platform [{}] and version [{}]", instanceId, platform, version); - ObjectNode request = new ObjectMapper().createObjectNode(); - request.put(PLATFORM_PARAM, platform); - request.put(VERSION_PARAM, version); - request.put(INSTANCE_ID_PARAM, instanceId.toString()); - JsonNode response = restClient.postForObject(UPDATE_SERVER_BASE_URL+"/api/thingsboard/updates", request, JsonNode.class); - updateMessage = new UpdateMessage( - response.get("message").asText(), - response.get("updateAvailable").asBoolean() - ); - } catch (Exception e) { - log.trace(e.getMessage()); - } + Runnable checkUpdatesRunnable = () -> { + try { + log.trace("Executing check update method for instanceId [{}], platform [{}] and version [{}]", instanceId, platform, version); + ObjectNode request = new ObjectMapper().createObjectNode(); + request.put(PLATFORM_PARAM, platform); + request.put(VERSION_PARAM, version); + request.put(INSTANCE_ID_PARAM, instanceId.toString()); + JsonNode response = restClient.postForObject(UPDATE_SERVER_BASE_URL+"/api/thingsboard/updates", request, JsonNode.class); + updateMessage = new UpdateMessage( + response.get("message").asText(), + response.get("updateAvailable").asBoolean() + ); + } catch (Exception e) { + log.trace(e.getMessage()); } }; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/AdminSettings.java b/common/data/src/main/java/org/thingsboard/server/common/data/AdminSettings.java index 09baf6d364..167c6f7c86 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/AdminSettings.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/AdminSettings.java @@ -24,7 +24,7 @@ public class AdminSettings extends BaseData { private static final long serialVersionUID = -7670322981725511892L; private String key; - private JsonNode jsonValue; + private transient JsonNode jsonValue; public AdminSettings() { super(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/ContactBased.java b/common/data/src/main/java/org/thingsboard/server/common/data/ContactBased.java index 8ee0021312..d5252a0ce1 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/ContactBased.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/ContactBased.java @@ -15,8 +15,10 @@ */ package org.thingsboard.server.common.data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.UUIDBased; +@EqualsAndHashCode(callSuper = true) public abstract class ContactBased extends SearchTextBased { private static final long serialVersionUID = 5047448057830660988L; @@ -114,72 +116,4 @@ public abstract class ContactBased extends SearchTextBased< this.email = email; } - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((address == null) ? 0 : address.hashCode()); - result = prime * result + ((address2 == null) ? 0 : address2.hashCode()); - result = prime * result + ((city == null) ? 0 : city.hashCode()); - result = prime * result + ((country == null) ? 0 : country.hashCode()); - result = prime * result + ((email == null) ? 0 : email.hashCode()); - result = prime * result + ((phone == null) ? 0 : phone.hashCode()); - result = prime * result + ((state == null) ? 0 : state.hashCode()); - result = prime * result + ((zip == null) ? 0 : zip.hashCode()); - return result; - } - - @SuppressWarnings("rawtypes") - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - ContactBased other = (ContactBased) obj; - if (address == null) { - if (other.address != null) - return false; - } else if (!address.equals(other.address)) - return false; - if (address2 == null) { - if (other.address2 != null) - return false; - } else if (!address2.equals(other.address2)) - return false; - if (city == null) { - if (other.city != null) - return false; - } else if (!city.equals(other.city)) - return false; - if (country == null) { - if (other.country != null) - return false; - } else if (!country.equals(other.country)) - return false; - if (email == null) { - if (other.email != null) - return false; - } else if (!email.equals(other.email)) - return false; - if (phone == null) { - if (other.phone != null) - return false; - } else if (!phone.equals(other.phone)) - return false; - if (state == null) { - if (other.state != null) - return false; - } else if (!state.equals(other.state)) - return false; - if (zip == null) { - if (other.zip != null) - return false; - } else if (!zip.equals(other.zip)) - return false; - return true; - } - } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Customer.java b/common/data/src/main/java/org/thingsboard/server/common/data/Customer.java index a82c235a45..4179291953 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Customer.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Customer.java @@ -29,7 +29,7 @@ public class Customer extends ContactBased implements HasName { private String title; private TenantId tenantId; - private JsonNode additionalInfo; + private transient JsonNode additionalInfo; public Customer() { super(); @@ -87,7 +87,7 @@ public class Customer extends ContactBased implements HasName { @Override public String getSearchText() { - return title; + return getTitle(); } @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java b/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java index 3e7060bfb6..71f2b1308b 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Dashboard.java @@ -22,7 +22,7 @@ public class Dashboard extends DashboardInfo { private static final long serialVersionUID = 872682138346187503L; - private JsonNode configuration; + private transient JsonNode configuration; public Dashboard() { super(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java b/common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java index 3be3b79d56..15898c6c63 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DashboardInfo.java @@ -73,7 +73,7 @@ public class DashboardInfo extends SearchTextBased implements HasNa @Override public String getSearchText() { - return title; + return getTitle(); } @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java b/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java index d8b776fdeb..47e992fd81 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/DataConstants.java @@ -29,7 +29,9 @@ public class DataConstants { public static final String SERVER_SCOPE = "SERVER_SCOPE"; public static final String SHARED_SCOPE = "SHARED_SCOPE"; - public static final String[] ALL_SCOPES = {CLIENT_SCOPE, SHARED_SCOPE, SERVER_SCOPE}; + public static final String[] allScopes() { + return new String[]{CLIENT_SCOPE, SHARED_SCOPE, SERVER_SCOPE}; + } public static final String ALARM = "ALARM"; public static final String ERROR = "ERROR"; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Device.java b/common/data/src/main/java/org/thingsboard/server/common/data/Device.java index 7d3d4f5742..131a3100c5 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Device.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Device.java @@ -15,12 +15,14 @@ */ package org.thingsboard.server.common.data; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.TenantId; import com.fasterxml.jackson.databind.JsonNode; +@EqualsAndHashCode(callSuper = true) public class Device extends SearchTextBased implements HasName { private static final long serialVersionUID = 2807343040519543363L; @@ -29,7 +31,7 @@ public class Device extends SearchTextBased implements HasName { private CustomerId customerId; private String name; private String type; - private JsonNode additionalInfo; + private transient JsonNode additionalInfo; public Device() { super(); @@ -91,56 +93,7 @@ public class Device extends SearchTextBased implements HasName { @Override public String getSearchText() { - return name; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode()); - result = prime * result + ((customerId == null) ? 0 : customerId.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((type == null) ? 0 : type.hashCode()); - result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - Device other = (Device) obj; - if (additionalInfo == null) { - if (other.additionalInfo != null) - return false; - } else if (!additionalInfo.equals(other.additionalInfo)) - return false; - if (customerId == null) { - if (other.customerId != null) - return false; - } else if (!customerId.equals(other.customerId)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (type == null) { - if (other.type != null) - return false; - } else if (!type.equals(other.type)) - return false; - if (tenantId == null) { - if (other.tenantId != null) - return false; - } else if (!tenantId.equals(other.tenantId)) - return false; - return true; + return getName(); } @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Event.java b/common/data/src/main/java/org/thingsboard/server/common/data/Event.java index aff0509fb9..af760e47fd 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Event.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Event.java @@ -31,7 +31,7 @@ public class Event extends BaseData { private String type; private String uid; private EntityId entityId; - private JsonNode body; + private transient JsonNode body; public Event() { super(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java b/common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java index 4501759e55..bb209f1011 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/Tenant.java @@ -16,17 +16,19 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.TenantId; import com.fasterxml.jackson.databind.JsonNode; +@EqualsAndHashCode(callSuper = true) public class Tenant extends ContactBased implements HasName { private static final long serialVersionUID = 8057243243859922101L; private String title; private String region; - private JsonNode additionalInfo; + private transient JsonNode additionalInfo; public Tenant() { super(); @@ -75,44 +77,7 @@ public class Tenant extends ContactBased implements HasName { @Override public String getSearchText() { - return title; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode()); - result = prime * result + ((region == null) ? 0 : region.hashCode()); - result = prime * result + ((title == null) ? 0 : title.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - Tenant other = (Tenant) obj; - if (additionalInfo == null) { - if (other.additionalInfo != null) - return false; - } else if (!additionalInfo.equals(other.additionalInfo)) - return false; - if (region == null) { - if (other.region != null) - return false; - } else if (!region.equals(other.region)) - return false; - if (title == null) { - if (other.title != null) - return false; - } else if (!title.equals(other.title)) - return false; - return true; + return getTitle(); } @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/User.java b/common/data/src/main/java/org/thingsboard/server/common/data/User.java index 1b97e2e49f..a6488995a9 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/User.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/User.java @@ -16,6 +16,7 @@ package org.thingsboard.server.common.data; import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; @@ -23,6 +24,7 @@ import org.thingsboard.server.common.data.security.Authority; import com.fasterxml.jackson.databind.JsonNode; +@EqualsAndHashCode(callSuper = true) public class User extends SearchTextBased implements HasName { private static final long serialVersionUID = 8250339805336035966L; @@ -33,7 +35,7 @@ public class User extends SearchTextBased implements HasName { private Authority authority; private String firstName; private String lastName; - private JsonNode additionalInfo; + private transient JsonNode additionalInfo; public User() { super(); @@ -118,65 +120,7 @@ public class User extends SearchTextBased implements HasName { @Override public String getSearchText() { - return email; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode()); - result = prime * result + ((authority == null) ? 0 : authority.hashCode()); - result = prime * result + ((customerId == null) ? 0 : customerId.hashCode()); - result = prime * result + ((email == null) ? 0 : email.hashCode()); - result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); - result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); - result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - User other = (User) obj; - if (additionalInfo == null) { - if (other.additionalInfo != null) - return false; - } else if (!additionalInfo.equals(other.additionalInfo)) - return false; - if (authority != other.authority) - return false; - if (customerId == null) { - if (other.customerId != null) - return false; - } else if (!customerId.equals(other.customerId)) - return false; - if (email == null) { - if (other.email != null) - return false; - } else if (!email.equals(other.email)) - return false; - if (firstName == null) { - if (other.firstName != null) - return false; - } else if (!firstName.equals(other.firstName)) - return false; - if (lastName == null) { - if (other.lastName != null) - return false; - } else if (!lastName.equals(other.lastName)) - return false; - if (tenantId == null) { - if (other.tenantId != null) - return false; - } else if (!tenantId.equals(other.tenantId)) - return false; - return true; + return getEmail(); } @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java index e48cf5b7a8..3fa6f62498 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/alarm/Alarm.java @@ -42,7 +42,7 @@ public class Alarm extends BaseData implements HasName { private long endTs; private long ackTs; private long clearTs; - private JsonNode details; + private transient JsonNode details; private boolean propagate; public Alarm() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java b/common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java index dafa514f61..382a2d72e2 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/asset/Asset.java @@ -16,12 +16,14 @@ package org.thingsboard.server.common.data.asset; import com.fasterxml.jackson.databind.JsonNode; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.SearchTextBased; import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; +@EqualsAndHashCode(callSuper = true) public class Asset extends SearchTextBased implements HasName { private static final long serialVersionUID = 2807343040519543363L; @@ -30,7 +32,7 @@ public class Asset extends SearchTextBased implements HasName { private CustomerId customerId; private String name; private String type; - private JsonNode additionalInfo; + private transient JsonNode additionalInfo; public Asset() { super(); @@ -92,56 +94,7 @@ public class Asset extends SearchTextBased implements HasName { @Override public String getSearchText() { - return name; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode()); - result = prime * result + ((customerId == null) ? 0 : customerId.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((type == null) ? 0 : type.hashCode()); - result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - Asset other = (Asset) obj; - if (additionalInfo == null) { - if (other.additionalInfo != null) - return false; - } else if (!additionalInfo.equals(other.additionalInfo)) - return false; - if (customerId == null) { - if (other.customerId != null) - return false; - } else if (!customerId.equals(other.customerId)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (type == null) { - if (other.type != null) - return false; - } else if (!type.equals(other.type)) - return false; - if (tenantId == null) { - if (other.tenantId != null) - return false; - } else if (!tenantId.equals(other.tenantId)) - return false; - return true; + return getName(); } @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityId.java b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityId.java index 17d69ac939..197762b219 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityId.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/id/EntityId.java @@ -20,6 +20,7 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import org.thingsboard.server.common.data.EntityType; +import java.io.Serializable; import java.util.UUID; /** @@ -28,7 +29,7 @@ import java.util.UUID; @JsonDeserialize(using = EntityIdDeserializer.class) @JsonSerialize(using = EntityIdSerializer.class) -public interface EntityId { +public interface EntityId extends Serializable { //NOSONAR, the constant is closely related to EntityId UUID NULL_UUID = UUID.fromString("13814000-1dd2-11b2-8080-808080808080"); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterable.java b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterable.java index 850597a879..e8a3eb13ce 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterable.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/page/PageDataIterable.java @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.page; import java.util.Iterator; import java.util.List; +import java.util.NoSuchElementException; import org.thingsboard.server.common.data.SearchTextBased; import org.thingsboard.server.common.data.id.UUIDBased; @@ -54,7 +55,7 @@ public class PageDataIterable> im fetch(nextPackLink); } } - return currentIdx != currentItems.size(); + return currentIdx < currentItems.size(); } private void fetch(TextPageLink link) { @@ -67,6 +68,9 @@ public class PageDataIterable> im @Override public T next() { + if(!hasNext()){ + throw new NoSuchElementException(); + } return currentItems.get(currentIdx++); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java index 253622e9c7..2db1a38ea2 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/ComponentDescriptor.java @@ -32,7 +32,7 @@ public class ComponentDescriptor extends SearchTextBased @Getter @Setter private ComponentScope scope; @Getter @Setter private String name; @Getter @Setter private String clazz; - @Getter @Setter private JsonNode configurationDescriptor; + @Getter @Setter private transient JsonNode configurationDescriptor; @Getter @Setter private String actions; public ComponentDescriptor() { diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/PluginMetaData.java b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/PluginMetaData.java index e5eb149fbc..755cf71bab 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/plugin/PluginMetaData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/plugin/PluginMetaData.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.common.data.plugin; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.HasName; import org.thingsboard.server.common.data.SearchTextBased; import org.thingsboard.server.common.data.id.PluginId; @@ -22,6 +23,7 @@ import org.thingsboard.server.common.data.id.TenantId; import com.fasterxml.jackson.databind.JsonNode; +@EqualsAndHashCode(callSuper = true) public class PluginMetaData extends SearchTextBased implements HasName { private static final long serialVersionUID = 1L; @@ -32,8 +34,8 @@ public class PluginMetaData extends SearchTextBased implements HasName private String clazz; private boolean publicAccess; private ComponentLifecycleState state; - private JsonNode configuration; - private JsonNode additionalInfo; + private transient JsonNode configuration; + private transient JsonNode additionalInfo; public PluginMetaData() { super(); @@ -57,7 +59,7 @@ public class PluginMetaData extends SearchTextBased implements HasName @Override public String getSearchText() { - return name; + return getName(); } public String getApiToken() { @@ -125,49 +127,6 @@ public class PluginMetaData extends SearchTextBased implements HasName this.additionalInfo = additionalInfo; } - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((apiToken == null) ? 0 : apiToken.hashCode()); - result = prime * result + ((clazz == null) ? 0 : clazz.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - PluginMetaData other = (PluginMetaData) obj; - if (apiToken == null) { - if (other.apiToken != null) - return false; - } else if (!apiToken.equals(other.apiToken)) - return false; - if (clazz == null) { - if (other.clazz != null) - return false; - } else if (!clazz.equals(other.clazz)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (tenantId == null) { - if (other.tenantId != null) - return false; - } else if (!tenantId.equals(other.tenantId)) - return false; - return true; - } - @Override public String toString() { return "PluginMetaData [apiToken=" + apiToken + ", tenantId=" + tenantId + ", name=" + name + ", clazz=" + clazz + ", publicAccess=" + publicAccess diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleMetaData.java b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleMetaData.java index 0ed44d94de..1fd72c2246 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleMetaData.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/rule/RuleMetaData.java @@ -35,10 +35,10 @@ public class RuleMetaData extends SearchTextBased implements HasName { private ComponentLifecycleState state; private int weight; private String pluginToken; - private JsonNode filters; - private JsonNode processor; - private JsonNode action; - private JsonNode additionalInfo; + private transient JsonNode filters; + private transient JsonNode processor; + private transient JsonNode action; + private transient JsonNode additionalInfo; public RuleMetaData() { super(); @@ -63,7 +63,7 @@ public class RuleMetaData extends SearchTextBased implements HasName { @Override public String getSearchText() { - return name; + return getName(); } @Override diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentials.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentials.java index 1fd3959e20..a835d6112e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentials.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentials.java @@ -15,10 +15,12 @@ */ package org.thingsboard.server.common.data.security; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.id.DeviceCredentialsId; import org.thingsboard.server.common.data.id.DeviceId; +@EqualsAndHashCode(callSuper = true) public class DeviceCredentials extends BaseData implements DeviceCredentialsFilter { private static final long serialVersionUID = -7869261127032877765L; @@ -78,46 +80,6 @@ public class DeviceCredentials extends BaseData implements this.credentialsValue = credentialsValue; } - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((credentialsId == null) ? 0 : credentialsId.hashCode()); - result = prime * result + ((credentialsType == null) ? 0 : credentialsType.hashCode()); - result = prime * result + ((credentialsValue == null) ? 0 : credentialsValue.hashCode()); - result = prime * result + ((deviceId == null) ? 0 : deviceId.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - DeviceCredentials other = (DeviceCredentials) obj; - if (credentialsId == null) { - if (other.credentialsId != null) - return false; - } else if (!credentialsId.equals(other.credentialsId)) - return false; - if (credentialsType != other.credentialsType) - return false; - if (credentialsValue == null) { - if (other.credentialsValue != null) - return false; - } else if (!credentialsValue.equals(other.credentialsValue)) - return false; - if (deviceId == null) { - if (other.deviceId != null) - return false; - } else if (!deviceId.equals(other.deviceId)) - return false; - return true; - } - @Override public String toString() { return "DeviceCredentials [deviceId=" + deviceId + ", credentialsType=" + credentialsType + ", credentialsId=" diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/UserCredentials.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/UserCredentials.java index 85790881ac..706901638e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/UserCredentials.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/UserCredentials.java @@ -15,10 +15,12 @@ */ package org.thingsboard.server.common.data.security; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.id.UserCredentialsId; import org.thingsboard.server.common.data.id.UserId; +@EqualsAndHashCode(callSuper = true) public class UserCredentials extends BaseData { private static final long serialVersionUID = -2108436378880529163L; @@ -86,52 +88,6 @@ public class UserCredentials extends BaseData { this.resetToken = resetToken; } - @Override - public int hashCode() { - final int prime = 31; - int result = super.hashCode(); - result = prime * result + ((activateToken == null) ? 0 : activateToken.hashCode()); - result = prime * result + (enabled ? 1231 : 1237); - result = prime * result + ((password == null) ? 0 : password.hashCode()); - result = prime * result + ((resetToken == null) ? 0 : resetToken.hashCode()); - result = prime * result + ((userId == null) ? 0 : userId.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (!super.equals(obj)) - return false; - if (getClass() != obj.getClass()) - return false; - UserCredentials other = (UserCredentials) obj; - if (activateToken == null) { - if (other.activateToken != null) - return false; - } else if (!activateToken.equals(other.activateToken)) - return false; - if (enabled != other.enabled) - return false; - if (password == null) { - if (other.password != null) - return false; - } else if (!password.equals(other.password)) - return false; - if (resetToken == null) { - if (other.resetToken != null) - return false; - } else if (!resetToken.equals(other.resetToken)) - return false; - if (userId == null) { - if (other.userId != null) - return false; - } else if (!userId.equals(other.userId)) - return false; - return true; - } - @Override public String toString() { StringBuilder builder = new StringBuilder(); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java index 02f17e93a0..caffe2dad0 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetType.java @@ -16,10 +16,12 @@ package org.thingsboard.server.common.data.widget; import com.fasterxml.jackson.databind.JsonNode; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.BaseData; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.WidgetTypeId; +@EqualsAndHashCode(callSuper = true) public class WidgetType extends BaseData { private static final long serialVersionUID = 8388684344603660756L; @@ -28,7 +30,7 @@ public class WidgetType extends BaseData { private String bundleAlias; private String alias; private String name; - private JsonNode descriptor; + private transient JsonNode descriptor; public WidgetType() { super(); @@ -87,33 +89,6 @@ public class WidgetType extends BaseData { this.descriptor = descriptor; } - @Override - public int hashCode() { - int result = super.hashCode(); - result = 31 * result + (tenantId != null ? tenantId.hashCode() : 0); - result = 31 * result + (bundleAlias != null ? bundleAlias.hashCode() : 0); - result = 31 * result + (alias != null ? alias.hashCode() : 0); - result = 31 * result + (name != null ? name.hashCode() : 0); - result = 31 * result + (descriptor != null ? descriptor.hashCode() : 0); - return result; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - - WidgetType that = (WidgetType) o; - - if (tenantId != null ? !tenantId.equals(that.tenantId) : that.tenantId != null) return false; - if (bundleAlias != null ? !bundleAlias.equals(that.bundleAlias) : that.bundleAlias != null) return false; - if (alias != null ? !alias.equals(that.alias) : that.alias != null) return false; - if (name != null ? !name.equals(that.name) : that.name != null) return false; - return descriptor != null ? descriptor.equals(that.descriptor) : that.descriptor == null; - - } - @Override public String toString() { final StringBuilder sb = new StringBuilder("WidgetType{"); diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java index 1149806bbe..025cf849d5 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/widget/WidgetsBundle.java @@ -80,7 +80,7 @@ public class WidgetsBundle extends SearchTextBased { @Override public String getSearchText() { - return title; + return getTitle(); } @Override diff --git a/common/transport/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java b/common/transport/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java index 640cce798b..b8a1210d32 100644 --- a/common/transport/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java +++ b/common/transport/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java @@ -30,6 +30,7 @@ import org.thingsboard.server.common.msg.kv.AttributesKVMsg; public class JsonConverter { private static final Gson GSON = new Gson(); + public static final String CAN_T_PARSE_VALUE = "Can't parse value: "; public static TelemetryUploadRequest convertToTelemetry(JsonElement jsonObject) throws JsonSyntaxException { return convertToTelemetry(jsonObject, BasicRequest.DEFAULT_REQUEST_ID); @@ -45,11 +46,11 @@ public class JsonConverter { if (je.isJsonObject()) { parseObject(request, systemTs, je.getAsJsonObject()); } else { - throw new JsonSyntaxException("Can't parse value: " + je); + throw new JsonSyntaxException(CAN_T_PARSE_VALUE + je); } }); } else { - throw new JsonSyntaxException("Can't parse value: " + jsonObject); + throw new JsonSyntaxException(CAN_T_PARSE_VALUE + jsonObject); } return request; } @@ -99,10 +100,10 @@ public class JsonConverter { result.add(new LongDataEntry(valueEntry.getKey(), value.getAsLong())); } } else { - throw new JsonSyntaxException("Can't parse value: " + value); + throw new JsonSyntaxException(CAN_T_PARSE_VALUE + value); } } else { - throw new JsonSyntaxException("Can't parse value: " + element); + throw new JsonSyntaxException(CAN_T_PARSE_VALUE + element); } } return result; @@ -119,7 +120,7 @@ public class JsonConverter { request.add(parseValues(element.getAsJsonObject()).stream().map(kv -> new BaseAttributeKvEntry(kv, ts)).collect(Collectors.toList())); return request; } else { - throw new JsonSyntaxException("Can't parse value: " + element); + throw new JsonSyntaxException(CAN_T_PARSE_VALUE + element); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java index 21f3585c35..be7e44f008 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java @@ -37,7 +37,6 @@ import org.thingsboard.server.dao.entity.EntityService; import org.thingsboard.server.dao.exception.DataValidationException; import org.thingsboard.server.common.data.relation.EntityRelationsQuery; import org.thingsboard.server.common.data.relation.EntitySearchDirection; -import org.thingsboard.server.dao.relation.RelationService; import org.thingsboard.server.common.data.relation.RelationsSearchParameters; import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.tenant.TenantDao; @@ -67,9 +66,6 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ @Autowired private TenantDao tenantDao; - @Autowired - private RelationService relationService; - @Autowired private EntityService entityService; @@ -272,7 +268,7 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ boolean hasNext = true; AlarmSeverity highestSeverity = null; AlarmQuery query; - while (hasNext) { + while (hasNext && AlarmSeverity.CRITICAL != highestSeverity) { query = new AlarmQuery(entityId, nextPageLink, alarmSearchStatus, alarmStatus, false); List alarms; try { @@ -286,33 +282,37 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ if (hasNext) { nextPageLink = new TimePageData<>(alarms, nextPageLink).getNextPageLink(); } - if (alarms.isEmpty()) { + AlarmSeverity severity = detectHighestSeverity(alarms); + if (severity == null) { continue; + } + if (severity == AlarmSeverity.CRITICAL || highestSeverity == null) { + highestSeverity = severity; } else { - List sorted = new ArrayList(alarms); - sorted.sort((p1, p2) -> p1.getSeverity().compareTo(p2.getSeverity())); - AlarmSeverity severity = sorted.get(0).getSeverity(); - if (severity == AlarmSeverity.CRITICAL) { - highestSeverity = severity; - break; - } else if (highestSeverity == null) { - highestSeverity = severity; - } else { - highestSeverity = highestSeverity.compareTo(severity) < 0 ? highestSeverity : severity; - } + highestSeverity = highestSeverity.compareTo(severity) < 0 ? highestSeverity : severity; } } return highestSeverity; } + private AlarmSeverity detectHighestSeverity(List alarms) { + if (!alarms.isEmpty()) { + List sorted = new ArrayList(alarms); + sorted.sort((p1, p2) -> p1.getSeverity().compareTo(p2.getSeverity())); + return sorted.get(0).getSeverity(); + } else { + return null; + } + } + private void deleteRelation(EntityRelation alarmRelation) throws ExecutionException, InterruptedException { log.debug("Deleting Alarm relation: {}", alarmRelation); - relationService.deleteRelation(alarmRelation).get(); + relationService.deleteRelationAsync(alarmRelation).get(); } private void createRelation(EntityRelation alarmRelation) throws ExecutionException, InterruptedException { log.debug("Creating Alarm relation: {}", alarmRelation); - relationService.saveRelation(alarmRelation).get(); + relationService.saveRelationAsync(alarmRelation).get(); } private Alarm merge(Alarm existing, Alarm alarm) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java index 14a9f21283..1ee4789a94 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/asset/BaseAssetService.java @@ -37,19 +37,15 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.TextPageData; import org.thingsboard.server.common.data.page.TextPageLink; import org.thingsboard.server.common.data.relation.EntityRelation; +import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.dao.customer.CustomerDao; import org.thingsboard.server.dao.entity.AbstractEntityService; import org.thingsboard.server.dao.exception.DataValidationException; -import org.thingsboard.server.common.data.relation.EntitySearchDirection; import org.thingsboard.server.dao.service.DataValidator; import org.thingsboard.server.dao.service.PaginatedRemover; import org.thingsboard.server.dao.tenant.TenantDao; -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import static org.thingsboard.server.dao.DaoUtil.toUUIDs; @@ -60,6 +56,10 @@ import static org.thingsboard.server.dao.service.Validator.*; @Slf4j public class BaseAssetService extends AbstractEntityService implements AssetService { + public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; + public static final String INCORRECT_PAGE_LINK = "Incorrect page link "; + public static final String INCORRECT_CUSTOMER_ID = "Incorrect customerId "; + public static final String INCORRECT_ASSET_ID = "Incorrect assetId "; @Autowired private AssetDao assetDao; @@ -72,21 +72,21 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @Override public Asset findAssetById(AssetId assetId) { log.trace("Executing findAssetById [{}]", assetId); - validateId(assetId, "Incorrect assetId " + assetId); + validateId(assetId, INCORRECT_ASSET_ID + assetId); return assetDao.findById(assetId.getId()); } @Override public ListenableFuture findAssetByIdAsync(AssetId assetId) { log.trace("Executing findAssetById [{}]", assetId); - validateId(assetId, "Incorrect assetId " + assetId); + validateId(assetId, INCORRECT_ASSET_ID + assetId); return assetDao.findByIdAsync(assetId.getId()); } @Override public Optional findAssetByTenantIdAndName(TenantId tenantId, String name) { log.trace("Executing findAssetByTenantIdAndName [{}][{}]", tenantId, name); - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); return assetDao.findAssetsByTenantIdAndName(tenantId.getId(), name); } @@ -114,7 +114,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @Override public void deleteAsset(AssetId assetId) { log.trace("Executing deleteAsset [{}]", assetId); - validateId(assetId, "Incorrect assetId " + assetId); + validateId(assetId, INCORRECT_ASSET_ID + assetId); deleteEntityRelations(assetId); assetDao.removeById(assetId.getId()); } @@ -122,8 +122,8 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @Override public TextPageData findAssetsByTenantId(TenantId tenantId, TextPageLink pageLink) { log.trace("Executing findAssetsByTenantId, tenantId [{}], pageLink [{}]", tenantId, pageLink); - validateId(tenantId, "Incorrect tenantId " + tenantId); - validatePageLink(pageLink, "Incorrect page link " + pageLink); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); List assets = assetDao.findAssetsByTenantId(tenantId.getId(), pageLink); return new TextPageData<>(assets, pageLink); } @@ -131,9 +131,9 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @Override public TextPageData findAssetsByTenantIdAndType(TenantId tenantId, String type, TextPageLink pageLink) { log.trace("Executing findAssetsByTenantIdAndType, tenantId [{}], type [{}], pageLink [{}]", tenantId, type, pageLink); - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); validateString(type, "Incorrect type " + type); - validatePageLink(pageLink, "Incorrect page link " + pageLink); + validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); List assets = assetDao.findAssetsByTenantIdAndType(tenantId.getId(), type, pageLink); return new TextPageData<>(assets, pageLink); } @@ -141,7 +141,7 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @Override public ListenableFuture> findAssetsByTenantIdAndIdsAsync(TenantId tenantId, List assetIds) { log.trace("Executing findAssetsByTenantIdAndIdsAsync, tenantId [{}], assetIds [{}]", tenantId, assetIds); - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); validateIds(assetIds, "Incorrect assetIds " + assetIds); return assetDao.findAssetsByTenantIdAndIdsAsync(tenantId.getId(), toUUIDs(assetIds)); } @@ -149,27 +149,27 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @Override public void deleteAssetsByTenantId(TenantId tenantId) { log.trace("Executing deleteAssetsByTenantId, tenantId [{}]", tenantId); - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); tenantAssetsRemover.removeEntities(tenantId); } @Override public TextPageData findAssetsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, TextPageLink pageLink) { log.trace("Executing findAssetsByTenantIdAndCustomerId, tenantId [{}], customerId [{}], pageLink [{}]", tenantId, customerId, pageLink); - validateId(tenantId, "Incorrect tenantId " + tenantId); - validateId(customerId, "Incorrect customerId " + customerId); - validatePageLink(pageLink, "Incorrect page link " + pageLink); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); + validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); List assets = assetDao.findAssetsByTenantIdAndCustomerId(tenantId.getId(), customerId.getId(), pageLink); - return new TextPageData(assets, pageLink); + return new TextPageData<>(assets, pageLink); } @Override public TextPageData findAssetsByTenantIdAndCustomerIdAndType(TenantId tenantId, CustomerId customerId, String type, TextPageLink pageLink) { log.trace("Executing findAssetsByTenantIdAndCustomerIdAndType, tenantId [{}], customerId [{}], type [{}], pageLink [{}]", tenantId, customerId, type, pageLink); - validateId(tenantId, "Incorrect tenantId " + tenantId); - validateId(customerId, "Incorrect customerId " + customerId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); validateString(type, "Incorrect type " + type); - validatePageLink(pageLink, "Incorrect page link " + pageLink); + validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); List assets = assetDao.findAssetsByTenantIdAndCustomerIdAndType(tenantId.getId(), customerId.getId(), type, pageLink); return new TextPageData<>(assets, pageLink); } @@ -177,8 +177,8 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @Override public ListenableFuture> findAssetsByTenantIdCustomerIdAndIdsAsync(TenantId tenantId, CustomerId customerId, List assetIds) { log.trace("Executing findAssetsByTenantIdAndCustomerIdAndIdsAsync, tenantId [{}], customerId [{}], assetIds [{}]", tenantId, customerId, assetIds); - validateId(tenantId, "Incorrect tenantId " + tenantId); - validateId(customerId, "Incorrect customerId " + customerId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); validateIds(assetIds, "Incorrect assetIds " + assetIds); return assetDao.findAssetsByTenantIdAndCustomerIdAndIdsAsync(tenantId.getId(), customerId.getId(), toUUIDs(assetIds)); } @@ -186,8 +186,8 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ @Override public void unassignCustomerAssets(TenantId tenantId, CustomerId customerId) { log.trace("Executing unassignCustomerAssets, tenantId [{}], customerId [{}]", tenantId, customerId); - validateId(tenantId, "Incorrect tenantId " + tenantId); - validateId(customerId, "Incorrect customerId " + customerId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); new CustomerAssetsUnassigner(tenantId).removeEntities(customerId); } @@ -205,22 +205,16 @@ public class BaseAssetService extends AbstractEntityService implements AssetServ } return Futures.successfulAsList(futures); }); - - assets = Futures.transform(assets, new Function, List>() { - @Nullable - @Override - public List apply(@Nullable List assetList) { - return assetList.stream().filter(asset -> query.getAssetTypes().contains(asset.getType())).collect(Collectors.toList()); - } - }); - + assets = Futures.transform(assets, (Function, List>)assetList -> + assetList == null ? Collections.emptyList() : assetList.stream().filter(asset -> query.getAssetTypes().contains(asset.getType())).collect(Collectors.toList()) + ); return assets; } @Override public ListenableFuture> findAssetTypesByTenantId(TenantId tenantId) { log.trace("Executing findAssetTypesByTenantId, tenantId [{}]", tenantId); - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); ListenableFuture> tenantAssetTypes = assetDao.findTenantAssetTypesAsync(tenantId.getId()); return Futures.transform(tenantAssetTypes, (Function, List>) assetTypes -> { diff --git a/dao/src/main/java/org/thingsboard/server/dao/attributes/CassandraBaseAttributesDao.java b/dao/src/main/java/org/thingsboard/server/dao/attributes/CassandraBaseAttributesDao.java index d3134b7d0f..6911cdb706 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/attributes/CassandraBaseAttributesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/attributes/CassandraBaseAttributesDao.java @@ -109,18 +109,21 @@ public class CassandraBaseAttributesDao extends CassandraAbstractAsyncDao implem stmt.setString(3, attribute.getKey()); stmt.setLong(4, attribute.getLastUpdateTs()); stmt.setString(5, attribute.getStrValue().orElse(null)); - if (attribute.getBooleanValue().isPresent()) { - stmt.setBool(6, attribute.getBooleanValue().get()); + Optional booleanValue = attribute.getBooleanValue(); + if (booleanValue.isPresent()) { + stmt.setBool(6, booleanValue.get()); } else { stmt.setToNull(6); } - if (attribute.getLongValue().isPresent()) { - stmt.setLong(7, attribute.getLongValue().get()); + Optional longValue = attribute.getLongValue(); + if (longValue.isPresent()) { + stmt.setLong(7, longValue.get()); } else { stmt.setToNull(7); } - if (attribute.getDoubleValue().isPresent()) { - stmt.setDouble(8, attribute.getDoubleValue().get()); + Optional doubleValue = attribute.getDoubleValue(); + if (doubleValue.isPresent()) { + stmt.setDouble(8, doubleValue.get()); } else { stmt.setToNull(8); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java b/dao/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java index 2b9000d7dd..36d1b783ea 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java +++ b/dao/src/main/java/org/thingsboard/server/dao/cassandra/AbstractCassandraCluster.java @@ -153,6 +153,7 @@ public abstract class AbstractCassandraCluster { Thread.sleep(initRetryInterval); } catch (InterruptedException ie) { log.warn("Failed to wait until retry", ie); + Thread.currentThread().interrupt(); } } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/component/CassandraBaseComponentDescriptorDao.java b/dao/src/main/java/org/thingsboard/server/dao/component/CassandraBaseComponentDescriptorDao.java index 99413d5d47..ff3f727610 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/component/CassandraBaseComponentDescriptorDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/component/CassandraBaseComponentDescriptorDao.java @@ -49,6 +49,8 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.select; @NoSqlDao public class CassandraBaseComponentDescriptorDao extends CassandraAbstractSearchTextDao implements ComponentDescriptorDao { + public static final String SEARCH_RESULT = "Search result: [{}]"; + @Override protected Class getColumnFamilyClass() { return ComponentDescriptorEntity.class; @@ -79,7 +81,7 @@ public class CassandraBaseComponentDescriptorDao extends CassandraAbstractSearch if (log.isTraceEnabled()) { log.trace("Search result: [{}] for component entity [{}]", componentDescriptor != null, componentDescriptor); } else { - log.debug("Search result: [{}]", componentDescriptor != null); + log.debug(SEARCH_RESULT, componentDescriptor != null); } return componentDescriptor; } @@ -93,7 +95,7 @@ public class CassandraBaseComponentDescriptorDao extends CassandraAbstractSearch if (log.isTraceEnabled()) { log.trace("Search result: [{}] for component entity [{}]", entity != null, entity); } else { - log.debug("Search result: [{}]", entity != null); + log.debug(SEARCH_RESULT, entity != null); } return DaoUtil.getData(entity); } @@ -104,9 +106,9 @@ public class CassandraBaseComponentDescriptorDao extends CassandraAbstractSearch List entities = findPageWithTextSearch(ModelConstants.COMPONENT_DESCRIPTOR_BY_TYPE_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, Arrays.asList(eq(ModelConstants.COMPONENT_DESCRIPTOR_TYPE_PROPERTY, type)), pageLink); if (log.isTraceEnabled()) { - log.trace("Search result: [{}]", Arrays.toString(entities.toArray())); + log.trace(SEARCH_RESULT, Arrays.toString(entities.toArray())); } else { - log.debug("Search result: [{}]", entities.size()); + log.debug(SEARCH_RESULT, entities.size()); } return DaoUtil.convertDataList(entities); } @@ -118,9 +120,9 @@ public class CassandraBaseComponentDescriptorDao extends CassandraAbstractSearch Arrays.asList(eq(ModelConstants.COMPONENT_DESCRIPTOR_TYPE_PROPERTY, type), eq(ModelConstants.COMPONENT_DESCRIPTOR_SCOPE_PROPERTY, scope.name())), pageLink); if (log.isTraceEnabled()) { - log.trace("Search result: [{}]", Arrays.toString(entities.toArray())); + log.trace(SEARCH_RESULT, Arrays.toString(entities.toArray())); } else { - log.debug("Search result: [{}]", entities.size()); + log.debug(SEARCH_RESULT, entities.size()); } return DaoUtil.convertDataList(entities); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java index 29fc14a755..e8ec21f3c0 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/customer/CustomerServiceImpl.java @@ -51,6 +51,7 @@ import static org.thingsboard.server.dao.service.Validator.validateId; public class CustomerServiceImpl extends AbstractEntityService implements CustomerService { private static final String PUBLIC_CUSTOMER_TITLE = "Public"; + public static final String INCORRECT_CUSTOMER_ID = "Incorrect customerId "; @Autowired private CustomerDao customerDao; @@ -73,14 +74,14 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom @Override public Customer findCustomerById(CustomerId customerId) { log.trace("Executing findCustomerById [{}]", customerId); - Validator.validateId(customerId, "Incorrect customerId " + customerId); + Validator.validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); return customerDao.findById(customerId.getId()); } @Override public ListenableFuture findCustomerByIdAsync(CustomerId customerId) { log.trace("Executing findCustomerByIdAsync [{}]", customerId); - validateId(customerId, "Incorrect customerId " + customerId); + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); return customerDao.findByIdAsync(customerId.getId()); } @@ -94,7 +95,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom @Override public void deleteCustomer(CustomerId customerId) { log.trace("Executing deleteCustomer [{}]", customerId); - Validator.validateId(customerId, "Incorrect customerId " + customerId); + Validator.validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); Customer customer = findCustomerById(customerId); if (customer == null) { throw new IncorrectParameterException("Unable to delete non-existent customer."); @@ -110,7 +111,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom @Override public Customer findOrCreatePublicCustomer(TenantId tenantId) { log.trace("Executing findOrCreatePublicCustomer, tenantId [{}]", tenantId); - Validator.validateId(tenantId, "Incorrect customerId " + tenantId); + Validator.validateId(tenantId, INCORRECT_CUSTOMER_ID + tenantId); Optional publicCustomerOpt = customerDao.findCustomersByTenantIdAndTitle(tenantId.getId(), PUBLIC_CUSTOMER_TITLE); if (publicCustomerOpt.isPresent()) { return publicCustomerOpt.get(); diff --git a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java index e1b1587f91..53fdb731dc 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/dashboard/DashboardServiceImpl.java @@ -46,6 +46,8 @@ import static org.thingsboard.server.dao.service.Validator.validateId; @Slf4j public class DashboardServiceImpl extends AbstractEntityService implements DashboardService { + public static final String INCORRECT_DASHBOARD_ID = "Incorrect dashboardId "; + public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; @Autowired private DashboardDao dashboardDao; @@ -61,28 +63,28 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @Override public Dashboard findDashboardById(DashboardId dashboardId) { log.trace("Executing findDashboardById [{}]", dashboardId); - Validator.validateId(dashboardId, "Incorrect dashboardId " + dashboardId); + Validator.validateId(dashboardId, INCORRECT_DASHBOARD_ID + dashboardId); return dashboardDao.findById(dashboardId.getId()); } @Override public ListenableFuture findDashboardByIdAsync(DashboardId dashboardId) { log.trace("Executing findDashboardByIdAsync [{}]", dashboardId); - validateId(dashboardId, "Incorrect dashboardId " + dashboardId); + validateId(dashboardId, INCORRECT_DASHBOARD_ID + dashboardId); return dashboardDao.findByIdAsync(dashboardId.getId()); } @Override public DashboardInfo findDashboardInfoById(DashboardId dashboardId) { log.trace("Executing findDashboardInfoById [{}]", dashboardId); - Validator.validateId(dashboardId, "Incorrect dashboardId " + dashboardId); + Validator.validateId(dashboardId, INCORRECT_DASHBOARD_ID + dashboardId); return dashboardInfoDao.findById(dashboardId.getId()); } @Override public ListenableFuture findDashboardInfoByIdAsync(DashboardId dashboardId) { log.trace("Executing findDashboardInfoByIdAsync [{}]", dashboardId); - validateId(dashboardId, "Incorrect dashboardId " + dashboardId); + validateId(dashboardId, INCORRECT_DASHBOARD_ID + dashboardId); return dashboardInfoDao.findByIdAsync(dashboardId.getId()); } @@ -110,7 +112,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @Override public void deleteDashboard(DashboardId dashboardId) { log.trace("Executing deleteDashboard [{}]", dashboardId); - Validator.validateId(dashboardId, "Incorrect dashboardId " + dashboardId); + Validator.validateId(dashboardId, INCORRECT_DASHBOARD_ID + dashboardId); deleteEntityRelations(dashboardId); dashboardDao.removeById(dashboardId.getId()); } @@ -118,7 +120,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @Override public TextPageData findDashboardsByTenantId(TenantId tenantId, TextPageLink pageLink) { log.trace("Executing findDashboardsByTenantId, tenantId [{}], pageLink [{}]", tenantId, pageLink); - Validator.validateId(tenantId, "Incorrect tenantId " + tenantId); + Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); Validator.validatePageLink(pageLink, "Incorrect page link " + pageLink); List dashboards = dashboardInfoDao.findDashboardsByTenantId(tenantId.getId(), pageLink); return new TextPageData<>(dashboards, pageLink); @@ -127,14 +129,14 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @Override public void deleteDashboardsByTenantId(TenantId tenantId) { log.trace("Executing deleteDashboardsByTenantId, tenantId [{}]", tenantId); - Validator.validateId(tenantId, "Incorrect tenantId " + tenantId); + Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); tenantDashboardsRemover.removeEntities(tenantId); } @Override public TextPageData findDashboardsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, TextPageLink pageLink) { log.trace("Executing findDashboardsByTenantIdAndCustomerId, tenantId [{}], customerId [{}], pageLink [{}]", tenantId, customerId, pageLink); - Validator.validateId(tenantId, "Incorrect tenantId " + tenantId); + Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); Validator.validateId(customerId, "Incorrect customerId " + customerId); Validator.validatePageLink(pageLink, "Incorrect page link " + pageLink); List dashboards = dashboardInfoDao.findDashboardsByTenantIdAndCustomerId(tenantId.getId(), customerId.getId(), pageLink); @@ -144,7 +146,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb @Override public void unassignCustomerDashboards(TenantId tenantId, CustomerId customerId) { log.trace("Executing unassignCustomerDashboards, tenantId [{}], customerId [{}]", tenantId, customerId); - Validator.validateId(tenantId, "Incorrect tenantId " + tenantId); + Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); Validator.validateId(customerId, "Incorrect customerId " + customerId); new CustomerDashboardsUnassigner(tenantId).removeEntities(customerId); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java index 76be99697c..e762a0c57d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/device/DeviceServiceImpl.java @@ -44,10 +44,7 @@ import org.thingsboard.server.dao.service.PaginatedRemover; import org.thingsboard.server.dao.tenant.TenantDao; import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import static org.thingsboard.server.dao.DaoUtil.toUUIDs; @@ -58,6 +55,10 @@ import static org.thingsboard.server.dao.service.Validator.*; @Slf4j public class DeviceServiceImpl extends AbstractEntityService implements DeviceService { + public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; + public static final String INCORRECT_PAGE_LINK = "Incorrect page link "; + public static final String INCORRECT_CUSTOMER_ID = "Incorrect customerId "; + public static final String INCORRECT_DEVICE_ID = "Incorrect deviceId "; @Autowired private DeviceDao deviceDao; @@ -73,21 +74,21 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @Override public Device findDeviceById(DeviceId deviceId) { log.trace("Executing findDeviceById [{}]", deviceId); - validateId(deviceId, "Incorrect deviceId " + deviceId); + validateId(deviceId, INCORRECT_DEVICE_ID + deviceId); return deviceDao.findById(deviceId.getId()); } @Override public ListenableFuture findDeviceByIdAsync(DeviceId deviceId) { log.trace("Executing findDeviceById [{}]", deviceId); - validateId(deviceId, "Incorrect deviceId " + deviceId); + validateId(deviceId, INCORRECT_DEVICE_ID + deviceId); return deviceDao.findByIdAsync(deviceId.getId()); } @Override public Optional findDeviceByTenantIdAndName(TenantId tenantId, String name) { log.trace("Executing findDeviceByTenantIdAndName [{}][{}]", tenantId, name); - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); Optional deviceOpt = deviceDao.findDeviceByTenantIdAndName(tenantId.getId(), name); if (deviceOpt.isPresent()) { return Optional.of(deviceOpt.get()); @@ -128,7 +129,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @Override public void deleteDevice(DeviceId deviceId) { log.trace("Executing deleteDevice [{}]", deviceId); - validateId(deviceId, "Incorrect deviceId " + deviceId); + validateId(deviceId, INCORRECT_DEVICE_ID + deviceId); DeviceCredentials deviceCredentials = deviceCredentialsService.findDeviceCredentialsByDeviceId(deviceId); if (deviceCredentials != null) { deviceCredentialsService.deleteDeviceCredentials(deviceCredentials); @@ -140,8 +141,8 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @Override public TextPageData findDevicesByTenantId(TenantId tenantId, TextPageLink pageLink) { log.trace("Executing findDevicesByTenantId, tenantId [{}], pageLink [{}]", tenantId, pageLink); - validateId(tenantId, "Incorrect tenantId " + tenantId); - validatePageLink(pageLink, "Incorrect page link " + pageLink); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); List devices = deviceDao.findDevicesByTenantId(tenantId.getId(), pageLink); return new TextPageData<>(devices, pageLink); } @@ -149,9 +150,9 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @Override public TextPageData findDevicesByTenantIdAndType(TenantId tenantId, String type, TextPageLink pageLink) { log.trace("Executing findDevicesByTenantIdAndType, tenantId [{}], type [{}], pageLink [{}]", tenantId, type, pageLink); - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); validateString(type, "Incorrect type " + type); - validatePageLink(pageLink, "Incorrect page link " + pageLink); + validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); List devices = deviceDao.findDevicesByTenantIdAndType(tenantId.getId(), type, pageLink); return new TextPageData<>(devices, pageLink); } @@ -159,7 +160,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @Override public ListenableFuture> findDevicesByTenantIdAndIdsAsync(TenantId tenantId, List deviceIds) { log.trace("Executing findDevicesByTenantIdAndIdsAsync, tenantId [{}], deviceIds [{}]", tenantId, deviceIds); - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); validateIds(deviceIds, "Incorrect deviceIds " + deviceIds); return deviceDao.findDevicesByTenantIdAndIdsAsync(tenantId.getId(), toUUIDs(deviceIds)); } @@ -168,16 +169,16 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @Override public void deleteDevicesByTenantId(TenantId tenantId) { log.trace("Executing deleteDevicesByTenantId, tenantId [{}]", tenantId); - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); tenantDevicesRemover.removeEntities(tenantId); } @Override public TextPageData findDevicesByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, TextPageLink pageLink) { log.trace("Executing findDevicesByTenantIdAndCustomerId, tenantId [{}], customerId [{}], pageLink [{}]", tenantId, customerId, pageLink); - validateId(tenantId, "Incorrect tenantId " + tenantId); - validateId(customerId, "Incorrect customerId " + customerId); - validatePageLink(pageLink, "Incorrect page link " + pageLink); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); + validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); List devices = deviceDao.findDevicesByTenantIdAndCustomerId(tenantId.getId(), customerId.getId(), pageLink); return new TextPageData<>(devices, pageLink); } @@ -185,10 +186,10 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @Override public TextPageData findDevicesByTenantIdAndCustomerIdAndType(TenantId tenantId, CustomerId customerId, String type, TextPageLink pageLink) { log.trace("Executing findDevicesByTenantIdAndCustomerIdAndType, tenantId [{}], customerId [{}], type [{}], pageLink [{}]", tenantId, customerId, type, pageLink); - validateId(tenantId, "Incorrect tenantId " + tenantId); - validateId(customerId, "Incorrect customerId " + customerId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); validateString(type, "Incorrect type " + type); - validatePageLink(pageLink, "Incorrect page link " + pageLink); + validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); List devices = deviceDao.findDevicesByTenantIdAndCustomerIdAndType(tenantId.getId(), customerId.getId(), type, pageLink); return new TextPageData<>(devices, pageLink); } @@ -196,8 +197,8 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @Override public ListenableFuture> findDevicesByTenantIdCustomerIdAndIdsAsync(TenantId tenantId, CustomerId customerId, List deviceIds) { log.trace("Executing findDevicesByTenantIdCustomerIdAndIdsAsync, tenantId [{}], customerId [{}], deviceIds [{}]", tenantId, customerId, deviceIds); - validateId(tenantId, "Incorrect tenantId " + tenantId); - validateId(customerId, "Incorrect customerId " + customerId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); validateIds(deviceIds, "Incorrect deviceIds " + deviceIds); return deviceDao.findDevicesByTenantIdCustomerIdAndIdsAsync(tenantId.getId(), customerId.getId(), toUUIDs(deviceIds)); @@ -206,8 +207,8 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @Override public void unassignCustomerDevices(TenantId tenantId, CustomerId customerId) { log.trace("Executing unassignCustomerDevices, tenantId [{}], customerId [{}]", tenantId, customerId); - validateId(tenantId, "Incorrect tenantId " + tenantId); - validateId(customerId, "Incorrect customerId " + customerId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + validateId(customerId, INCORRECT_CUSTOMER_ID + customerId); new CustomerDevicesUnassigner(tenantId).removeEntities(customerId); } @@ -230,7 +231,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @Nullable @Override public List apply(@Nullable List deviceList) { - return deviceList.stream().filter(device -> query.getDeviceTypes().contains(device.getType())).collect(Collectors.toList()); + return deviceList == null ? Collections.emptyList() : deviceList.stream().filter(device -> query.getDeviceTypes().contains(device.getType())).collect(Collectors.toList()); } }); @@ -240,7 +241,7 @@ public class DeviceServiceImpl extends AbstractEntityService implements DeviceSe @Override public ListenableFuture> findDeviceTypesByTenantId(TenantId tenantId) { log.trace("Executing findDeviceTypesByTenantId, tenantId [{}]", tenantId); - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); ListenableFuture> tenantDeviceTypes = deviceDao.findTenantDeviceTypesAsync(tenantId.getId()); return Futures.transform(tenantDeviceTypes, (Function, List>) deviceTypes -> { diff --git a/dao/src/main/java/org/thingsboard/server/dao/entity/AbstractEntityService.java b/dao/src/main/java/org/thingsboard/server/dao/entity/AbstractEntityService.java index b75196daf2..a7f1530b62 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/entity/AbstractEntityService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/entity/AbstractEntityService.java @@ -31,12 +31,7 @@ public abstract class AbstractEntityService { protected void deleteEntityRelations(EntityId entityId) { log.trace("Executing deleteEntityRelations [{}]", entityId); - try { - relationService.deleteEntityRelations(entityId).get(); - } catch (InterruptedException | ExecutionException e) { - throw new RuntimeException(e); - } + relationService.deleteEntityRelations(entityId); } - } diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/BaseEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/BaseEntity.java index f927e27d95..effe911e8a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/BaseEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/BaseEntity.java @@ -18,7 +18,7 @@ package org.thingsboard.server.dao.model; import java.io.Serializable; import java.util.UUID; -public interface BaseEntity extends ToData, Serializable { +public interface BaseEntity extends ToData { UUID getId(); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/EntitySubtypeEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/EntitySubtypeEntity.java index 77983d34b7..a653b4d365 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/EntitySubtypeEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/EntitySubtypeEntity.java @@ -19,7 +19,6 @@ package org.thingsboard.server.dao.model; import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; -import com.datastax.driver.mapping.annotations.Transient; import org.thingsboard.server.common.data.EntitySubtype; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.id.TenantId; @@ -32,9 +31,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.*; @Table(name = ENTITY_SUBTYPE_COLUMN_FAMILY_NAME) public class EntitySubtypeEntity { - @Transient - private static final long serialVersionUID = -1268181961886910152L; - @PartitionKey(value = 0) @Column(name = ENTITY_SUBTYPE_TENANT_ID_PROPERTY) private UUID tenantId; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java index 194a41c7b8..9b596fc4ca 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java @@ -27,8 +27,8 @@ public class ModelConstants { private ModelConstants() { } - public static UUID NULL_UUID = UUIDs.startOf(0); - public static String NULL_UUID_STR = UUIDConverter.fromTimeUUID(NULL_UUID); + public static final UUID NULL_UUID = UUIDs.startOf(0); + public static final String NULL_UUID_STR = UUIDConverter.fromTimeUUID(NULL_UUID); /** * Generic constants. @@ -42,6 +42,7 @@ public class ModelConstants { public static final String ALIAS_PROPERTY = "alias"; public static final String SEARCH_TEXT_PROPERTY = "search_text"; public static final String ADDITIONAL_INFO_PROPERTY = "additional_info"; + public static final String ENTITY_TYPE_PROPERTY = "entity_type"; /** * Cassandra user constants. @@ -66,7 +67,7 @@ public class ModelConstants { public static final String USER_CREDENTIALS_COLUMN_FAMILY_NAME = "user_credentials"; public static final String USER_CREDENTIALS_USER_ID_PROPERTY = USER_ID_PROPERTY; public static final String USER_CREDENTIALS_ENABLED_PROPERTY = "enabled"; - public static final String USER_CREDENTIALS_PASSWORD_PROPERTY = "password"; + public static final String USER_CREDENTIALS_PASSWORD_PROPERTY = "password"; //NOSONAR, the constant used to identify password column name (not password value itself) public static final String USER_CREDENTIALS_ACTIVATE_TOKEN_PROPERTY = "activate_token"; public static final String USER_CREDENTIALS_RESET_TOKEN_PROPERTY = "reset_token"; @@ -155,7 +156,7 @@ public class ModelConstants { */ public static final String ENTITY_SUBTYPE_COLUMN_FAMILY_NAME = "entity_subtype"; public static final String ENTITY_SUBTYPE_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; - public static final String ENTITY_SUBTYPE_ENTITY_TYPE_PROPERTY = "entity_type"; + public static final String ENTITY_SUBTYPE_ENTITY_TYPE_PROPERTY = ENTITY_TYPE_PROPERTY; public static final String ENTITY_SUBTYPE_TYPE_PROPERTY = "type"; /** @@ -250,7 +251,7 @@ public class ModelConstants { public static final String PLUGIN_API_TOKEN_PROPERTY = "api_token"; public static final String PLUGIN_CLASS_PROPERTY = "plugin_class"; public static final String PLUGIN_ACCESS_PROPERTY = "public_access"; - public static final String PLUGIN_STATE_PROPERTY = "state"; + public static final String PLUGIN_STATE_PROPERTY = STATE_PROPERTY; public static final String PLUGIN_CONFIGURATION_PROPERTY = "configuration"; public static final String PLUGIN_BY_API_TOKEN_COLUMN_FAMILY_NAME = "plugin_by_api_token"; @@ -277,7 +278,7 @@ public class ModelConstants { public static final String RULE_COLUMN_FAMILY_NAME = "rule"; public static final String RULE_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; public static final String RULE_NAME_PROPERTY = "name"; - public static final String RULE_STATE_PROPERTY = "state"; + public static final String RULE_STATE_PROPERTY = STATE_PROPERTY; public static final String RULE_WEIGHT_PROPERTY = "weight"; public static final String RULE_PLUGIN_TOKEN_PROPERTY = "plugin_token"; public static final String RULE_FILTERS = "filters"; @@ -294,7 +295,7 @@ public class ModelConstants { public static final String EVENT_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY; public static final String EVENT_TYPE_PROPERTY = "event_type"; public static final String EVENT_UID_PROPERTY = "event_uid"; - public static final String EVENT_ENTITY_TYPE_PROPERTY = "entity_type"; + public static final String EVENT_ENTITY_TYPE_PROPERTY = ENTITY_TYPE_PROPERTY; public static final String EVENT_ENTITY_ID_PROPERTY = "entity_id"; public static final String EVENT_BODY_PROPERTY = "body"; @@ -310,7 +311,7 @@ public class ModelConstants { public static final String TS_KV_LATEST_CF = "ts_kv_latest_cf"; - public static final String ENTITY_TYPE_COLUMN = "entity_type"; + public static final String ENTITY_TYPE_COLUMN = ENTITY_TYPE_PROPERTY; public static final String ENTITY_ID_COLUMN = "entity_id"; public static final String ATTRIBUTE_TYPE_COLUMN = "attribute_type"; public static final String ATTRIBUTE_KEY_COLUMN = "attribute_key"; @@ -328,17 +329,17 @@ public class ModelConstants { public static final String LONG_VALUE_COLUMN = "long_v"; public static final String DOUBLE_VALUE_COLUMN = "dbl_v"; - public static final String[] NONE_AGGREGATION_COLUMNS = new String[]{LONG_VALUE_COLUMN, DOUBLE_VALUE_COLUMN, BOOLEAN_VALUE_COLUMN, STRING_VALUE_COLUMN, KEY_COLUMN, TS_COLUMN}; + protected static final String[] NONE_AGGREGATION_COLUMNS = new String[]{LONG_VALUE_COLUMN, DOUBLE_VALUE_COLUMN, BOOLEAN_VALUE_COLUMN, STRING_VALUE_COLUMN, KEY_COLUMN, TS_COLUMN}; - public static final String[] COUNT_AGGREGATION_COLUMNS = new String[]{count(LONG_VALUE_COLUMN), count(DOUBLE_VALUE_COLUMN), count(BOOLEAN_VALUE_COLUMN), count(STRING_VALUE_COLUMN)}; + protected static final String[] COUNT_AGGREGATION_COLUMNS = new String[]{count(LONG_VALUE_COLUMN), count(DOUBLE_VALUE_COLUMN), count(BOOLEAN_VALUE_COLUMN), count(STRING_VALUE_COLUMN)}; - public static final String[] MIN_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, + protected static final String[] MIN_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, new String[]{min(LONG_VALUE_COLUMN), min(DOUBLE_VALUE_COLUMN), min(BOOLEAN_VALUE_COLUMN), min(STRING_VALUE_COLUMN)}); - public static final String[] MAX_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, + protected static final String[] MAX_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, new String[]{max(LONG_VALUE_COLUMN), max(DOUBLE_VALUE_COLUMN), max(BOOLEAN_VALUE_COLUMN), max(STRING_VALUE_COLUMN)}); - public static final String[] SUM_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, + protected static final String[] SUM_AGGREGATION_COLUMNS = ArrayUtils.addAll(COUNT_AGGREGATION_COLUMNS, new String[]{sum(LONG_VALUE_COLUMN), sum(DOUBLE_VALUE_COLUMN)}); - public static final String[] AVG_AGGREGATION_COLUMNS = SUM_AGGREGATION_COLUMNS; + protected static final String[] AVG_AGGREGATION_COLUMNS = SUM_AGGREGATION_COLUMNS; public static String min(String s) { return "min(" + s + ")"; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/AdminSettingsEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/AdminSettingsEntity.java index 89cd08a834..b5dc234881 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/AdminSettingsEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/AdminSettingsEntity.java @@ -19,8 +19,9 @@ import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; -import com.datastax.driver.mapping.annotations.Transient; import com.fasterxml.jackson.databind.JsonNode; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.thingsboard.server.common.data.AdminSettings; import org.thingsboard.server.common.data.id.AdminSettingsId; import org.thingsboard.server.dao.model.BaseEntity; @@ -31,11 +32,10 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.*; @Table(name = ADMIN_SETTINGS_COLUMN_FAMILY_NAME) +@EqualsAndHashCode +@ToString public final class AdminSettingsEntity implements BaseEntity { - @Transient - private static final long serialVersionUID = 899117723388310403L; - @PartitionKey(value = 0) @Column(name = ID_PROPERTY) private UUID id; @@ -82,56 +82,6 @@ public final class AdminSettingsEntity implements BaseEntity { this.jsonValue = jsonValue; } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((jsonValue == null) ? 0 : jsonValue.hashCode()); - result = prime * result + ((key == null) ? 0 : key.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - AdminSettingsEntity other = (AdminSettingsEntity) obj; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - if (jsonValue == null) { - if (other.jsonValue != null) - return false; - } else if (!jsonValue.equals(other.jsonValue)) - return false; - if (key == null) { - if (other.key != null) - return false; - } else if (!key.equals(other.key)) - return false; - return true; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("AdminSettingsEntity [id="); - builder.append(id); - builder.append(", key="); - builder.append(key); - builder.append(", jsonValue="); - builder.append(jsonValue); - builder.append("]"); - return builder.toString(); - } - @Override public AdminSettings toData() { AdminSettings adminSettings = new AdminSettings(new AdminSettingsId(id)); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/AlarmEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/AlarmEntity.java index 078699d8f8..9610d1375c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/AlarmEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/AlarmEntity.java @@ -18,6 +18,8 @@ package org.thingsboard.server.dao.model.nosql; import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.mapping.annotations.*; import com.fasterxml.jackson.databind.JsonNode; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmId; @@ -36,11 +38,10 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.*; @Table(name = ALARM_COLUMN_FAMILY_NAME) +@EqualsAndHashCode +@ToString public final class AlarmEntity implements BaseEntity { - @Transient - private static final long serialVersionUID = -1265181166886910152L; - @ClusteringColumn(value = 1) @Column(name = ID_PROPERTY) private UUID id; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/AssetEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/AssetEntity.java index 2f82e03e3f..3a36ce51bd 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/AssetEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/AssetEntity.java @@ -19,8 +19,9 @@ import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; -import com.datastax.driver.mapping.annotations.Transient; import com.fasterxml.jackson.databind.JsonNode; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.thingsboard.server.common.data.asset.Asset; import org.thingsboard.server.common.data.id.AssetId; import org.thingsboard.server.common.data.id.CustomerId; @@ -33,11 +34,10 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.*; @Table(name = ASSET_COLUMN_FAMILY_NAME) +@EqualsAndHashCode +@ToString public final class AssetEntity implements SearchTextEntity { - @Transient - private static final long serialVersionUID = -1265181166886910152L; - @PartitionKey(value = 0) @Column(name = ID_PROPERTY) private UUID id; @@ -132,7 +132,7 @@ public final class AssetEntity implements SearchTextEntity { @Override public String getSearchTextSource() { - return name; + return getName(); } @Override @@ -144,80 +144,6 @@ public final class AssetEntity implements SearchTextEntity { return searchText; } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode()); - result = prime * result + ((customerId == null) ? 0 : customerId.hashCode()); - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((type == null) ? 0 : type.hashCode()); - result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - AssetEntity other = (AssetEntity) obj; - if (additionalInfo == null) { - if (other.additionalInfo != null) - return false; - } else if (!additionalInfo.equals(other.additionalInfo)) - return false; - if (customerId == null) { - if (other.customerId != null) - return false; - } else if (!customerId.equals(other.customerId)) - return false; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (type == null) { - if (other.type != null) - return false; - } else if (!type.equals(other.type)) - return false; - if (tenantId == null) { - if (other.tenantId != null) - return false; - } else if (!tenantId.equals(other.tenantId)) - return false; - return true; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("AssetEntity [id="); - builder.append(id); - builder.append(", tenantId="); - builder.append(tenantId); - builder.append(", customerId="); - builder.append(customerId); - builder.append(", name="); - builder.append(name); - builder.append(", type="); - builder.append(type); - builder.append(", additionalInfo="); - builder.append(additionalInfo); - builder.append("]"); - return builder.toString(); - } - @Override public Asset toData() { Asset asset = new Asset(new AssetId(id)); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/ComponentDescriptorEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/ComponentDescriptorEntity.java index 2ff09a7a77..a07b6607ba 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/ComponentDescriptorEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/ComponentDescriptorEntity.java @@ -36,8 +36,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.*; @Table(name = COMPONENT_DESCRIPTOR_COLUMN_FAMILY_NAME) public class ComponentDescriptorEntity implements SearchTextEntity { - private static final long serialVersionUID = 1L; - @PartitionKey @Column(name = ID_PROPERTY) private UUID id; @@ -160,6 +158,6 @@ public class ComponentDescriptorEntity implements SearchTextEntity { - @Transient - private static final long serialVersionUID = -7732527103760948490L; - @PartitionKey(value = 0) @Column(name = ID_PROPERTY) private UUID id; @@ -197,7 +197,7 @@ public final class CustomerEntity implements SearchTextEntity { @Override public String getSearchTextSource() { - return title; + return getTitle(); } @Override @@ -209,128 +209,6 @@ public final class CustomerEntity implements SearchTextEntity { return searchText; } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode()); - result = prime * result + ((address == null) ? 0 : address.hashCode()); - result = prime * result + ((address2 == null) ? 0 : address2.hashCode()); - result = prime * result + ((city == null) ? 0 : city.hashCode()); - result = prime * result + ((country == null) ? 0 : country.hashCode()); - result = prime * result + ((email == null) ? 0 : email.hashCode()); - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((phone == null) ? 0 : phone.hashCode()); - result = prime * result + ((state == null) ? 0 : state.hashCode()); - result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode()); - result = prime * result + ((title == null) ? 0 : title.hashCode()); - result = prime * result + ((zip == null) ? 0 : zip.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - CustomerEntity other = (CustomerEntity) obj; - if (additionalInfo == null) { - if (other.additionalInfo != null) - return false; - } else if (!additionalInfo.equals(other.additionalInfo)) - return false; - if (address == null) { - if (other.address != null) - return false; - } else if (!address.equals(other.address)) - return false; - if (address2 == null) { - if (other.address2 != null) - return false; - } else if (!address2.equals(other.address2)) - return false; - if (city == null) { - if (other.city != null) - return false; - } else if (!city.equals(other.city)) - return false; - if (country == null) { - if (other.country != null) - return false; - } else if (!country.equals(other.country)) - return false; - if (email == null) { - if (other.email != null) - return false; - } else if (!email.equals(other.email)) - return false; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - if (phone == null) { - if (other.phone != null) - return false; - } else if (!phone.equals(other.phone)) - return false; - if (state == null) { - if (other.state != null) - return false; - } else if (!state.equals(other.state)) - return false; - if (tenantId == null) { - if (other.tenantId != null) - return false; - } else if (!tenantId.equals(other.tenantId)) - return false; - if (title == null) { - if (other.title != null) - return false; - } else if (!title.equals(other.title)) - return false; - if (zip == null) { - if (other.zip != null) - return false; - } else if (!zip.equals(other.zip)) - return false; - return true; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("CustomerEntity [id="); - builder.append(id); - builder.append(", tenantId="); - builder.append(tenantId); - builder.append(", title="); - builder.append(title); - builder.append(", country="); - builder.append(country); - builder.append(", state="); - builder.append(state); - builder.append(", city="); - builder.append(city); - builder.append(", address="); - builder.append(address); - builder.append(", address2="); - builder.append(address2); - builder.append(", zip="); - builder.append(zip); - builder.append(", phone="); - builder.append(phone); - builder.append(", email="); - builder.append(email); - builder.append(", additionalInfo="); - builder.append(additionalInfo); - builder.append("]"); - return builder.toString(); - } - @Override public Customer toData() { Customer customer = new Customer(new CustomerId(id)); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/DashboardEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/DashboardEntity.java index f246f92cbf..047a8f269e 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/DashboardEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/DashboardEntity.java @@ -19,8 +19,9 @@ import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; -import com.datastax.driver.mapping.annotations.Transient; import com.fasterxml.jackson.databind.JsonNode; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.thingsboard.server.common.data.Dashboard; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DashboardId; @@ -33,11 +34,10 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.*; @Table(name = DASHBOARD_COLUMN_FAMILY_NAME) +@EqualsAndHashCode +@ToString public final class DashboardEntity implements SearchTextEntity { - @Transient - private static final long serialVersionUID = 2998395951247446191L; - @PartitionKey(value = 0) @Column(name = ID_PROPERTY) private UUID id; @@ -119,7 +119,7 @@ public final class DashboardEntity implements SearchTextEntity { @Override public String getSearchTextSource() { - return title; + return getTitle(); } @Override @@ -131,80 +131,6 @@ public final class DashboardEntity implements SearchTextEntity { return searchText; } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((configuration == null) ? 0 : configuration.hashCode()); - result = prime * result + ((customerId == null) ? 0 : customerId.hashCode()); - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((searchText == null) ? 0 : searchText.hashCode()); - result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode()); - result = prime * result + ((title == null) ? 0 : title.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - DashboardEntity other = (DashboardEntity) obj; - if (configuration == null) { - if (other.configuration != null) - return false; - } else if (!configuration.equals(other.configuration)) - return false; - if (customerId == null) { - if (other.customerId != null) - return false; - } else if (!customerId.equals(other.customerId)) - return false; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - if (searchText == null) { - if (other.searchText != null) - return false; - } else if (!searchText.equals(other.searchText)) - return false; - if (tenantId == null) { - if (other.tenantId != null) - return false; - } else if (!tenantId.equals(other.tenantId)) - return false; - if (title == null) { - if (other.title != null) - return false; - } else if (!title.equals(other.title)) - return false; - return true; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("DashboardEntity [id="); - builder.append(id); - builder.append(", tenantId="); - builder.append(tenantId); - builder.append(", customerId="); - builder.append(customerId); - builder.append(", title="); - builder.append(title); - builder.append(", searchText="); - builder.append(searchText); - builder.append(", configuration="); - builder.append(configuration); - builder.append("]"); - return builder.toString(); - } - @Override public Dashboard toData() { Dashboard dashboard = new Dashboard(new DashboardId(id)); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/DashboardInfoEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/DashboardInfoEntity.java index 467c400a2f..a2a5280a30 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/DashboardInfoEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/DashboardInfoEntity.java @@ -19,7 +19,8 @@ import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; -import com.datastax.driver.mapping.annotations.Transient; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.thingsboard.server.common.data.DashboardInfo; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DashboardId; @@ -31,11 +32,10 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.*; @Table(name = DASHBOARD_COLUMN_FAMILY_NAME) +@EqualsAndHashCode +@ToString public class DashboardInfoEntity implements SearchTextEntity { - @Transient - private static final long serialVersionUID = 2998395951247446191L; - @PartitionKey(value = 0) @Column(name = ID_PROPERTY) private UUID id; @@ -105,7 +105,7 @@ public class DashboardInfoEntity implements SearchTextEntity { @Override public String getSearchTextSource() { - return title; + return getTitle(); } @Override @@ -117,72 +117,6 @@ public class DashboardInfoEntity implements SearchTextEntity { return searchText; } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((customerId == null) ? 0 : customerId.hashCode()); - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((searchText == null) ? 0 : searchText.hashCode()); - result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode()); - result = prime * result + ((title == null) ? 0 : title.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - DashboardInfoEntity other = (DashboardInfoEntity) obj; - if (customerId == null) { - if (other.customerId != null) - return false; - } else if (!customerId.equals(other.customerId)) - return false; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - if (searchText == null) { - if (other.searchText != null) - return false; - } else if (!searchText.equals(other.searchText)) - return false; - if (tenantId == null) { - if (other.tenantId != null) - return false; - } else if (!tenantId.equals(other.tenantId)) - return false; - if (title == null) { - if (other.title != null) - return false; - } else if (!title.equals(other.title)) - return false; - return true; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("DashboardInfoEntity [id="); - builder.append(id); - builder.append(", tenantId="); - builder.append(tenantId); - builder.append(", customerId="); - builder.append(customerId); - builder.append(", title="); - builder.append(title); - builder.append(", searchText="); - builder.append(searchText); - builder.append("]"); - return builder.toString(); - } - @Override public DashboardInfo toData() { DashboardInfo dashboardInfo = new DashboardInfo(new DashboardId(id)); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/DeviceCredentialsEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/DeviceCredentialsEntity.java index 806af3b3b5..f51942eeb8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/DeviceCredentialsEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/DeviceCredentialsEntity.java @@ -19,7 +19,8 @@ import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; -import com.datastax.driver.mapping.annotations.Transient; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.thingsboard.server.common.data.id.DeviceCredentialsId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.security.DeviceCredentials; @@ -32,11 +33,10 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.*; @Table(name = DEVICE_CREDENTIALS_COLUMN_FAMILY_NAME) +@EqualsAndHashCode +@ToString public final class DeviceCredentialsEntity implements BaseEntity { - @Transient - private static final long serialVersionUID = -2667310560260623272L; - @PartitionKey(value = 0) @Column(name = ID_PROPERTY) private UUID id; @@ -109,69 +109,6 @@ public final class DeviceCredentialsEntity implements BaseEntity { - @Transient - private static final long serialVersionUID = -1265181166886910152L; - @PartitionKey(value = 0) @Column(name = ID_PROPERTY) private UUID id; @@ -132,7 +132,7 @@ public final class DeviceEntity implements SearchTextEntity { @Override public String getSearchTextSource() { - return name; + return getName(); } @Override @@ -144,80 +144,6 @@ public final class DeviceEntity implements SearchTextEntity { return searchText; } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode()); - result = prime * result + ((customerId == null) ? 0 : customerId.hashCode()); - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((name == null) ? 0 : name.hashCode()); - result = prime * result + ((type == null) ? 0 : type.hashCode()); - result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - DeviceEntity other = (DeviceEntity) obj; - if (additionalInfo == null) { - if (other.additionalInfo != null) - return false; - } else if (!additionalInfo.equals(other.additionalInfo)) - return false; - if (customerId == null) { - if (other.customerId != null) - return false; - } else if (!customerId.equals(other.customerId)) - return false; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - if (name == null) { - if (other.name != null) - return false; - } else if (!name.equals(other.name)) - return false; - if (type == null) { - if (other.type != null) - return false; - } else if (!type.equals(other.type)) - return false; - if (tenantId == null) { - if (other.tenantId != null) - return false; - } else if (!tenantId.equals(other.tenantId)) - return false; - return true; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("DeviceEntity [id="); - builder.append(id); - builder.append(", tenantId="); - builder.append(tenantId); - builder.append(", customerId="); - builder.append(customerId); - builder.append(", name="); - builder.append(name); - builder.append(", type="); - builder.append(type); - builder.append(", additionalInfo="); - builder.append(additionalInfo); - builder.append("]"); - return builder.toString(); - } - @Override public Device toData() { Device device = new Device(new DeviceId(id)); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/EventEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/EventEntity.java index 55945731b1..380c620ab4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/EventEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/EventEntity.java @@ -41,9 +41,6 @@ import static org.thingsboard.server.dao.model.ModelConstants.*; @Table(name = EVENT_COLUMN_FAMILY_NAME) public class EventEntity implements BaseEntity { - @Transient - private static final long serialVersionUID = -1265181166886910153L; - @Column(name = ID_PROPERTY) private UUID id; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/PluginMetaDataEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/PluginMetaDataEntity.java index 3d2e6b3c96..8e50cceceb 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/PluginMetaDataEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/PluginMetaDataEntity.java @@ -18,6 +18,8 @@ package org.thingsboard.server.dao.model.nosql; import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.mapping.annotations.*; import com.fasterxml.jackson.databind.JsonNode; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.thingsboard.server.common.data.id.PluginId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentLifecycleState; @@ -32,11 +34,10 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.*; @Table(name = PLUGIN_COLUMN_FAMILY_NAME) +@EqualsAndHashCode +@ToString public class PluginMetaDataEntity implements SearchTextEntity { - @Transient - private static final long serialVersionUID = -5231612734979707866L; - @PartitionKey @Column(name = ID_PROPERTY) private UUID id; @@ -89,7 +90,7 @@ public class PluginMetaDataEntity implements SearchTextEntity { @Override public String getSearchTextSource() { - return searchText; + return getSearchText(); } @Override @@ -190,27 +191,4 @@ public class PluginMetaDataEntity implements SearchTextEntity { return data; } - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - PluginMetaDataEntity entity = (PluginMetaDataEntity) o; - return Objects.equals(id, entity.id) && Objects.equals(apiToken, entity.apiToken) && Objects.equals(tenantId, entity.tenantId) - && Objects.equals(name, entity.name) && Objects.equals(clazz, entity.clazz) && Objects.equals(state, entity.state) - && Objects.equals(configuration, entity.configuration) - && Objects.equals(searchText, entity.searchText); - } - - @Override - public int hashCode() { - return Objects.hash(id, apiToken, tenantId, name, clazz, state, configuration, searchText); - } - - @Override - public String toString() { - return "PluginMetaDataEntity{" + "id=" + id + ", apiToken='" + apiToken + '\'' + ", tenantId=" + tenantId + ", name='" + name + '\'' + ", clazz='" - + clazz + '\'' + ", state=" + state + ", configuration=" + configuration + ", searchText='" + searchText + '\'' + '}'; - } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/RuleMetaDataEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/RuleMetaDataEntity.java index b278aeabb6..1b1402a2d7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/RuleMetaDataEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/RuleMetaDataEntity.java @@ -21,6 +21,8 @@ import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; import com.fasterxml.jackson.databind.JsonNode; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.thingsboard.server.common.data.id.RuleId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.plugin.ComponentLifecycleState; @@ -30,17 +32,15 @@ import org.thingsboard.server.dao.model.SearchTextEntity; import org.thingsboard.server.dao.model.type.ComponentLifecycleStateCodec; import org.thingsboard.server.dao.model.type.JsonCodec; -import javax.persistence.Transient; -import java.util.Objects; import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.*; @Table(name = RULE_COLUMN_FAMILY_NAME) +@EqualsAndHashCode +@ToString public class RuleMetaDataEntity implements SearchTextEntity { - @Transient - private static final long serialVersionUID = 4011728715100800304L; @PartitionKey @Column(name = ID_PROPERTY) private UUID id; @@ -87,7 +87,7 @@ public class RuleMetaDataEntity implements SearchTextEntity { @Override public String getSearchTextSource() { - return searchText; + return getSearchText(); } @Override @@ -197,35 +197,4 @@ public class RuleMetaDataEntity implements SearchTextEntity { return rule; } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - RuleMetaDataEntity that = (RuleMetaDataEntity) o; - return weight == that.weight && - Objects.equals(id, that.id) && - Objects.equals(tenantId, that.tenantId) && - Objects.equals(name, that.name) && - Objects.equals(pluginToken, that.pluginToken) && - Objects.equals(state, that.state) && - Objects.equals(searchText, that.searchText); - } - - @Override - public int hashCode() { - return Objects.hash(id, tenantId, name, pluginToken, state, weight, searchText); - } - - @Override - public String toString() { - return "RuleMetaDataEntity{" + - "id=" + id + - ", tenantId=" + tenantId + - ", name='" + name + '\'' + - ", pluginToken='" + pluginToken + '\'' + - ", state='" + state + '\'' + - ", weight=" + weight + - ", searchText='" + searchText + '\'' + - '}'; - } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/TenantEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/TenantEntity.java index 8adb57449b..a143f0af76 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/TenantEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/TenantEntity.java @@ -19,8 +19,9 @@ import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; -import com.datastax.driver.mapping.annotations.Transient; import com.fasterxml.jackson.databind.JsonNode; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.dao.model.SearchTextEntity; @@ -31,11 +32,10 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.*; @Table(name = TENANT_COLUMN_FAMILY_NAME) +@EqualsAndHashCode +@ToString public final class TenantEntity implements SearchTextEntity { - @Transient - private static final long serialVersionUID = -6198635547142409206L; - @PartitionKey(value = 0) @Column(name = ID_PROPERTY) private UUID id; @@ -195,7 +195,7 @@ public final class TenantEntity implements SearchTextEntity { @Override public String getSearchTextSource() { - return title; + return getTitle(); } @Override @@ -207,128 +207,6 @@ public final class TenantEntity implements SearchTextEntity { return searchText; } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode()); - result = prime * result + ((address == null) ? 0 : address.hashCode()); - result = prime * result + ((address2 == null) ? 0 : address2.hashCode()); - result = prime * result + ((city == null) ? 0 : city.hashCode()); - result = prime * result + ((country == null) ? 0 : country.hashCode()); - result = prime * result + ((email == null) ? 0 : email.hashCode()); - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((phone == null) ? 0 : phone.hashCode()); - result = prime * result + ((region == null) ? 0 : region.hashCode()); - result = prime * result + ((state == null) ? 0 : state.hashCode()); - result = prime * result + ((title == null) ? 0 : title.hashCode()); - result = prime * result + ((zip == null) ? 0 : zip.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - TenantEntity other = (TenantEntity) obj; - if (additionalInfo == null) { - if (other.additionalInfo != null) - return false; - } else if (!additionalInfo.equals(other.additionalInfo)) - return false; - if (address == null) { - if (other.address != null) - return false; - } else if (!address.equals(other.address)) - return false; - if (address2 == null) { - if (other.address2 != null) - return false; - } else if (!address2.equals(other.address2)) - return false; - if (city == null) { - if (other.city != null) - return false; - } else if (!city.equals(other.city)) - return false; - if (country == null) { - if (other.country != null) - return false; - } else if (!country.equals(other.country)) - return false; - if (email == null) { - if (other.email != null) - return false; - } else if (!email.equals(other.email)) - return false; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - if (phone == null) { - if (other.phone != null) - return false; - } else if (!phone.equals(other.phone)) - return false; - if (region == null) { - if (other.region != null) - return false; - } else if (!region.equals(other.region)) - return false; - if (state == null) { - if (other.state != null) - return false; - } else if (!state.equals(other.state)) - return false; - if (title == null) { - if (other.title != null) - return false; - } else if (!title.equals(other.title)) - return false; - if (zip == null) { - if (other.zip != null) - return false; - } else if (!zip.equals(other.zip)) - return false; - return true; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("TenantEntity [id="); - builder.append(id); - builder.append(", title="); - builder.append(title); - builder.append(", region="); - builder.append(region); - builder.append(", country="); - builder.append(country); - builder.append(", state="); - builder.append(state); - builder.append(", city="); - builder.append(city); - builder.append(", address="); - builder.append(address); - builder.append(", address2="); - builder.append(address2); - builder.append(", zip="); - builder.append(zip); - builder.append(", phone="); - builder.append(phone); - builder.append(", email="); - builder.append(email); - builder.append(", additionalInfo="); - builder.append(additionalInfo); - builder.append("]"); - return builder.toString(); - } - @Override public Tenant toData() { Tenant tenant = new Tenant(new TenantId(id)); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/UserCredentialsEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/UserCredentialsEntity.java index d748d7fad5..6cb1c9fedf 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/UserCredentialsEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/UserCredentialsEntity.java @@ -19,7 +19,7 @@ import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; -import com.datastax.driver.mapping.annotations.Transient; +import lombok.EqualsAndHashCode; import org.thingsboard.server.common.data.id.UserCredentialsId; import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.security.UserCredentials; @@ -30,11 +30,9 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.*; @Table(name = USER_CREDENTIALS_COLUMN_FAMILY_NAME) +@EqualsAndHashCode public final class UserCredentialsEntity implements BaseEntity { - @Transient - private static final long serialVersionUID = 1348221414123438374L; - @PartitionKey(value = 0) @Column(name = ID_PROPERTY) private UUID id; @@ -119,58 +117,6 @@ public final class UserCredentialsEntity implements BaseEntity this.resetToken = resetToken; } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((activateToken == null) ? 0 : activateToken.hashCode()); - result = prime * result + (enabled ? 1231 : 1237); - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((password == null) ? 0 : password.hashCode()); - result = prime * result + ((resetToken == null) ? 0 : resetToken.hashCode()); - result = prime * result + ((userId == null) ? 0 : userId.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - UserCredentialsEntity other = (UserCredentialsEntity) obj; - if (activateToken == null) { - if (other.activateToken != null) - return false; - } else if (!activateToken.equals(other.activateToken)) - return false; - if (enabled != other.enabled) - return false; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - if (password == null) { - if (other.password != null) - return false; - } else if (!password.equals(other.password)) - return false; - if (resetToken == null) { - if (other.resetToken != null) - return false; - } else if (!resetToken.equals(other.resetToken)) - return false; - if (userId == null) { - if (other.userId != null) - return false; - } else if (!userId.equals(other.userId)) - return false; - return true; - } - @Override public UserCredentials toData() { UserCredentials userCredentials = new UserCredentials(new UserCredentialsId(id)); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/UserEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/UserEntity.java index 50d336caf5..bbdebe9fbc 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/UserEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/UserEntity.java @@ -19,8 +19,9 @@ import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; -import com.datastax.driver.mapping.annotations.Transient; import com.fasterxml.jackson.databind.JsonNode; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.thingsboard.server.common.data.User; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.TenantId; @@ -35,11 +36,10 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.*; @Table(name = USER_COLUMN_FAMILY_NAME) +@EqualsAndHashCode +@ToString public final class UserEntity implements SearchTextEntity { - @Transient - private static final long serialVersionUID = -7740338274987723489L; - @PartitionKey(value = 0) @Column(name = ID_PROPERTY) private UUID id; @@ -158,7 +158,7 @@ public final class UserEntity implements SearchTextEntity { @Override public String getSearchTextSource() { - return email; + return getEmail(); } @Override @@ -170,93 +170,6 @@ public final class UserEntity implements SearchTextEntity { return searchText; } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((additionalInfo == null) ? 0 : additionalInfo.hashCode()); - result = prime * result + ((authority == null) ? 0 : authority.hashCode()); - result = prime * result + ((customerId == null) ? 0 : customerId.hashCode()); - result = prime * result + ((email == null) ? 0 : email.hashCode()); - result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); - result = prime * result + ((id == null) ? 0 : id.hashCode()); - result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); - result = prime * result + ((tenantId == null) ? 0 : tenantId.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - UserEntity other = (UserEntity) obj; - if (additionalInfo == null) { - if (other.additionalInfo != null) - return false; - } else if (!additionalInfo.equals(other.additionalInfo)) - return false; - if (authority != other.authority) - return false; - if (customerId == null) { - if (other.customerId != null) - return false; - } else if (!customerId.equals(other.customerId)) - return false; - if (email == null) { - if (other.email != null) - return false; - } else if (!email.equals(other.email)) - return false; - if (firstName == null) { - if (other.firstName != null) - return false; - } else if (!firstName.equals(other.firstName)) - return false; - if (id == null) { - if (other.id != null) - return false; - } else if (!id.equals(other.id)) - return false; - if (lastName == null) { - if (other.lastName != null) - return false; - } else if (!lastName.equals(other.lastName)) - return false; - if (tenantId == null) { - if (other.tenantId != null) - return false; - } else if (!tenantId.equals(other.tenantId)) - return false; - return true; - } - - @Override - public String toString() { - StringBuilder builder = new StringBuilder(); - builder.append("UserEntity [id="); - builder.append(id); - builder.append(", authority="); - builder.append(authority); - builder.append(", tenantId="); - builder.append(tenantId); - builder.append(", customerId="); - builder.append(customerId); - builder.append(", email="); - builder.append(email); - builder.append(", firstName="); - builder.append(firstName); - builder.append(", lastName="); - builder.append(lastName); - builder.append(", additionalInfo="); - builder.append(additionalInfo); - builder.append("]"); - return builder.toString(); - } - @Override public User toData() { User user = new User(new UserId(id)); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/WidgetTypeEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/WidgetTypeEntity.java index fa476d7eea..3806f59b5a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/WidgetTypeEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/WidgetTypeEntity.java @@ -19,8 +19,9 @@ import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; -import com.datastax.driver.mapping.annotations.Transient; import com.fasterxml.jackson.databind.JsonNode; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.WidgetTypeId; import org.thingsboard.server.common.data.widget.WidgetType; @@ -32,11 +33,10 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.*; @Table(name = WIDGET_TYPE_COLUMN_FAMILY_NAME) +@EqualsAndHashCode +@ToString public final class WidgetTypeEntity implements BaseEntity { - @Transient - private static final long serialVersionUID = 3591054897680176342L; - @PartitionKey(value = 0) @Column(name = ID_PROPERTY) private UUID id; @@ -125,45 +125,6 @@ public final class WidgetTypeEntity implements BaseEntity { this.descriptor = descriptor; } - @Override - public int hashCode() { - int result = id != null ? id.hashCode() : 0; - result = 31 * result + (tenantId != null ? tenantId.hashCode() : 0); - result = 31 * result + (bundleAlias != null ? bundleAlias.hashCode() : 0); - result = 31 * result + (alias != null ? alias.hashCode() : 0); - result = 31 * result + (name != null ? name.hashCode() : 0); - result = 31 * result + (descriptor != null ? descriptor.hashCode() : 0); - return result; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - WidgetTypeEntity that = (WidgetTypeEntity) o; - - if (id != null ? !id.equals(that.id) : that.id != null) return false; - if (tenantId != null ? !tenantId.equals(that.tenantId) : that.tenantId != null) return false; - if (bundleAlias != null ? !bundleAlias.equals(that.bundleAlias) : that.bundleAlias != null) return false; - if (alias != null ? !alias.equals(that.alias) : that.alias != null) return false; - if (name != null ? !name.equals(that.name) : that.name != null) return false; - return descriptor != null ? descriptor.equals(that.descriptor) : that.descriptor == null; - } - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder("WidgetTypeEntity{"); - sb.append("id=").append(id); - sb.append(", tenantId=").append(tenantId); - sb.append(", bundleAlias='").append(bundleAlias).append('\''); - sb.append(", alias='").append(alias).append('\''); - sb.append(", name ='").append(name).append('\''); - sb.append(", descriptor=").append(descriptor); - sb.append('}'); - return sb.toString(); - } - @Override public WidgetType toData() { WidgetType widgetType = new WidgetType(new WidgetTypeId(id)); diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/WidgetsBundleEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/WidgetsBundleEntity.java index 75cce98eaf..8b9ca81054 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/nosql/WidgetsBundleEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/nosql/WidgetsBundleEntity.java @@ -20,7 +20,8 @@ import com.datastax.driver.core.utils.UUIDs; import com.datastax.driver.mapping.annotations.Column; import com.datastax.driver.mapping.annotations.PartitionKey; import com.datastax.driver.mapping.annotations.Table; -import com.datastax.driver.mapping.annotations.Transient; +import lombok.EqualsAndHashCode; +import lombok.ToString; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.WidgetsBundleId; import org.thingsboard.server.common.data.widget.WidgetsBundle; @@ -32,11 +33,10 @@ import java.util.UUID; import static org.thingsboard.server.dao.model.ModelConstants.*; @Table(name = WIDGETS_BUNDLE_COLUMN_FAMILY_NAME) +@EqualsAndHashCode +@ToString public final class WidgetsBundleEntity implements SearchTextEntity { - @Transient - private static final long serialVersionUID = -8842195928585650849L; - @PartitionKey(value = 0) @Column(name = ID_PROPERTY) private UUID id; @@ -119,7 +119,7 @@ public final class WidgetsBundleEntity implements SearchTextEntity implements SearchTextEntity { - @Transient - private static final long serialVersionUID = -271106508790582977L; @Column(name = ModelConstants.USER_TENANT_ID_PROPERTY) private String tenantId; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java index 15e6549fc2..4224655214 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetTypeEntity.java @@ -32,7 +32,6 @@ import org.thingsboard.server.dao.util.mapping.JsonStringType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; -import javax.persistence.Transient; @Data @EqualsAndHashCode(callSuper = true) @@ -41,9 +40,6 @@ import javax.persistence.Transient; @Table(name = ModelConstants.WIDGET_TYPE_COLUMN_FAMILY_NAME) public final class WidgetTypeEntity extends BaseSqlEntity implements BaseEntity { - @Transient - private static final long serialVersionUID = -5436279069884988630L; - @Column(name = ModelConstants.WIDGET_TYPE_TENANT_ID_PROPERTY) private String tenantId; diff --git a/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetsBundleEntity.java b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetsBundleEntity.java index 4cc0fc65c6..d6f6d77213 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetsBundleEntity.java +++ b/dao/src/main/java/org/thingsboard/server/dao/model/sql/WidgetsBundleEntity.java @@ -30,7 +30,6 @@ import org.thingsboard.server.dao.model.SearchTextEntity; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; -import javax.persistence.Transient; @Data @EqualsAndHashCode(callSuper = true) @@ -38,9 +37,6 @@ import javax.persistence.Transient; @Table(name = ModelConstants.WIDGETS_BUNDLE_COLUMN_FAMILY_NAME) public final class WidgetsBundleEntity extends BaseSqlEntity implements SearchTextEntity { - @Transient - private static final long serialVersionUID = 6897035686422298096L; - @Column(name = ModelConstants.WIDGETS_BUNDLE_TENANT_ID_PROPERTY) private String tenantId; diff --git a/dao/src/main/java/org/thingsboard/server/dao/plugin/CassandraBasePluginDao.java b/dao/src/main/java/org/thingsboard/server/dao/plugin/CassandraBasePluginDao.java index 1ff2f22c80..fc39c06f02 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/plugin/CassandraBasePluginDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/plugin/CassandraBasePluginDao.java @@ -40,6 +40,8 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; @NoSqlDao public class CassandraBasePluginDao extends CassandraAbstractSearchTextDao implements PluginDao { + public static final String SEARCH_RESULT = "Search result: [{}]"; + @Override protected Class getColumnFamilyClass() { return PluginMetaDataEntity.class; @@ -57,7 +59,7 @@ public class CassandraBasePluginDao extends CassandraAbstractSearchTextDao entities = findPageWithTextSearch(ModelConstants.PLUGIN_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, Arrays.asList(eq(ModelConstants.PLUGIN_TENANT_ID_PROPERTY, tenantId.getId())), pageLink); if (log.isTraceEnabled()) { - log.trace("Search result: [{}]", Arrays.toString(entities.toArray())); + log.trace(SEARCH_RESULT, Arrays.toString(entities.toArray())); } else { - log.debug("Search result: [{}]", entities.size()); + log.debug(SEARCH_RESULT, entities.size()); } return DaoUtil.convertDataList(entities); } @@ -108,9 +110,9 @@ public class CassandraBasePluginDao extends CassandraAbstractSearchTextDao rs != null ? getEntityRelation(rs.one()) : null); } + @Override + public boolean saveRelation(EntityRelation relation) { + BoundStatement stmt = getSaveRelationStatement(relation); + ResultSet rs = executeWrite(stmt); + return rs.wasApplied(); + } @Override - public ListenableFuture saveRelation(EntityRelation relation) { + public ListenableFuture saveRelationAsync(EntityRelation relation) { + BoundStatement stmt = getSaveRelationStatement(relation); + ResultSetFuture future = executeAsyncWrite(stmt); + return getBooleanListenableFuture(future); + } + + private BoundStatement getSaveRelationStatement(EntityRelation relation) { BoundStatement stmt = getSaveStmt().bind() .setUUID(0, relation.getFrom().getId()) .setString(1, relation.getFrom().getEntityType().name()) @@ -150,17 +163,34 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati .set(4, relation.getTypeGroup(), relationTypeGroupCodec) .setString(5, relation.getType()) .set(6, relation.getAdditionalInfo(), JsonNode.class); - ResultSetFuture future = executeAsyncWrite(stmt); - return getBooleanListenableFuture(future); + return stmt; } @Override - public ListenableFuture deleteRelation(EntityRelation relation) { + public boolean deleteRelation(EntityRelation relation) { return deleteRelation(relation.getFrom(), relation.getTo(), relation.getType(), relation.getTypeGroup()); } @Override - public ListenableFuture deleteRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { + public ListenableFuture deleteRelationAsync(EntityRelation relation) { + return deleteRelationAsync(relation.getFrom(), relation.getTo(), relation.getType(), relation.getTypeGroup()); + } + + @Override + public boolean deleteRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { + BoundStatement stmt = getDeleteRelationStatement(from, to, relationType, typeGroup); + ResultSet rs = executeWrite(stmt); + return rs.wasApplied(); + } + + @Override + public ListenableFuture deleteRelationAsync(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { + BoundStatement stmt = getDeleteRelationStatement(from, to, relationType, typeGroup); + ResultSetFuture future = executeAsyncWrite(stmt); + return getBooleanListenableFuture(future); + } + + private BoundStatement getDeleteRelationStatement(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { BoundStatement stmt = getDeleteStmt().bind() .setUUID(0, from.getId()) .setString(1, from.getEntityType().name()) @@ -168,12 +198,21 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati .setString(3, to.getEntityType().name()) .set(4, typeGroup, relationTypeGroupCodec) .setString(5, relationType); - ResultSetFuture future = executeAsyncWrite(stmt); - return getBooleanListenableFuture(future); + return stmt; } @Override - public ListenableFuture deleteOutboundRelations(EntityId entity) { + public boolean deleteOutboundRelations(EntityId entity) { + BoundStatement stmt = getDeleteAllByEntityStmt().bind() + .setUUID(0, entity.getId()) + .setString(1, entity.getEntityType().name()); + ResultSet rs = executeWrite(stmt); + return rs.wasApplied(); + } + + + @Override + public ListenableFuture deleteOutboundRelationsAsync(EntityId entity) { BoundStatement stmt = getDeleteAllByEntityStmt().bind() .setUUID(0, entity.getId()) .setString(1, entity.getEntityType().name()); @@ -242,9 +281,9 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati if (findAllByFromStmt == null) { findAllByFromStmt = getSession().prepare(SELECT_COLUMNS + " " + FROM + ModelConstants.RELATION_COLUMN_FAMILY_NAME + " " + - WHERE + ModelConstants.RELATION_FROM_ID_PROPERTY + " = ? " + - AND + ModelConstants.RELATION_FROM_TYPE_PROPERTY + " = ? " + - AND + ModelConstants.RELATION_TYPE_GROUP_PROPERTY + " = ? "); + WHERE + ModelConstants.RELATION_FROM_ID_PROPERTY + EQUAL_TO_PARAM + + AND + ModelConstants.RELATION_FROM_TYPE_PROPERTY + EQUAL_TO_PARAM + + AND + ModelConstants.RELATION_TYPE_GROUP_PROPERTY + EQUAL_TO_PARAM); } return findAllByFromStmt; } @@ -253,10 +292,10 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati if (findAllByFromAndTypeStmt == null) { findAllByFromAndTypeStmt = getSession().prepare(SELECT_COLUMNS + " " + FROM + ModelConstants.RELATION_COLUMN_FAMILY_NAME + " " + - WHERE + ModelConstants.RELATION_FROM_ID_PROPERTY + " = ? " + - AND + ModelConstants.RELATION_FROM_TYPE_PROPERTY + " = ? " + - AND + ModelConstants.RELATION_TYPE_GROUP_PROPERTY + " = ? " + - AND + ModelConstants.RELATION_TYPE_PROPERTY + " = ? "); + WHERE + ModelConstants.RELATION_FROM_ID_PROPERTY + EQUAL_TO_PARAM + + AND + ModelConstants.RELATION_FROM_TYPE_PROPERTY + EQUAL_TO_PARAM + + AND + ModelConstants.RELATION_TYPE_GROUP_PROPERTY + EQUAL_TO_PARAM + + AND + ModelConstants.RELATION_TYPE_PROPERTY + EQUAL_TO_PARAM); } return findAllByFromAndTypeStmt; } @@ -266,9 +305,9 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati if (findAllByToStmt == null) { findAllByToStmt = getSession().prepare(SELECT_COLUMNS + " " + FROM + ModelConstants.RELATION_REVERSE_VIEW_NAME + " " + - WHERE + ModelConstants.RELATION_TO_ID_PROPERTY + " = ? " + - AND + ModelConstants.RELATION_TO_TYPE_PROPERTY + " = ? " + - AND + ModelConstants.RELATION_TYPE_GROUP_PROPERTY + " = ? "); + WHERE + ModelConstants.RELATION_TO_ID_PROPERTY + EQUAL_TO_PARAM + + AND + ModelConstants.RELATION_TO_TYPE_PROPERTY + EQUAL_TO_PARAM + + AND + ModelConstants.RELATION_TYPE_GROUP_PROPERTY + EQUAL_TO_PARAM); } return findAllByToStmt; } @@ -277,10 +316,10 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati if (findAllByToAndTypeStmt == null) { findAllByToAndTypeStmt = getSession().prepare(SELECT_COLUMNS + " " + FROM + ModelConstants.RELATION_REVERSE_VIEW_NAME + " " + - WHERE + ModelConstants.RELATION_TO_ID_PROPERTY + " = ? " + - AND + ModelConstants.RELATION_TO_TYPE_PROPERTY + " = ? " + - AND + ModelConstants.RELATION_TYPE_GROUP_PROPERTY + " = ? " + - AND + ModelConstants.RELATION_TYPE_PROPERTY + " = ? "); + WHERE + ModelConstants.RELATION_TO_ID_PROPERTY + EQUAL_TO_PARAM + + AND + ModelConstants.RELATION_TO_TYPE_PROPERTY + EQUAL_TO_PARAM + + AND + ModelConstants.RELATION_TYPE_GROUP_PROPERTY + EQUAL_TO_PARAM + + AND + ModelConstants.RELATION_TYPE_PROPERTY + EQUAL_TO_PARAM); } return findAllByToAndTypeStmt; } @@ -290,12 +329,12 @@ public class BaseRelationDao extends CassandraAbstractAsyncDao implements Relati if (checkRelationStmt == null) { checkRelationStmt = getSession().prepare(SELECT_COLUMNS + " " + FROM + ModelConstants.RELATION_COLUMN_FAMILY_NAME + " " + - WHERE + ModelConstants.RELATION_FROM_ID_PROPERTY + " = ? " + - AND + ModelConstants.RELATION_FROM_TYPE_PROPERTY + " = ? " + - AND + ModelConstants.RELATION_TO_ID_PROPERTY + " = ? " + - AND + ModelConstants.RELATION_TO_TYPE_PROPERTY + " = ? " + - AND + ModelConstants.RELATION_TYPE_GROUP_PROPERTY + " = ? " + - AND + ModelConstants.RELATION_TYPE_PROPERTY + " = ? "); + WHERE + ModelConstants.RELATION_FROM_ID_PROPERTY + EQUAL_TO_PARAM + + AND + ModelConstants.RELATION_FROM_TYPE_PROPERTY + EQUAL_TO_PARAM + + AND + ModelConstants.RELATION_TO_ID_PROPERTY + EQUAL_TO_PARAM + + AND + ModelConstants.RELATION_TO_TYPE_PROPERTY + EQUAL_TO_PARAM + + AND + ModelConstants.RELATION_TYPE_GROUP_PROPERTY + EQUAL_TO_PARAM + + AND + ModelConstants.RELATION_TYPE_PROPERTY + EQUAL_TO_PARAM); } return checkRelationStmt; } diff --git a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java index 9f333dcb42..3574e83d7d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/relation/BaseRelationService.java @@ -31,6 +31,7 @@ import org.thingsboard.server.dao.exception.DataValidationException; import javax.annotation.Nullable; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutionException; import java.util.function.BiConsumer; /** @@ -61,28 +62,49 @@ public class BaseRelationService implements RelationService { } @Override - public ListenableFuture saveRelation(EntityRelation relation) { + public boolean saveRelation(EntityRelation relation) { log.trace("Executing saveRelation [{}]", relation); validate(relation); return relationDao.saveRelation(relation); } @Override - public ListenableFuture deleteRelation(EntityRelation relation) { + public ListenableFuture saveRelationAsync(EntityRelation relation) { + log.trace("Executing saveRelationAsync [{}]", relation); + validate(relation); + return relationDao.saveRelationAsync(relation); + } + + @Override + public boolean deleteRelation(EntityRelation relation) { log.trace("Executing deleteRelation [{}]", relation); validate(relation); return relationDao.deleteRelation(relation); } @Override - public ListenableFuture deleteRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { + public ListenableFuture deleteRelationAsync(EntityRelation relation) { + log.trace("Executing deleteRelationAsync [{}]", relation); + validate(relation); + return relationDao.deleteRelationAsync(relation); + } + + @Override + public boolean deleteRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { log.trace("Executing deleteRelation [{}][{}][{}][{}]", from, to, relationType, typeGroup); validate(from, to, relationType, typeGroup); return relationDao.deleteRelation(from, to, relationType, typeGroup); } @Override - public ListenableFuture deleteEntityRelations(EntityId entity) { + public ListenableFuture deleteRelationAsync(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { + log.trace("Executing deleteRelationAsync [{}][{}][{}][{}]", from, to, relationType, typeGroup); + validate(from, to, relationType, typeGroup); + return relationDao.deleteRelationAsync(from, to, relationType, typeGroup); + } + + @Override + public boolean deleteEntityRelations(EntityId entity) { log.trace("Executing deleteEntityRelations [{}]", entity); validate(entity); List>> inboundRelationsList = new ArrayList<>(); @@ -90,12 +112,42 @@ public class BaseRelationService implements RelationService { inboundRelationsList.add(relationDao.findAllByTo(entity, typeGroup)); } ListenableFuture>> inboundRelations = Futures.allAsList(inboundRelationsList); + ListenableFuture> inboundDeletions = Futures.transform(inboundRelations, new Function>, List>() { + @Override + public List apply(List> relations) { + List results = new ArrayList<>(); + for (List relationList : relations) { + relationList.stream().forEach(relation -> results.add(relationDao.deleteRelation(relation))); + } + return results; + } + }); + ListenableFuture inboundFuture = Futures.transform(inboundDeletions, getListToBooleanFunction()); + boolean inboundDeleteResult = false; + try { + inboundDeleteResult = inboundFuture.get(); + } catch (InterruptedException | ExecutionException e) { + log.error("Error deleting entity inbound relations", e); + } + boolean outboundDeleteResult = relationDao.deleteOutboundRelations(entity); + return inboundDeleteResult && outboundDeleteResult; + } + + @Override + public ListenableFuture deleteEntityRelationsAsync(EntityId entity) { + log.trace("Executing deleteEntityRelationsAsync [{}]", entity); + validate(entity); + List>> inboundRelationsList = new ArrayList<>(); + for (RelationTypeGroup typeGroup : RelationTypeGroup.values()) { + inboundRelationsList.add(relationDao.findAllByTo(entity, typeGroup)); + } + ListenableFuture>> inboundRelations = Futures.allAsList(inboundRelationsList); ListenableFuture> inboundDeletions = Futures.transform(inboundRelations, new AsyncFunction>, List>() { @Override public ListenableFuture> apply(List> relations) throws Exception { List> results = new ArrayList<>(); for (List relationList : relations) { - relationList.stream().forEach(relation -> results.add(relationDao.deleteRelation(relation))); + relationList.stream().forEach(relation -> results.add(relationDao.deleteRelationAsync(relation))); } return Futures.allAsList(results); } @@ -103,7 +155,7 @@ public class BaseRelationService implements RelationService { ListenableFuture inboundFuture = Futures.transform(inboundDeletions, getListToBooleanFunction()); - ListenableFuture outboundFuture = relationDao.deleteOutboundRelations(entity); + ListenableFuture outboundFuture = relationDao.deleteOutboundRelationsAsync(entity); return Futures.transform(Futures.allAsList(Arrays.asList(inboundFuture, outboundFuture)), getListToBooleanFunction()); } @@ -208,16 +260,13 @@ public class BaseRelationService implements RelationService { ListenableFuture> relationSet = findRelationsRecursively(params.getEntityId(), params.getDirection(), maxLvl, new ConcurrentHashMap<>()); return Futures.transform(relationSet, (Function, List>) input -> { List relations = new ArrayList<>(); + if (filters == null || filters.isEmpty()) { + relations.addAll(input); + return relations; + } for (EntityRelation relation : input) { - if (filters == null || filters.isEmpty()) { + if (matchFilters(filters, relation, params.getDirection())) { relations.add(relation); - } else { - for (EntityTypeFilter filter : filters) { - if (match(filter, relation, params.getDirection())) { - relations.add(relation); - break; - } - } } } return relations; @@ -303,6 +352,15 @@ public class BaseRelationService implements RelationService { }; } + private boolean matchFilters(List filters, EntityRelation relation, EntitySearchDirection direction) { + for (EntityTypeFilter filter : filters) { + if (match(filter, relation, direction)) { + return true; + } + } + return false; + } + private boolean match(EntityTypeFilter filter, EntityRelation relation, EntitySearchDirection direction) { if (StringUtils.isEmpty(filter.getRelationType()) || filter.getRelationType().equals(relation.getType())) { if (filter.getEntityTypes() == null || filter.getEntityTypes().isEmpty()) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/relation/RelationDao.java b/dao/src/main/java/org/thingsboard/server/dao/relation/RelationDao.java index ec946d0ed1..edd6d879a5 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/relation/RelationDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/relation/RelationDao.java @@ -41,13 +41,21 @@ public interface RelationDao { ListenableFuture getRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup); - ListenableFuture saveRelation(EntityRelation relation); + boolean saveRelation(EntityRelation relation); - ListenableFuture deleteRelation(EntityRelation relation); + ListenableFuture saveRelationAsync(EntityRelation relation); - ListenableFuture deleteRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup); + boolean deleteRelation(EntityRelation relation); - ListenableFuture deleteOutboundRelations(EntityId entity); + ListenableFuture deleteRelationAsync(EntityRelation relation); + + boolean deleteRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup); + + ListenableFuture deleteRelationAsync(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup); + + boolean deleteOutboundRelations(EntityId entity); + + ListenableFuture deleteOutboundRelationsAsync(EntityId entity); ListenableFuture> findRelations(EntityId from, String relationType, RelationTypeGroup typeGroup, EntityType toType, TimePageLink pageLink); diff --git a/dao/src/main/java/org/thingsboard/server/dao/relation/RelationService.java b/dao/src/main/java/org/thingsboard/server/dao/relation/RelationService.java index 89aae8e5e5..cef93935e6 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/relation/RelationService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/relation/RelationService.java @@ -33,13 +33,21 @@ public interface RelationService { ListenableFuture getRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup); - ListenableFuture saveRelation(EntityRelation relation); + boolean saveRelation(EntityRelation relation); - ListenableFuture deleteRelation(EntityRelation relation); + ListenableFuture saveRelationAsync(EntityRelation relation); - ListenableFuture deleteRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup); + boolean deleteRelation(EntityRelation relation); - ListenableFuture deleteEntityRelations(EntityId entity); + ListenableFuture deleteRelationAsync(EntityRelation relation); + + boolean deleteRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup); + + ListenableFuture deleteRelationAsync(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup); + + boolean deleteEntityRelations(EntityId entity); + + ListenableFuture deleteEntityRelationsAsync(EntityId entity); ListenableFuture> findByFrom(EntityId from, RelationTypeGroup typeGroup); diff --git a/dao/src/main/java/org/thingsboard/server/dao/rule/CassandraBaseRuleDao.java b/dao/src/main/java/org/thingsboard/server/dao/rule/CassandraBaseRuleDao.java index 7026c85751..4993d46ec2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/rule/CassandraBaseRuleDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/rule/CassandraBaseRuleDao.java @@ -40,6 +40,8 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID; @NoSqlDao public class CassandraBaseRuleDao extends CassandraAbstractSearchTextDao implements RuleDao { + public static final String SEARCH_RESULT = "Search result: [{}]"; + @Override protected Class getColumnFamilyClass() { return RuleMetaDataEntity.class; @@ -61,9 +63,9 @@ public class CassandraBaseRuleDao extends CassandraAbstractSearchTextDao entities = findPageWithTextSearch(ModelConstants.RULE_BY_TENANT_AND_SEARCH_TEXT_COLUMN_FAMILY_NAME, Arrays.asList(eq(ModelConstants.RULE_TENANT_ID_PROPERTY, tenantId.getId())), pageLink); if (log.isTraceEnabled()) { - log.trace("Search result: [{}]", Arrays.toString(entities.toArray())); + log.trace(SEARCH_RESULT, Arrays.toString(entities.toArray())); } else { - log.debug("Search result: [{}]", entities.size()); + log.debug(SEARCH_RESULT, entities.size()); } return DaoUtil.convertDataList(entities); } @@ -75,9 +77,9 @@ public class CassandraBaseRuleDao extends CassandraAbstractSearchTextDao> { } protected boolean isSameData(D existentData, D actualData) { - if (actualData.getId() == null) { - return false; - } else if (!existentData.getId().equals(actualData.getId())) { - return false; - } - return true; + return actualData.getId() != null && existentData.getId().equals(actualData.getId()); } protected static void validateEmail(String email) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java b/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java index bb4912ea66..d8a511d9c7 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java +++ b/dao/src/main/java/org/thingsboard/server/dao/service/Validator.java @@ -117,11 +117,7 @@ public class Validator { * @param errorMessage the error message for exception */ public static void validatePageLink(TextPageLink pageLink, String errorMessage) { - if (pageLink == null) { - throw new IncorrectParameterException(errorMessage); - } else if (pageLink.getLimit() < 1) { - throw new IncorrectParameterException(errorMessage); - } else if (pageLink.getIdOffset() != null && pageLink.getIdOffset().version() != 1) { + if (pageLink == null || pageLink.getLimit() < 1 || (pageLink.getIdOffset() != null && pageLink.getIdOffset().version() != 1)) { throw new IncorrectParameterException(errorMessage); } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractSearchTimeDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractSearchTimeDao.java index c13d899a01..80f8588d73 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractSearchTimeDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/JpaAbstractSearchTimeDao.java @@ -38,38 +38,51 @@ public abstract class JpaAbstractSearchTimeDao, D> exten return new Specification() { @Override public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) { - List predicates = new ArrayList<>(); + List predicates; if (pageLink.isAscOrder()) { - if (pageLink.getIdOffset() != null) { - Predicate lowerBound = criteriaBuilder.greaterThan(root.get(idColumn), UUIDConverter.fromTimeUUID(pageLink.getIdOffset())); - predicates.add(lowerBound); - } else if (pageLink.getStartTime() != null) { - UUID startOf = UUIDs.startOf(pageLink.getStartTime()); - Predicate lowerBound = criteriaBuilder.greaterThanOrEqualTo(root.get(idColumn), UUIDConverter.fromTimeUUID(startOf)); - predicates.add(lowerBound); - } - if (pageLink.getEndTime() != null) { - UUID endOf = UUIDs.endOf(pageLink.getEndTime()); - Predicate upperBound = criteriaBuilder.lessThanOrEqualTo(root.get(idColumn), UUIDConverter.fromTimeUUID(endOf)); - predicates.add(upperBound); - } + predicates = createAscPredicates(pageLink, idColumn, root, criteriaBuilder); } else { - if (pageLink.getIdOffset() != null) { - Predicate lowerBound = criteriaBuilder.lessThan(root.get(idColumn), UUIDConverter.fromTimeUUID(pageLink.getIdOffset())); - predicates.add(lowerBound); - } else if (pageLink.getEndTime() != null) { - UUID endOf = UUIDs.endOf(pageLink.getEndTime()); - Predicate lowerBound = criteriaBuilder.lessThanOrEqualTo(root.get(idColumn), UUIDConverter.fromTimeUUID(endOf)); - predicates.add(lowerBound); - } - if (pageLink.getStartTime() != null) { - UUID startOf = UUIDs.startOf(pageLink.getStartTime()); - Predicate upperBound = criteriaBuilder.greaterThanOrEqualTo(root.get(idColumn), UUIDConverter.fromTimeUUID(startOf)); - predicates.add(upperBound); - } + predicates = createDescPredicates(pageLink, idColumn, root, criteriaBuilder); } return criteriaBuilder.and(predicates.toArray(new Predicate[0])); } }; } + + private static List createAscPredicates(TimePageLink pageLink, String idColumn, Root root, CriteriaBuilder criteriaBuilder) { + List predicates = new ArrayList<>(); + if (pageLink.getIdOffset() != null) { + Predicate lowerBound = criteriaBuilder.greaterThan(root.get(idColumn), UUIDConverter.fromTimeUUID(pageLink.getIdOffset())); + predicates.add(lowerBound); + } else if (pageLink.getStartTime() != null) { + UUID startOf = UUIDs.startOf(pageLink.getStartTime()); + Predicate lowerBound = criteriaBuilder.greaterThanOrEqualTo(root.get(idColumn), UUIDConverter.fromTimeUUID(startOf)); + predicates.add(lowerBound); + } + if (pageLink.getEndTime() != null) { + UUID endOf = UUIDs.endOf(pageLink.getEndTime()); + Predicate upperBound = criteriaBuilder.lessThanOrEqualTo(root.get(idColumn), UUIDConverter.fromTimeUUID(endOf)); + predicates.add(upperBound); + } + return predicates; + } + + private static List createDescPredicates(TimePageLink pageLink, String idColumn, Root root, CriteriaBuilder criteriaBuilder) { + List predicates = new ArrayList<>(); + if (pageLink.getIdOffset() != null) { + Predicate lowerBound = criteriaBuilder.lessThan(root.get(idColumn), UUIDConverter.fromTimeUUID(pageLink.getIdOffset())); + predicates.add(lowerBound); + } else if (pageLink.getEndTime() != null) { + UUID endOf = UUIDs.endOf(pageLink.getEndTime()); + Predicate lowerBound = criteriaBuilder.lessThanOrEqualTo(root.get(idColumn), UUIDConverter.fromTimeUUID(endOf)); + predicates.add(lowerBound); + } + if (pageLink.getStartTime() != null) { + UUID startOf = UUIDs.startOf(pageLink.getStartTime()); + Predicate upperBound = criteriaBuilder.greaterThanOrEqualTo(root.get(idColumn), UUIDConverter.fromTimeUUID(startOf)); + predicates.add(upperBound); + } + return predicates; + } + } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/plugin/JpaBasePluginDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/plugin/JpaBasePluginDao.java index c0843f31d7..0a523cbd0d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/plugin/JpaBasePluginDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/plugin/JpaBasePluginDao.java @@ -46,6 +46,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID_STR; @SqlDao public class JpaBasePluginDao extends JpaAbstractSearchTextDao implements PluginDao { + public static final String SEARCH_RESULT = "Search result: [{}]"; @Autowired private PluginMetaDataRepository pluginMetaDataRepository; @@ -66,7 +67,7 @@ public class JpaBasePluginDao extends JpaAbstractSearchTextDao saveRelation(EntityRelation relation) { + public boolean saveRelation(EntityRelation relation) { + return relationRepository.save(new RelationEntity(relation)) != null; + } + + @Override + public ListenableFuture saveRelationAsync(EntityRelation relation) { return service.submit(() -> relationRepository.save(new RelationEntity(relation)) != null); } @Override - public ListenableFuture deleteRelation(EntityRelation relation) { + public boolean deleteRelation(EntityRelation relation) { + RelationCompositeKey key = new RelationCompositeKey(relation); + boolean relationExistsBeforeDelete = relationRepository.exists(key); + relationRepository.delete(key); + return relationExistsBeforeDelete; + } + + @Override + public ListenableFuture deleteRelationAsync(EntityRelation relation) { RelationCompositeKey key = new RelationCompositeKey(relation); return service.submit( () -> { @@ -136,7 +149,15 @@ public class JpaRelationDao extends JpaAbstractDaoListeningExecutorService imple } @Override - public ListenableFuture deleteRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { + public boolean deleteRelation(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { + RelationCompositeKey key = getRelationCompositeKey(from, to, relationType, typeGroup); + boolean relationExistsBeforeDelete = relationRepository.exists(key); + relationRepository.delete(key); + return relationExistsBeforeDelete; + } + + @Override + public ListenableFuture deleteRelationAsync(EntityId from, EntityId to, String relationType, RelationTypeGroup typeGroup) { RelationCompositeKey key = getRelationCompositeKey(from, to, relationType, typeGroup); return service.submit( () -> { @@ -147,7 +168,16 @@ public class JpaRelationDao extends JpaAbstractDaoListeningExecutorService imple } @Override - public ListenableFuture deleteOutboundRelations(EntityId entity) { + public boolean deleteOutboundRelations(EntityId entity) { + boolean relationExistsBeforeDelete = relationRepository + .findAllByFromIdAndFromType(UUIDConverter.fromTimeUUID(entity.getId()), entity.getEntityType().name()) + .size() > 0; + relationRepository.deleteByFromIdAndFromType(UUIDConverter.fromTimeUUID(entity.getId()), entity.getEntityType().name()); + return relationExistsBeforeDelete; + } + + @Override + public ListenableFuture deleteOutboundRelationsAsync(EntityId entity) { return service.submit( () -> { boolean relationExistsBeforeDelete = relationRepository diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaBaseRuleDao.java b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaBaseRuleDao.java index e2cb561a31..92d222571f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaBaseRuleDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/rule/JpaBaseRuleDao.java @@ -46,6 +46,7 @@ import static org.thingsboard.server.dao.model.ModelConstants.NULL_UUID_STR; @SqlDao public class JpaBaseRuleDao extends JpaAbstractSearchTextDao implements RuleDao { + public static final String SEARCH_RESULT = "Search result: [{}]"; @Autowired private RuleMetaDataRepository ruleMetaDataRepository; @@ -81,9 +82,9 @@ public class JpaBaseRuleDao extends JpaAbstractSearchTextDao>() { - @Nullable @Override public Optional apply(@Nullable TsKvEntity entity) { if (entity != null && entity.isNotEmpty()) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java index 3193b853ed..df68b6a9d8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/tenant/TenantServiceImpl.java @@ -47,6 +47,7 @@ import static org.thingsboard.server.dao.service.Validator.validateId; public class TenantServiceImpl extends AbstractEntityService implements TenantService { private static final String DEFAULT_TENANT_REGION = "Global"; + public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; @Autowired private TenantDao tenantDao; @@ -78,14 +79,14 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe @Override public Tenant findTenantById(TenantId tenantId) { log.trace("Executing findTenantById [{}]", tenantId); - Validator.validateId(tenantId, "Incorrect tenantId " + tenantId); + Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); return tenantDao.findById(tenantId.getId()); } @Override public ListenableFuture findTenantByIdAsync(TenantId tenantId) { log.trace("Executing TenantIdAsync [{}]", tenantId); - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); return tenantDao.findByIdAsync(tenantId.getId()); } @@ -100,7 +101,7 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe @Override public void deleteTenant(TenantId tenantId) { log.trace("Executing deleteTenant [{}]", tenantId); - Validator.validateId(tenantId, "Incorrect tenantId " + tenantId); + Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); customerService.deleteCustomersByTenantId(tenantId); widgetsBundleService.deleteWidgetsBundlesByTenantId(tenantId); dashboardService.deleteDashboardsByTenantId(tenantId); diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/AggregatePartitionsFunction.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/AggregatePartitionsFunction.java index 2362f5822e..2e0bad96b4 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/AggregatePartitionsFunction.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/AggregatePartitionsFunction.java @@ -49,128 +49,110 @@ public class AggregatePartitionsFunction implements com.google.common.base.Funct this.ts = ts; } - @Nullable @Override public Optional apply(@Nullable List rsList) { try { log.trace("[{}][{}][{}] Going to aggregate data", key, ts, aggregation); - if (rsList == null || rsList.size() == 0) { + if (rsList == null || rsList.isEmpty()) { return Optional.empty(); } - long count = 0; - DataType dataType = null; - Boolean bValue = null; - String sValue = null; - Double dValue = null; - Long lValue = null; + AggregationResult aggResult = new AggregationResult(); for (ResultSet rs : rsList) { for (Row row : rs.all()) { - long curCount; - - Long curLValue = null; - Double curDValue = null; - Boolean curBValue = null; - String curSValue = null; - - long longCount = row.getLong(LONG_CNT_POS); - long doubleCount = row.getLong(DOUBLE_CNT_POS); - long boolCount = row.getLong(BOOL_CNT_POS); - long strCount = row.getLong(STR_CNT_POS); - - if (longCount > 0) { - dataType = DataType.LONG; - curCount = longCount; - curLValue = getLongValue(row); - } else if (doubleCount > 0) { - dataType = DataType.DOUBLE; - curCount = doubleCount; - curDValue = getDoubleValue(row); - } else if (boolCount > 0) { - dataType = DataType.BOOLEAN; - curCount = boolCount; - curBValue = getBooleanValue(row); - } else if (strCount > 0) { - dataType = DataType.STRING; - curCount = strCount; - curSValue = getStringValue(row); - } else { - continue; - } - - if (aggregation == Aggregation.COUNT) { - count += curCount; - } else if (aggregation == Aggregation.AVG || aggregation == Aggregation.SUM) { - count += curCount; - if (curDValue != null) { - dValue = dValue == null ? curDValue : dValue + curDValue; - } else if (curLValue != null) { - lValue = lValue == null ? curLValue : lValue + curLValue; - } - } else if (aggregation == Aggregation.MIN) { - if (curDValue != null) { - dValue = dValue == null ? curDValue : Math.min(dValue, curDValue); - } else if (curLValue != null) { - lValue = lValue == null ? curLValue : Math.min(lValue, curLValue); - } else if (curBValue != null) { - bValue = bValue == null ? curBValue : bValue && curBValue; - } else if (curSValue != null) { - if (sValue == null || curSValue.compareTo(sValue) < 0) { - sValue = curSValue; - } - } - } else if (aggregation == Aggregation.MAX) { - if (curDValue != null) { - dValue = dValue == null ? curDValue : Math.max(dValue, curDValue); - } else if (curLValue != null) { - lValue = lValue == null ? curLValue : Math.max(lValue, curLValue); - } else if (curBValue != null) { - bValue = bValue == null ? curBValue : bValue || curBValue; - } else if (curSValue != null) { - if (sValue == null || curSValue.compareTo(sValue) > 0) { - sValue = curSValue; - } - } - } + processResultSetRow(row, aggResult); } } - if (dataType == null) { - return Optional.empty(); - } else if (aggregation == Aggregation.COUNT) { - return Optional.of(new BasicTsKvEntry(ts, new LongDataEntry(key, (long) count))); - } else if (aggregation == Aggregation.AVG || aggregation == Aggregation.SUM) { - if (count == 0 || (dataType == DataType.DOUBLE && dValue == null) || (dataType == DataType.LONG && lValue == null)) { - return Optional.empty(); - } else if (dataType == DataType.DOUBLE) { - return Optional.of(new BasicTsKvEntry(ts, new DoubleDataEntry(key, aggregation == Aggregation.SUM ? dValue : (dValue / count)))); - } else if (dataType == DataType.LONG) { - return Optional.of(new BasicTsKvEntry(ts, new LongDataEntry(key, aggregation == Aggregation.SUM ? lValue : (lValue / count)))); - } - } else if (aggregation == Aggregation.MIN || aggregation == Aggregation.MAX) { - if (dataType == DataType.DOUBLE) { - return Optional.of(new BasicTsKvEntry(ts, new DoubleDataEntry(key, dValue))); - } else if (dataType == DataType.LONG) { - return Optional.of(new BasicTsKvEntry(ts, new LongDataEntry(key, lValue))); - } else if (dataType == DataType.STRING) { - return Optional.of(new BasicTsKvEntry(ts, new StringDataEntry(key, sValue))); - } else { - return Optional.of(new BasicTsKvEntry(ts, new BooleanDataEntry(key, bValue))); - } - } - log.trace("[{}][{}][{}] Aggregated data is empty.", key, ts, aggregation); - return Optional.empty(); + return processAggregationResult(aggResult); }catch (Exception e){ log.error("[{}][{}][{}] Failed to aggregate data", key, ts, aggregation, e); return Optional.empty(); } } + private void processResultSetRow(Row row, AggregationResult aggResult) { + long curCount; + + Long curLValue = null; + Double curDValue = null; + Boolean curBValue = null; + String curSValue = null; + + long longCount = row.getLong(LONG_CNT_POS); + long doubleCount = row.getLong(DOUBLE_CNT_POS); + long boolCount = row.getLong(BOOL_CNT_POS); + long strCount = row.getLong(STR_CNT_POS); + + if (longCount > 0) { + aggResult.dataType = DataType.LONG; + curCount = longCount; + curLValue = getLongValue(row); + } else if (doubleCount > 0) { + aggResult.dataType = DataType.DOUBLE; + curCount = doubleCount; + curDValue = getDoubleValue(row); + } else if (boolCount > 0) { + aggResult.dataType = DataType.BOOLEAN; + curCount = boolCount; + curBValue = getBooleanValue(row); + } else if (strCount > 0) { + aggResult.dataType = DataType.STRING; + curCount = strCount; + curSValue = getStringValue(row); + } else { + return; + } + + if (aggregation == Aggregation.COUNT) { + aggResult.count += curCount; + } else if (aggregation == Aggregation.AVG || aggregation == Aggregation.SUM) { + processAvgOrSumAggregation(aggResult, curCount, curLValue, curDValue); + } else if (aggregation == Aggregation.MIN) { + processMinAggregation(aggResult, curLValue, curDValue, curBValue, curSValue); + } else if (aggregation == Aggregation.MAX) { + processMaxAggregation(aggResult, curLValue, curDValue, curBValue, curSValue); + } + } + + private void processAvgOrSumAggregation(AggregationResult aggResult, long curCount, Long curLValue, Double curDValue) { + aggResult.count += curCount; + if (curDValue != null) { + aggResult.dValue = aggResult.dValue == null ? curDValue : aggResult.dValue + curDValue; + } else if (curLValue != null) { + aggResult.lValue = aggResult.lValue == null ? curLValue : aggResult.lValue + curLValue; + } + } + + private void processMinAggregation(AggregationResult aggResult, Long curLValue, Double curDValue, Boolean curBValue, String curSValue) { + if (curDValue != null) { + aggResult.dValue = aggResult.dValue == null ? curDValue : Math.min(aggResult.dValue, curDValue); + } else if (curLValue != null) { + aggResult.lValue = aggResult.lValue == null ? curLValue : Math.min(aggResult.lValue, curLValue); + } else if (curBValue != null) { + aggResult.bValue = aggResult.bValue == null ? curBValue : aggResult.bValue && curBValue; + } else if (curSValue != null && (aggResult.sValue == null || curSValue.compareTo(aggResult.sValue) < 0)) { + aggResult.sValue = curSValue; + } + } + + private void processMaxAggregation(AggregationResult aggResult, Long curLValue, Double curDValue, Boolean curBValue, String curSValue) { + if (curDValue != null) { + aggResult.dValue = aggResult.dValue == null ? curDValue : Math.max(aggResult.dValue, curDValue); + } else if (curLValue != null) { + aggResult.lValue = aggResult.lValue == null ? curLValue : Math.max(aggResult.lValue, curLValue); + } else if (curBValue != null) { + aggResult.bValue = aggResult.bValue == null ? curBValue : aggResult.bValue || curBValue; + } else if (curSValue != null && (aggResult.sValue == null || curSValue.compareTo(aggResult.sValue) > 0)) { + aggResult.sValue = curSValue; + } + } + private Boolean getBooleanValue(Row row) { if (aggregation == Aggregation.MIN || aggregation == Aggregation.MAX) { return row.getBool(BOOL_POS); } else { - return null; + return null; //NOSONAR, null is used for further comparison } } @@ -199,4 +181,55 @@ public class AggregatePartitionsFunction implements com.google.common.base.Funct return null; } } + + private Optional processAggregationResult(AggregationResult aggResult) { + Optional result; + if (aggResult.dataType == null) { + result = Optional.empty(); + } else if (aggregation == Aggregation.COUNT) { + result = Optional.of(new BasicTsKvEntry(ts, new LongDataEntry(key, aggResult.count))); + } else if (aggregation == Aggregation.AVG || aggregation == Aggregation.SUM) { + result = processAvgOrSumResult(aggResult); + } else if (aggregation == Aggregation.MIN || aggregation == Aggregation.MAX) { + result = processMinOrMaxResult(aggResult); + } else { + result = Optional.empty(); + } + if (!result.isPresent()) { + log.trace("[{}][{}][{}] Aggregated data is empty.", key, ts, aggregation); + } + return result; + } + + private Optional processAvgOrSumResult(AggregationResult aggResult) { + if (aggResult.count == 0 || (aggResult.dataType == DataType.DOUBLE && aggResult.dValue == null) || (aggResult.dataType == DataType.LONG && aggResult.lValue == null)) { + return Optional.empty(); + } else if (aggResult.dataType == DataType.DOUBLE) { + return Optional.of(new BasicTsKvEntry(ts, new DoubleDataEntry(key, aggregation == Aggregation.SUM ? aggResult.dValue : (aggResult.dValue / aggResult.count)))); + } else if (aggResult.dataType == DataType.LONG) { + return Optional.of(new BasicTsKvEntry(ts, new LongDataEntry(key, aggregation == Aggregation.SUM ? aggResult.lValue : (aggResult.lValue / aggResult.count)))); + } + return Optional.empty(); + } + + private Optional processMinOrMaxResult(AggregationResult aggResult) { + if (aggResult.dataType == DataType.DOUBLE) { + return Optional.of(new BasicTsKvEntry(ts, new DoubleDataEntry(key, aggResult.dValue))); + } else if (aggResult.dataType == DataType.LONG) { + return Optional.of(new BasicTsKvEntry(ts, new LongDataEntry(key, aggResult.lValue))); + } else if (aggResult.dataType == DataType.STRING) { + return Optional.of(new BasicTsKvEntry(ts, new StringDataEntry(key, aggResult.sValue))); + } else { + return Optional.of(new BasicTsKvEntry(ts, new BooleanDataEntry(key, aggResult.bValue))); + } + } + + private class AggregationResult { + DataType dataType = null; + Boolean bValue = null; + String sValue = null; + Double dValue = null; + Long lValue = null; + long count = 0; + } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java index 8e9aa0aba2..92cd042790 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/CassandraBaseTimeseriesDao.java @@ -42,6 +42,7 @@ import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -57,6 +58,10 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.eq; public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implements TimeseriesDao { private static final int MIN_AGGREGATION_STEP_MS = 1000; + public static final String INSERT_INTO = "INSERT INTO "; + public static final String GENERATED_QUERY_FOR_ENTITY_TYPE_AND_ENTITY_ID = "Generated query [{}] for entityType {} and entityId {}"; + public static final String SELECT_PREFIX = "SELECT "; + public static final String EQUALS_PARAM = " = ? "; @Autowired private Environment environment; @@ -136,7 +141,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem @Nullable @Override public List apply(@Nullable List> input) { - return input.stream().filter(v -> v.isPresent()).map(v -> v.get()).collect(Collectors.toList()); + return input == null ? Collections.emptyList() : input.stream().filter(v -> v.isPresent()).map(v -> v.get()).collect(Collectors.toList()); } }, readResultsProcessingExecutor); } @@ -189,7 +194,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem Futures.addCallback(executeAsyncRead(stmt), new FutureCallback() { @Override public void onSuccess(@Nullable ResultSet result) { - cursor.addData(convertResultToTsKvEntryList(result.all())); + cursor.addData(convertResultToTsKvEntryList(result == null ? Collections.emptyList() : result.all())); findAllAsyncSequentiallyWithLimit(cursor, resultFuture); } @@ -237,7 +242,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem stmt.setLong(3, partition); stmt.setLong(4, startTs); stmt.setLong(5, endTs); - log.debug("Generated query [{}] for entityType {} and entityId {}", stmt, entityId.getEntityType(), entityId.getId()); + log.debug(GENERATED_QUERY_FOR_ENTITY_TYPE_AND_ENTITY_ID, stmt, entityId.getEntityType(), entityId.getId()); futures.add(executeAsyncRead(stmt)); } return Futures.allAsList(futures); @@ -254,7 +259,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem stmt.setString(0, entityId.getEntityType().name()); stmt.setUUID(1, entityId.getId()); stmt.setString(2, key); - log.debug("Generated query [{}] for entityType {} and entityId {}", stmt, entityId.getEntityType(), entityId.getId()); + log.debug(GENERATED_QUERY_FOR_ENTITY_TYPE_AND_ENTITY_ID, stmt, entityId.getEntityType(), entityId.getId()); return getFuture(executeAsyncRead(stmt), rs -> convertResultToTsKvEntry(key, rs.one())); } @@ -263,7 +268,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem BoundStatement stmt = getFindAllLatestStmt().bind(); stmt.setString(0, entityId.getEntityType().name()); stmt.setUUID(1, entityId.getId()); - log.debug("Generated query [{}] for entityType {} and entityId {}", stmt, entityId.getEntityType(), entityId.getId()); + log.debug(GENERATED_QUERY_FOR_ENTITY_TYPE_AND_ENTITY_ID, stmt, entityId.getEntityType(), entityId.getId()); return getFuture(executeAsyncRead(stmt), rs -> convertResultToTsKvEntryList(rs.all())); } @@ -376,7 +381,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem if (saveStmts == null) { saveStmts = new PreparedStatement[DataType.values().length]; for (DataType type : DataType.values()) { - saveStmts[type.ordinal()] = getSession().prepare("INSERT INTO " + ModelConstants.TS_KV_CF + + saveStmts[type.ordinal()] = getSession().prepare(INSERT_INTO + ModelConstants.TS_KV_CF + "(" + ModelConstants.ENTITY_TYPE_COLUMN + "," + ModelConstants.ENTITY_ID_COLUMN + "," + ModelConstants.KEY_COLUMN + @@ -393,7 +398,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem if (saveTtlStmts == null) { saveTtlStmts = new PreparedStatement[DataType.values().length]; for (DataType type : DataType.values()) { - saveTtlStmts[type.ordinal()] = getSession().prepare("INSERT INTO " + ModelConstants.TS_KV_CF + + saveTtlStmts[type.ordinal()] = getSession().prepare(INSERT_INTO + ModelConstants.TS_KV_CF + "(" + ModelConstants.ENTITY_TYPE_COLUMN + "," + ModelConstants.ENTITY_ID_COLUMN + "," + ModelConstants.KEY_COLUMN + @@ -415,12 +420,12 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem } else if (type == Aggregation.AVG && fetchStmts[Aggregation.SUM.ordinal()] != null) { fetchStmts[type.ordinal()] = fetchStmts[Aggregation.SUM.ordinal()]; } else { - fetchStmts[type.ordinal()] = getSession().prepare("SELECT " + + fetchStmts[type.ordinal()] = getSession().prepare(SELECT_PREFIX + String.join(", ", ModelConstants.getFetchColumnNames(type)) + " FROM " + ModelConstants.TS_KV_CF - + " WHERE " + ModelConstants.ENTITY_TYPE_COLUMN + " = ? " - + "AND " + ModelConstants.ENTITY_ID_COLUMN + " = ? " - + "AND " + ModelConstants.KEY_COLUMN + " = ? " - + "AND " + ModelConstants.PARTITION_COLUMN + " = ? " + + " WHERE " + ModelConstants.ENTITY_TYPE_COLUMN + EQUALS_PARAM + + "AND " + ModelConstants.ENTITY_ID_COLUMN + EQUALS_PARAM + + "AND " + ModelConstants.KEY_COLUMN + EQUALS_PARAM + + "AND " + ModelConstants.PARTITION_COLUMN + EQUALS_PARAM + "AND " + ModelConstants.TS_COLUMN + " > ? " + "AND " + ModelConstants.TS_COLUMN + " <= ?" + (type == Aggregation.NONE ? " ORDER BY " + ModelConstants.TS_COLUMN + " DESC LIMIT ?" : "")); @@ -434,7 +439,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem if (latestInsertStmts == null) { latestInsertStmts = new PreparedStatement[DataType.values().length]; for (DataType type : DataType.values()) { - latestInsertStmts[type.ordinal()] = getSession().prepare("INSERT INTO " + ModelConstants.TS_KV_LATEST_CF + + latestInsertStmts[type.ordinal()] = getSession().prepare(INSERT_INTO + ModelConstants.TS_KV_LATEST_CF + "(" + ModelConstants.ENTITY_TYPE_COLUMN + "," + ModelConstants.ENTITY_ID_COLUMN + "," + ModelConstants.KEY_COLUMN + @@ -449,7 +454,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem private PreparedStatement getPartitionInsertStmt() { if (partitionInsertStmt == null) { - partitionInsertStmt = getSession().prepare("INSERT INTO " + ModelConstants.TS_KV_PARTITIONS_CF + + partitionInsertStmt = getSession().prepare(INSERT_INTO + ModelConstants.TS_KV_PARTITIONS_CF + "(" + ModelConstants.ENTITY_TYPE_COLUMN + "," + ModelConstants.ENTITY_ID_COLUMN + "," + ModelConstants.PARTITION_COLUMN + @@ -461,7 +466,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem private PreparedStatement getPartitionInsertTtlStmt() { if (partitionInsertTtlStmt == null) { - partitionInsertTtlStmt = getSession().prepare("INSERT INTO " + ModelConstants.TS_KV_PARTITIONS_CF + + partitionInsertTtlStmt = getSession().prepare(INSERT_INTO + ModelConstants.TS_KV_PARTITIONS_CF + "(" + ModelConstants.ENTITY_TYPE_COLUMN + "," + ModelConstants.ENTITY_ID_COLUMN + "," + ModelConstants.PARTITION_COLUMN + @@ -474,7 +479,7 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem private PreparedStatement getFindLatestStmt() { if (findLatestStmt == null) { - findLatestStmt = getSession().prepare("SELECT " + + findLatestStmt = getSession().prepare(SELECT_PREFIX + ModelConstants.KEY_COLUMN + "," + ModelConstants.TS_COLUMN + "," + ModelConstants.STRING_VALUE_COLUMN + "," + @@ -482,16 +487,16 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem ModelConstants.LONG_VALUE_COLUMN + "," + ModelConstants.DOUBLE_VALUE_COLUMN + " " + "FROM " + ModelConstants.TS_KV_LATEST_CF + " " + - "WHERE " + ModelConstants.ENTITY_TYPE_COLUMN + " = ? " + - "AND " + ModelConstants.ENTITY_ID_COLUMN + " = ? " + - "AND " + ModelConstants.KEY_COLUMN + " = ? "); + "WHERE " + ModelConstants.ENTITY_TYPE_COLUMN + EQUALS_PARAM + + "AND " + ModelConstants.ENTITY_ID_COLUMN + EQUALS_PARAM + + "AND " + ModelConstants.KEY_COLUMN + EQUALS_PARAM); } return findLatestStmt; } private PreparedStatement getFindAllLatestStmt() { if (findAllLatestStmt == null) { - findAllLatestStmt = getSession().prepare("SELECT " + + findAllLatestStmt = getSession().prepare(SELECT_PREFIX + ModelConstants.KEY_COLUMN + "," + ModelConstants.TS_COLUMN + "," + ModelConstants.STRING_VALUE_COLUMN + "," + @@ -499,8 +504,8 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem ModelConstants.LONG_VALUE_COLUMN + "," + ModelConstants.DOUBLE_VALUE_COLUMN + " " + "FROM " + ModelConstants.TS_KV_LATEST_CF + " " + - "WHERE " + ModelConstants.ENTITY_TYPE_COLUMN + " = ? " + - "AND " + ModelConstants.ENTITY_ID_COLUMN + " = ? "); + "WHERE " + ModelConstants.ENTITY_TYPE_COLUMN + EQUALS_PARAM + + "AND " + ModelConstants.ENTITY_ID_COLUMN + EQUALS_PARAM); } return findAllLatestStmt; } @@ -523,16 +528,28 @@ public class CassandraBaseTimeseriesDao extends CassandraAbstractAsyncDao implem private static void addValue(KvEntry kvEntry, BoundStatement stmt, int column) { switch (kvEntry.getDataType()) { case BOOLEAN: - stmt.setBool(column, kvEntry.getBooleanValue().get().booleanValue()); + Optional booleanValue = kvEntry.getBooleanValue(); + if (booleanValue.isPresent()) { + stmt.setBool(column, booleanValue.get().booleanValue()); + } break; case STRING: - stmt.setString(column, kvEntry.getStrValue().get()); + Optional stringValue = kvEntry.getStrValue(); + if (stringValue.isPresent()) { + stmt.setString(column, stringValue.get()); + } break; case LONG: - stmt.setLong(column, kvEntry.getLongValue().get().longValue()); + Optional longValue = kvEntry.getLongValue(); + if (longValue.isPresent()) { + stmt.setLong(column, longValue.get().longValue()); + } break; case DOUBLE: - stmt.setDouble(column, kvEntry.getDoubleValue().get().doubleValue()); + Optional doubleValue = kvEntry.getDoubleValue(); + if (doubleValue.isPresent()) { + stmt.setDouble(column, doubleValue.get().doubleValue()); + } break; } } diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsPartitionDate.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsPartitionDate.java index c863b2e42c..2b63a9e0c8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsPartitionDate.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/TsPartitionDate.java @@ -25,7 +25,7 @@ public enum TsPartitionDate { MINUTES("yyyy-MM-dd-HH-mm", ChronoUnit.MINUTES), HOURS("yyyy-MM-dd-HH", ChronoUnit.HOURS), DAYS("yyyy-MM-dd", ChronoUnit.DAYS), MONTHS("yyyy-MM", ChronoUnit.MONTHS), YEARS("yyyy", ChronoUnit.YEARS); private final String pattern; - private final TemporalUnit truncateUnit; + private final transient TemporalUnit truncateUnit; TsPartitionDate(String pattern, TemporalUnit truncateUnit) { this.pattern = pattern; diff --git a/dao/src/main/java/org/thingsboard/server/dao/user/CassandraUserCredentialsDao.java b/dao/src/main/java/org/thingsboard/server/dao/user/CassandraUserCredentialsDao.java index 8dec384370..f4f84d4568 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/user/CassandraUserCredentialsDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/user/CassandraUserCredentialsDao.java @@ -35,6 +35,8 @@ import static com.datastax.driver.core.querybuilder.QueryBuilder.select; @NoSqlDao public class CassandraUserCredentialsDao extends CassandraAbstractModelDao implements UserCredentialsDao { + public static final String EXECUTE_QUERY = "Execute query {}"; + @Override protected Class getColumnFamilyClass() { return UserCredentialsEntity.class; @@ -49,7 +51,7 @@ public class CassandraUserCredentialsDao extends CassandraAbstractModelDao findUserByIdAsync(UserId userId) { log.trace("Executing findUserByIdAsync [{}]", userId); - validateId(userId, "Incorrect userId " + userId); + validateId(userId, INCORRECT_USER_ID + userId); return userDao.findByIdAsync(userId.getId()); } @@ -101,7 +103,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic @Override public UserCredentials findUserCredentialsByUserId(UserId userId) { log.trace("Executing findUserCredentialsByUserId [{}]", userId); - validateId(userId, "Incorrect userId " + userId); + validateId(userId, INCORRECT_USER_ID + userId); return userCredentialsDao.findByUserId(userId.getId()); } @@ -165,7 +167,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic @Override public void deleteUser(UserId userId) { log.trace("Executing deleteUser [{}]", userId); - validateId(userId, "Incorrect userId " + userId); + validateId(userId, INCORRECT_USER_ID + userId); UserCredentials userCredentials = userCredentialsDao.findByUserId(userId.getId()); userCredentialsDao.removeById(userCredentials.getUuidId()); deleteEntityRelations(userId); @@ -175,7 +177,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic @Override public TextPageData findTenantAdmins(TenantId tenantId, TextPageLink pageLink) { log.trace("Executing findTenantAdmins, tenantId [{}], pageLink [{}]", tenantId, pageLink); - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); validatePageLink(pageLink, "Incorrect page link " + pageLink); List users = userDao.findTenantAdmins(tenantId.getId(), pageLink); return new TextPageData<>(users, pageLink); @@ -184,14 +186,14 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic @Override public void deleteTenantAdmins(TenantId tenantId) { log.trace("Executing deleteTenantAdmins, tenantId [{}]", tenantId); - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); tenantAdminsRemover.removeEntities(tenantId); } @Override public TextPageData findCustomerUsers(TenantId tenantId, CustomerId customerId, TextPageLink pageLink) { log.trace("Executing findCustomerUsers, tenantId [{}], customerId [{}], pageLink [{}]", tenantId, customerId, pageLink); - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); validateId(customerId, "Incorrect customerId " + customerId); validatePageLink(pageLink, "Incorrect page link " + pageLink); List users = userDao.findCustomerUsers(tenantId.getId(), customerId.getId(), pageLink); @@ -201,7 +203,7 @@ public class UserServiceImpl extends AbstractEntityService implements UserServic @Override public void deleteCustomerUsers(TenantId tenantId, CustomerId customerId) { log.trace("Executing deleteCustomerUsers, customerId [{}]", customerId); - validateId(tenantId, "Incorrect tenantId " + tenantId); + validateId(tenantId, INCORRECT_TENANT_ID + tenantId); validateId(customerId, "Incorrect customerId " + customerId); new CustomerUsersRemover(tenantId).removeEntities(customerId); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java index b9cd303322..90e11868e5 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetTypeServiceImpl.java @@ -36,6 +36,8 @@ import java.util.List; @Slf4j public class WidgetTypeServiceImpl implements WidgetTypeService { + public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; + public static final String INCORRECT_BUNDLE_ALIAS = "Incorrect bundleAlias "; @Autowired private WidgetTypeDao widgetTypeDao; @@ -69,16 +71,16 @@ public class WidgetTypeServiceImpl implements WidgetTypeService { @Override public List findWidgetTypesByTenantIdAndBundleAlias(TenantId tenantId, String bundleAlias) { log.trace("Executing findWidgetTypesByTenantIdAndBundleAlias, tenantId [{}], bundleAlias [{}]", tenantId, bundleAlias); - Validator.validateId(tenantId, "Incorrect tenantId " + tenantId); - Validator.validateString(bundleAlias, "Incorrect bundleAlias " + bundleAlias); + Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + Validator.validateString(bundleAlias, INCORRECT_BUNDLE_ALIAS + bundleAlias); return widgetTypeDao.findWidgetTypesByTenantIdAndBundleAlias(tenantId.getId(), bundleAlias); } @Override public WidgetType findWidgetTypeByTenantIdBundleAliasAndAlias(TenantId tenantId, String bundleAlias, String alias) { log.trace("Executing findWidgetTypeByTenantIdBundleAliasAndAlias, tenantId [{}], bundleAlias [{}], alias [{}]", tenantId, bundleAlias, alias); - Validator.validateId(tenantId, "Incorrect tenantId " + tenantId); - Validator.validateString(bundleAlias, "Incorrect bundleAlias " + bundleAlias); + Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + Validator.validateString(bundleAlias, INCORRECT_BUNDLE_ALIAS + bundleAlias); Validator.validateString(alias, "Incorrect alias " + alias); return widgetTypeDao.findByTenantIdBundleAliasAndAlias(tenantId.getId(), bundleAlias, alias); } @@ -86,8 +88,8 @@ public class WidgetTypeServiceImpl implements WidgetTypeService { @Override public void deleteWidgetTypesByTenantIdAndBundleAlias(TenantId tenantId, String bundleAlias) { log.trace("Executing deleteWidgetTypesByTenantIdAndBundleAlias, tenantId [{}], bundleAlias [{}]", tenantId, bundleAlias); - Validator.validateId(tenantId, "Incorrect tenantId " + tenantId); - Validator.validateString(bundleAlias, "Incorrect bundleAlias " + bundleAlias); + Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + Validator.validateString(bundleAlias, INCORRECT_BUNDLE_ALIAS + bundleAlias); List widgetTypes = widgetTypeDao.findWidgetTypesByTenantIdAndBundleAlias(tenantId.getId(), bundleAlias); for (WidgetType widgetType : widgetTypes) { deleteWidgetType(new WidgetTypeId(widgetType.getUuidId())); diff --git a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java index 7e413d8614..f7b371ea68 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/widget/WidgetsBundleServiceImpl.java @@ -41,6 +41,8 @@ import java.util.List; public class WidgetsBundleServiceImpl implements WidgetsBundleService { private static final int DEFAULT_WIDGETS_BUNDLE_LIMIT = 300; + public static final String INCORRECT_TENANT_ID = "Incorrect tenantId "; + public static final String INCORRECT_PAGE_LINK = "Incorrect page link "; @Autowired private WidgetsBundleDao widgetsBundleDao; @@ -80,7 +82,7 @@ public class WidgetsBundleServiceImpl implements WidgetsBundleService { @Override public WidgetsBundle findWidgetsBundleByTenantIdAndAlias(TenantId tenantId, String alias) { log.trace("Executing findWidgetsBundleByTenantIdAndAlias, tenantId [{}], alias [{}]", tenantId, alias); - Validator.validateId(tenantId, "Incorrect tenantId " + tenantId); + Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); Validator.validateString(alias, "Incorrect alias " + alias); return widgetsBundleDao.findWidgetsBundleByTenantIdAndAlias(tenantId.getId(), alias); } @@ -88,7 +90,7 @@ public class WidgetsBundleServiceImpl implements WidgetsBundleService { @Override public TextPageData findSystemWidgetsBundlesByPageLink(TextPageLink pageLink) { log.trace("Executing findSystemWidgetsBundles, pageLink [{}]", pageLink); - Validator.validatePageLink(pageLink, "Incorrect page link " + pageLink); + Validator.validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); return new TextPageData<>(widgetsBundleDao.findSystemWidgetsBundles(pageLink), pageLink); } @@ -111,23 +113,23 @@ public class WidgetsBundleServiceImpl implements WidgetsBundleService { @Override public TextPageData findTenantWidgetsBundlesByTenantId(TenantId tenantId, TextPageLink pageLink) { log.trace("Executing findTenantWidgetsBundlesByTenantId, tenantId [{}], pageLink [{}]", tenantId, pageLink); - Validator.validateId(tenantId, "Incorrect tenantId " + tenantId); - Validator.validatePageLink(pageLink, "Incorrect page link " + pageLink); + Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + Validator.validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); return new TextPageData<>(widgetsBundleDao.findTenantWidgetsBundlesByTenantId(tenantId.getId(), pageLink), pageLink); } @Override public TextPageData findAllTenantWidgetsBundlesByTenantIdAndPageLink(TenantId tenantId, TextPageLink pageLink) { log.trace("Executing findAllTenantWidgetsBundlesByTenantIdAndPageLink, tenantId [{}], pageLink [{}]", tenantId, pageLink); - Validator.validateId(tenantId, "Incorrect tenantId " + tenantId); - Validator.validatePageLink(pageLink, "Incorrect page link " + pageLink); + Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); + Validator.validatePageLink(pageLink, INCORRECT_PAGE_LINK + pageLink); return new TextPageData<>(widgetsBundleDao.findAllTenantWidgetsBundlesByTenantId(tenantId.getId(), pageLink), pageLink); } @Override public List findAllTenantWidgetsBundlesByTenantId(TenantId tenantId) { log.trace("Executing findAllTenantWidgetsBundlesByTenantId, tenantId [{}]", tenantId); - Validator.validateId(tenantId, "Incorrect tenantId " + tenantId); + Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); List widgetsBundles = new ArrayList<>(); TextPageLink pageLink = new TextPageLink(DEFAULT_WIDGETS_BUNDLE_LIMIT); TextPageData pageData; @@ -144,7 +146,7 @@ public class WidgetsBundleServiceImpl implements WidgetsBundleService { @Override public void deleteWidgetsBundlesByTenantId(TenantId tenantId) { log.trace("Executing deleteWidgetsBundlesByTenantId, tenantId [{}]", tenantId); - Validator.validateId(tenantId, "Incorrect tenantId " + tenantId); + Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); tenantWidgetsBundleRemover.removeEntities(tenantId); } diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseAlarmServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseAlarmServiceTest.java index b208e75d29..23fc3cc1a3 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseAlarmServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseAlarmServiceTest.java @@ -57,7 +57,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest { EntityRelation relation = new EntityRelation(parentId, childId, EntityRelation.CONTAINS_TYPE); - Assert.assertTrue(relationService.saveRelation(relation).get()); + Assert.assertTrue(relationService.saveRelationAsync(relation).get()); long ts = System.currentTimeMillis(); Alarm alarm = Alarm.builder().tenantId(tenantId).originator(childId) @@ -94,7 +94,7 @@ public abstract class BaseAlarmServiceTest extends AbstractServiceTest { EntityRelation relation = new EntityRelation(parentId, childId, EntityRelation.CONTAINS_TYPE); - Assert.assertTrue(relationService.saveRelation(relation).get()); + Assert.assertTrue(relationService.saveRelationAsync(relation).get()); long ts = System.currentTimeMillis(); Alarm alarm = Alarm.builder().tenantId(tenantId).originator(childId) diff --git a/dao/src/test/java/org/thingsboard/server/dao/service/BaseRelationServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/service/BaseRelationServiceTest.java index d76265dd7d..6b58af8e19 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/service/BaseRelationServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/service/BaseRelationServiceTest.java @@ -75,13 +75,13 @@ public abstract class BaseRelationServiceTest extends AbstractServiceTest { saveRelation(relationA); saveRelation(relationB); - Assert.assertTrue(relationService.deleteRelation(relationA).get()); + Assert.assertTrue(relationService.deleteRelationAsync(relationA).get()); Assert.assertFalse(relationService.checkRelation(parentId, childId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.COMMON).get()); Assert.assertTrue(relationService.checkRelation(childId, subChildId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.COMMON).get()); - Assert.assertTrue(relationService.deleteRelation(childId, subChildId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.COMMON).get()); + Assert.assertTrue(relationService.deleteRelationAsync(childId, subChildId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.COMMON).get()); } @Test @@ -96,7 +96,7 @@ public abstract class BaseRelationServiceTest extends AbstractServiceTest { saveRelation(relationA); saveRelation(relationB); - Assert.assertTrue(relationService.deleteEntityRelations(childId).get()); + Assert.assertTrue(relationService.deleteEntityRelationsAsync(childId).get()); Assert.assertFalse(relationService.checkRelation(parentId, childId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.COMMON).get()); @@ -152,7 +152,7 @@ public abstract class BaseRelationServiceTest extends AbstractServiceTest { } private Boolean saveRelation(EntityRelation relationA1) throws ExecutionException, InterruptedException { - return relationService.saveRelation(relationA1).get(); + return relationService.saveRelationAsync(relationA1).get(); } @Test diff --git a/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/PluginAction.java b/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/PluginAction.java index 04d7881b26..c2ab092e6b 100644 --- a/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/PluginAction.java +++ b/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/PluginAction.java @@ -28,7 +28,7 @@ import java.util.Optional; public interface PluginAction extends ConfigurableComponent, RuleLifecycleComponent { - Optional> convert(RuleContext ctx, ToDeviceActorMsg toDeviceActorMsg, RuleProcessingMetaData deviceMsgMd); + Optional convert(RuleContext ctx, ToDeviceActorMsg toDeviceActorMsg, RuleProcessingMetaData deviceMsgMd); Optional convert(PluginToRuleMsg response); diff --git a/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/handlers/DefaultWebsocketMsgHandler.java b/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/handlers/DefaultWebsocketMsgHandler.java index afcb693270..62558b66a3 100644 --- a/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/handlers/DefaultWebsocketMsgHandler.java +++ b/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/handlers/DefaultWebsocketMsgHandler.java @@ -33,6 +33,7 @@ import java.util.Map; @Slf4j public class DefaultWebsocketMsgHandler implements WebsocketMsgHandler { + public static final String PROCESSING_MSG = "[{}] Processing: {}"; protected final ObjectMapper jsonMapper = new ObjectMapper(); protected final Map wsSessionsMap = new HashMap<>(); @@ -41,9 +42,9 @@ public class DefaultWebsocketMsgHandler implements WebsocketMsgHandler { public void process(PluginContext ctx, PluginWebsocketMsg wsMsg) { PluginWebsocketSessionRef sessionRef = wsMsg.getSessionRef(); if (log.isTraceEnabled()) { - log.trace("[{}] Processing: {}", sessionRef.getSessionId(), wsMsg); + log.trace(PROCESSING_MSG, sessionRef.getSessionId(), wsMsg); } else { - log.debug("[{}] Processing: {}", sessionRef.getSessionId(), wsMsg.getClass().getSimpleName()); + log.debug(PROCESSING_MSG, sessionRef.getSessionId(), wsMsg.getClass().getSimpleName()); } if (wsMsg instanceof SessionEventPluginWebSocketMsg) { handleWebSocketSessionEvent(ctx, sessionRef, (SessionEventPluginWebSocketMsg) wsMsg); @@ -59,19 +60,19 @@ public class DefaultWebsocketMsgHandler implements WebsocketMsgHandler { } protected void cleanupWebSocketSession(PluginContext ctx, String sessionId) { - + //Do nothing } protected void handleWebSocketSessionEvent(PluginContext ctx, PluginWebsocketSessionRef sessionRef, SessionEventPluginWebSocketMsg wsMsg) { String sessionId = sessionRef.getSessionId(); SessionEvent event = wsMsg.getPayload(); - log.debug("[{}] Processing: {}", sessionId, event); + log.debug(PROCESSING_MSG, sessionId, event); switch (event.getEventType()) { case ESTABLISHED: wsSessionsMap.put(sessionId, new WsSessionMetaData(sessionRef)); break; case ERROR: - log.debug("[{}] Unknown websocket session error: {}. ", sessionId, event.getError().get()); + log.debug("[{}] Unknown websocket session error: {}. ", sessionId, event.getError().orElse(null)); break; case CLOSED: wsSessionsMap.remove(sessionId); diff --git a/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/ws/BasicPluginWebsocketSessionRef.java b/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/ws/BasicPluginWebsocketSessionRef.java index ea765513b2..c5a63c6f2b 100644 --- a/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/ws/BasicPluginWebsocketSessionRef.java +++ b/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/ws/BasicPluginWebsocketSessionRef.java @@ -30,7 +30,7 @@ public class BasicPluginWebsocketSessionRef implements PluginWebsocketSessionRef private final String sessionId; private final PluginApiCallSecurityContext securityCtx; private final URI uri; - private final Map attributes; + private final transient Map attributes; private final InetSocketAddress localAddress; private final InetSocketAddress remoteAddress; diff --git a/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/ws/msg/AbstractPluginWebSocketMsg.java b/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/ws/msg/AbstractPluginWebSocketMsg.java index 6adadffb27..a50ffab377 100644 --- a/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/ws/msg/AbstractPluginWebSocketMsg.java +++ b/extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/ws/msg/AbstractPluginWebSocketMsg.java @@ -20,12 +20,14 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.extensions.api.plugins.PluginApiCallSecurityContext; import org.thingsboard.server.extensions.api.plugins.ws.PluginWebsocketSessionRef; +import java.io.Serializable; + public abstract class AbstractPluginWebSocketMsg implements PluginWebsocketMsg { private static final long serialVersionUID = 1L; private final PluginWebsocketSessionRef sessionRef; - private final T payload; + private final transient T payload; AbstractPluginWebSocketMsg(PluginWebsocketSessionRef sessionRef, T payload) { this.sessionRef = sessionRef; diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/mail/SendMailAction.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/mail/SendMailAction.java index f5eb23fe02..0f3bacdca9 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/mail/SendMailAction.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/mail/SendMailAction.java @@ -74,7 +74,7 @@ public class SendMailAction extends SimpleRuleLifecycleComponent implements Plug } @Override - public Optional> convert(RuleContext ctx, ToDeviceActorMsg toDeviceActorMsg, RuleProcessingMetaData metadata) { + public Optional convert(RuleContext ctx, ToDeviceActorMsg toDeviceActorMsg, RuleProcessingMetaData metadata) { String sendFlag = configuration.getSendFlag(); if (StringUtils.isEmpty(sendFlag) || (Boolean) metadata.get(sendFlag).orElse(Boolean.FALSE)) { VelocityContext context = VelocityUtils.createContext(metadata); diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/RpcPluginAction.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/RpcPluginAction.java index d2b4f85f4f..e3f9bba862 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/RpcPluginAction.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/RpcPluginAction.java @@ -37,10 +37,11 @@ import java.util.Optional; public class RpcPluginAction extends SimpleRuleLifecycleComponent implements PluginAction { public void init(EmptyComponentConfiguration configuration) { + //Do nothing } @Override - public Optional> convert(RuleContext ctx, ToDeviceActorMsg toDeviceActorMsg, RuleProcessingMetaData deviceMsgMd) { + public Optional convert(RuleContext ctx, ToDeviceActorMsg toDeviceActorMsg, RuleProcessingMetaData deviceMsgMd) { FromDeviceMsg msg = toDeviceActorMsg.getPayload(); if (msg.getMsgType() == MsgType.TO_SERVER_RPC_REQUEST) { ToServerRpcRequestMsg payload = (ToServerRpcRequestMsg) msg; diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/ServerSideRpcCallAction.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/ServerSideRpcCallAction.java index 7a92543674..36a438f50c 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/ServerSideRpcCallAction.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/ServerSideRpcCallAction.java @@ -64,7 +64,7 @@ public class ServerSideRpcCallAction extends SimpleRuleLifecycleComponent implem } @Override - public Optional> convert(RuleContext ctx, ToDeviceActorMsg toDeviceActorMsg, RuleProcessingMetaData metadata) { + public Optional convert(RuleContext ctx, ToDeviceActorMsg toDeviceActorMsg, RuleProcessingMetaData metadata) { String sendFlag = configuration.getSendFlag(); if (StringUtils.isEmpty(sendFlag) || (Boolean) metadata.get(sendFlag).orElse(Boolean.FALSE)) { VelocityContext context = VelocityUtils.createContext(metadata); diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/telemetry/TelemetryPluginAction.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/telemetry/TelemetryPluginAction.java index ce6fd57c5f..24dfd541b0 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/telemetry/TelemetryPluginAction.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/telemetry/TelemetryPluginAction.java @@ -50,7 +50,7 @@ public class TelemetryPluginAction extends SimpleRuleLifecycleComponent implemen } @Override - public Optional> convert(RuleContext ctx, ToDeviceActorMsg toDeviceActorMsg, RuleProcessingMetaData deviceMsgMd) { + public Optional convert(RuleContext ctx, ToDeviceActorMsg toDeviceActorMsg, RuleProcessingMetaData deviceMsgMd) { FromDeviceMsg msg = toDeviceActorMsg.getPayload(); if (msg.getMsgType() == MsgType.POST_TELEMETRY_REQUEST) { TelemetryUploadRequest payload = (TelemetryUploadRequest) msg; diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/template/AbstractTemplatePluginAction.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/template/AbstractTemplatePluginAction.java index 0274141278..57fdcd3971 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/template/AbstractTemplatePluginAction.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/template/AbstractTemplatePluginAction.java @@ -52,7 +52,7 @@ public abstract class AbstractTemplatePluginAction> convert(RuleContext ctx, ToDeviceActorMsg msg, RuleProcessingMetaData deviceMsgMd) { + public Optional convert(RuleContext ctx, ToDeviceActorMsg msg, RuleProcessingMetaData deviceMsgMd) { FromDeviceRequestMsg payload; if (msg.getPayload() instanceof FromDeviceRequestMsg) { payload = (FromDeviceRequestMsg) msg.getPayload(); @@ -76,7 +76,7 @@ public abstract class AbstractTemplatePluginAction> buildRuleToPluginMsg(RuleContext ctx, + abstract protected Optional buildRuleToPluginMsg(RuleContext ctx, ToDeviceActorMsg msg, FromDeviceRequestMsg payload); diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/filter/DeviceAttributesFilter.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/filter/DeviceAttributesFilter.java index 323de921bd..7dbe6b1262 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/filter/DeviceAttributesFilter.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/filter/DeviceAttributesFilter.java @@ -46,6 +46,8 @@ public class DeviceAttributesFilter extends BasicJsFilter { case POST_ATTRIBUTES_REQUEST: bindings = NashornJsEvaluator.updateBindings(bindings, (UpdateAttributesRequest) msg); break; + default: + break; } } diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/filter/NashornJsEvaluator.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/filter/NashornJsEvaluator.java index 84b76cad5d..5d4f3d5e7d 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/filter/NashornJsEvaluator.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/filter/NashornJsEvaluator.java @@ -85,13 +85,13 @@ public class NashornJsEvaluator { protected static Object getValue(KvEntry attr) { switch (attr.getDataType()) { case STRING: - return attr.getStrValue().get(); + return attr.getStrValue().orElse(null); case LONG: - return attr.getLongValue().get(); + return attr.getLongValue().orElse(null); case DOUBLE: - return attr.getDoubleValue().get(); + return attr.getDoubleValue().orElse(null); case BOOLEAN: - return attr.getBooleanValue().get(); + return attr.getBooleanValue().orElse(null); } return null; } diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/messaging/DeviceMessagingPlugin.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/messaging/DeviceMessagingPlugin.java index 8fb5eef497..011ccca27a 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/messaging/DeviceMessagingPlugin.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/messaging/DeviceMessagingPlugin.java @@ -54,16 +54,16 @@ public class DeviceMessagingPlugin extends AbstractPlugin pendingMsgs = new HashMap<>(); @@ -69,6 +67,7 @@ public class DeviceMessagingRuleMsgHandler implements RuleMsgHandler { switch (request.getMethod()) { case GET_DEVICE_LIST_METHOD_NAME: processGetDeviceList(ctx, md); + break; case SEND_MSG_METHOD_NAME: processSendMsg(ctx, md, request); break; @@ -89,8 +88,9 @@ public class DeviceMessagingRuleMsgHandler implements RuleMsgHandler { if (pendindMsg != null) { log.trace("[{}] Received response: {}", requestId, msg); ToServerRpcResponseMsg response; - if (msg.getError().isPresent()) { - response = new ToServerRpcResponseMsg(pendindMsg.getRequestId(), toJsonString(msg.getError().get())); + Optional rpcError = msg.getError(); + if (rpcError.isPresent()) { + response = new ToServerRpcResponseMsg(pendindMsg.getRequestId(), toJsonString(rpcError.get())); } else { response = new ToServerRpcResponseMsg(pendindMsg.getRequestId(), msg.getResponse().orElse("")); } @@ -200,7 +200,7 @@ public class DeviceMessagingRuleMsgHandler implements RuleMsgHandler { private String toJsonString(String error) { JsonObject errorObj = new JsonObject(); - errorObj.addProperty("error", error); + errorObj.addProperty(ERROR_PROPERTY, error); return GSON.toJson(errorObj); } @@ -208,19 +208,19 @@ public class DeviceMessagingRuleMsgHandler implements RuleMsgHandler { JsonObject errorObj = new JsonObject(); switch (error) { case NOT_FOUND: - errorObj.addProperty("error", "Target device not found!"); + errorObj.addProperty(ERROR_PROPERTY, "Target device not found!"); break; case NO_ACTIVE_CONNECTION: - errorObj.addProperty("error", "No active connection to remote device!"); + errorObj.addProperty(ERROR_PROPERTY, "No active connection to remote device!"); break; case TIMEOUT: - errorObj.addProperty("error", "Timeout while waiting response from device!"); + errorObj.addProperty(ERROR_PROPERTY, "Timeout while waiting response from device!"); break; case FORBIDDEN: - errorObj.addProperty("error", "This action is not allowed! Devices are unassigned or assigned to different customers!"); + errorObj.addProperty(ERROR_PROPERTY, "This action is not allowed! Devices are unassigned or assigned to different customers!"); break; case INTERNAL: - errorObj.addProperty("error", "Internal server error!"); + errorObj.addProperty(ERROR_PROPERTY, "Internal server error!"); break; } return GSON.toJson(errorObj); diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/RpcPlugin.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/RpcPlugin.java index 00ab4965da..aab9648a5f 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/RpcPlugin.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/RpcPlugin.java @@ -71,16 +71,16 @@ public class RpcPlugin extends AbstractPlugin { @Override public void resume(PluginContext ctx) { - + //Do nothing } @Override public void suspend(PluginContext ctx) { - + //Do nothing } @Override public void stop(PluginContext ctx) { - + //Do nothing } } diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/handlers/RpcRestMsgHandler.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/handlers/RpcRestMsgHandler.java index 7cf6dfcbc1..c71b171871 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/handlers/RpcRestMsgHandler.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/handlers/RpcRestMsgHandler.java @@ -110,8 +110,9 @@ public class RpcRestMsgHandler extends DefaultRestMsgHandler { } public void reply(PluginContext ctx, DeferredResult responseWriter, FromDeviceRpcResponse response) { - if (response.getError().isPresent()) { - RpcError error = response.getError().get(); + Optional rpcError = response.getError(); + if (rpcError.isPresent()) { + RpcError error = rpcError.get(); switch (error) { case TIMEOUT: responseWriter.setResult(new ResponseEntity<>(HttpStatus.REQUEST_TIMEOUT)); @@ -124,8 +125,9 @@ public class RpcRestMsgHandler extends DefaultRestMsgHandler { break; } } else { - if (response.getResponse().isPresent() && !StringUtils.isEmpty(response.getResponse().get())) { - String data = response.getResponse().get(); + Optional responseData = response.getResponse(); + if (responseData.isPresent() && !StringUtils.isEmpty(responseData.get())) { + String data = responseData.get(); try { responseWriter.setResult(new ResponseEntity<>(jsonMapper.readTree(data), HttpStatus.OK)); } catch (IOException e) { diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/SubscriptionManager.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/SubscriptionManager.java index 60f46cee3f..d137e10fbd 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/SubscriptionManager.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/SubscriptionManager.java @@ -134,32 +134,7 @@ public class SubscriptionManager { if (sessionSubscriptions != null) { Subscription subscription = sessionSubscriptions.remove(subscriptionId); if (subscription != null) { - EntityId entityId = subscription.getEntityId(); - if (subscription.isLocal() && subscription.getServer() != null) { - rpcHandler.onSubscriptionClose(ctx, subscription.getServer(), sessionId, subscription.getSubscriptionId()); - } - if (sessionSubscriptions.isEmpty()) { - log.debug("[{}] Removed last subscription for particular session.", sessionId); - subscriptionsByWsSessionId.remove(sessionId); - } else { - log.debug("[{}] Removed session subscription.", sessionId); - } - Set deviceSubscriptions = subscriptionsByEntityId.get(entityId); - if (deviceSubscriptions != null) { - boolean result = deviceSubscriptions.remove(subscription); - if (result) { - if (deviceSubscriptions.size() == 0) { - log.debug("[{}] Removed last subscription for particular device.", sessionId); - subscriptionsByEntityId.remove(entityId); - } else { - log.debug("[{}] Removed device subscription.", sessionId); - } - } else { - log.debug("[{}] Subscription not found!", sessionId); - } - } else { - log.debug("[{}] No device subscriptions found!", sessionId); - } + processSubscriptionRemoval(ctx, sessionId, sessionSubscriptions, subscription); } else { log.debug("[{}][{}] Subscription not found!", sessionId, subscriptionId); } @@ -168,6 +143,36 @@ public class SubscriptionManager { } } + private void processSubscriptionRemoval(PluginContext ctx, String sessionId, + Map sessionSubscriptions, Subscription subscription) { + EntityId entityId = subscription.getEntityId(); + if (subscription.isLocal() && subscription.getServer() != null) { + rpcHandler.onSubscriptionClose(ctx, subscription.getServer(), sessionId, subscription.getSubscriptionId()); + } + if (sessionSubscriptions.isEmpty()) { + log.debug("[{}] Removed last subscription for particular session.", sessionId); + subscriptionsByWsSessionId.remove(sessionId); + } else { + log.debug("[{}] Removed session subscription.", sessionId); + } + Set deviceSubscriptions = subscriptionsByEntityId.get(entityId); + if (deviceSubscriptions != null) { + boolean result = deviceSubscriptions.remove(subscription); + if (result) { + if (deviceSubscriptions.size() == 0) { + log.debug("[{}] Removed last subscription for particular device.", sessionId); + subscriptionsByEntityId.remove(entityId); + } else { + log.debug("[{}] Removed device subscription.", sessionId); + } + } else { + log.debug("[{}] Subscription not found!", sessionId); + } + } else { + log.debug("[{}] No device subscriptions found!", sessionId); + } + } + public void onLocalSubscriptionUpdate(PluginContext ctx, EntityId entityId, SubscriptionType type, Function> f) { Set deviceSubscriptions = subscriptionsByEntityId.get(entityId); if (deviceSubscriptions != null) { @@ -272,22 +277,26 @@ public class SubscriptionManager { log.debug("[{}] Removed {} subscriptions for particular session.", sessionId, sessionSubscriptionSize); if (localSession) { - Set affectedServers = new HashSet<>(); - for (Subscription subscription : sessionSubscriptions.values()) { - if (subscription.getServer() != null) { - affectedServers.add(subscription.getServer()); - } - } - for (ServerAddress address : affectedServers) { - log.debug("[{}] Going to onSubscriptionUpdate [{}] server about session close event", sessionId, address); - rpcHandler.onSessionClose(ctx, address, sessionId); - } + notifyWsSubscriptionClosed(ctx, sessionId, sessionSubscriptions); } } else { log.debug("[{}] No subscriptions found!", sessionId); } } + private void notifyWsSubscriptionClosed(PluginContext ctx, String sessionId, Map sessionSubscriptions) { + Set affectedServers = new HashSet<>(); + for (Subscription subscription : sessionSubscriptions.values()) { + if (subscription.getServer() != null) { + affectedServers.add(subscription.getServer()); + } + } + for (ServerAddress address : affectedServers) { + log.debug("[{}] Going to onSubscriptionUpdate [{}] server about session close event", sessionId, address); + rpcHandler.onSessionClose(ctx, address, sessionId); + } + } + public void onClusterUpdate(PluginContext ctx) { log.trace("Processing cluster onUpdate msg!"); Iterator>> deviceIterator = subscriptionsByEntityId.entrySet().iterator(); @@ -296,35 +305,9 @@ public class SubscriptionManager { Set subscriptions = e.getValue(); Optional newAddressOptional = ctx.resolve(e.getKey()); if (newAddressOptional.isPresent()) { - ServerAddress newAddress = newAddressOptional.get(); - Iterator subscriptionIterator = subscriptions.iterator(); - while (subscriptionIterator.hasNext()) { - Subscription s = subscriptionIterator.next(); - if (s.isLocal()) { - if (!newAddress.equals(s.getServer())) { - log.trace("[{}] Local subscription is now handled on new server [{}]", s.getWsSessionId(), newAddress); - s.setServer(newAddress); - rpcHandler.onNewSubscription(ctx, newAddress, s.getWsSessionId(), s); - } - } else { - log.trace("[{}] Remote subscription is now handled on new server address: [{}]", s.getWsSessionId(), newAddress); - subscriptionIterator.remove(); - //TODO: onUpdate state of subscription by WsSessionId and other maps. - } - } + checkSubsciptionsNewAddress(ctx, newAddressOptional, subscriptions); } else { - Iterator subscriptionIterator = subscriptions.iterator(); - while (subscriptionIterator.hasNext()) { - Subscription s = subscriptionIterator.next(); - if (s.isLocal()) { - if (s.getServer() != null) { - log.trace("[{}] Local subscription is no longer handled on remote server address [{}]", s.getWsSessionId(), s.getServer()); - s.setServer(null); - } - } else { - log.trace("[{}] Remote subscription is on up to date server address.", s.getWsSessionId()); - } - } + checkSubsciptionsPrevAddress(subscriptions); } if (subscriptions.size() == 0) { log.trace("[{}] No more subscriptions for this device on current server.", e.getKey()); @@ -333,6 +316,42 @@ public class SubscriptionManager { } } + private void checkSubsciptionsNewAddress(PluginContext ctx, Optional newAddressOptional, Set subscriptions) { + if (newAddressOptional.isPresent()) { + ServerAddress newAddress = newAddressOptional.get(); + Iterator subscriptionIterator = subscriptions.iterator(); + while (subscriptionIterator.hasNext()) { + Subscription s = subscriptionIterator.next(); + if (s.isLocal()) { + if (!newAddress.equals(s.getServer())) { + log.trace("[{}] Local subscription is now handled on new server [{}]", s.getWsSessionId(), newAddress); + s.setServer(newAddress); + rpcHandler.onNewSubscription(ctx, newAddress, s.getWsSessionId(), s); + } + } else { + log.trace("[{}] Remote subscription is now handled on new server address: [{}]", s.getWsSessionId(), newAddress); + subscriptionIterator.remove(); + //TODO: onUpdate state of subscription by WsSessionId and other maps. + } + } + } + } + + private void checkSubsciptionsPrevAddress(Set subscriptions) { + Iterator subscriptionIterator = subscriptions.iterator(); + while (subscriptionIterator.hasNext()) { + Subscription s = subscriptionIterator.next(); + if (s.isLocal()) { + if (s.getServer() != null) { + log.trace("[{}] Local subscription is no longer handled on remote server address [{}]", s.getWsSessionId(), s.getServer()); + s.setServer(null); + } + } else { + log.trace("[{}] Remote subscription is on up to date server address.", s.getWsSessionId()); + } + } + } + public void clear() { subscriptionsByWsSessionId.clear(); subscriptionsByEntityId.clear(); diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/TelemetryStoragePlugin.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/TelemetryStoragePlugin.java index 94444c8767..91027fed78 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/TelemetryStoragePlugin.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/TelemetryStoragePlugin.java @@ -53,7 +53,7 @@ public class TelemetryStoragePlugin extends AbstractPlugin historyCmds; public TelemetryPluginCmdsWrapper() { + super(); } public List getAttrSubCmds() { diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRestMsgHandler.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRestMsgHandler.java index 440e28b6d0..87613d91c7 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRestMsgHandler.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRestMsgHandler.java @@ -74,69 +74,88 @@ public class TelemetryRestMsgHandler extends DefaultRestMsgHandler { EntityId entityId = EntityIdFactory.getByTypeAndId(entityType, entityIdStr); if (method.equals("keys")) { - if (feature == TelemetryFeature.TIMESERIES) { - ctx.loadLatestTimeseries(entityId, new PluginCallback>() { - @Override - public void onSuccess(PluginContext ctx, List value) { - List keys = value.stream().map(tsKv -> tsKv.getKey()).collect(Collectors.toList()); - msg.getResponseHolder().setResult(new ResponseEntity<>(keys, HttpStatus.OK)); - } - - @Override - public void onFailure(PluginContext ctx, Exception e) { - msg.getResponseHolder().setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR)); - } - }); - } else if (feature == TelemetryFeature.ATTRIBUTES) { - PluginCallback> callback = getAttributeKeysPluginCallback(msg); - if (!StringUtils.isEmpty(scope)) { - ctx.loadAttributes(entityId, scope, callback); - } else { - ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), callback); - } - } + handleHttpGetKeysMethod(ctx, msg, feature, scope, entityId); } else if (method.equals("values")) { - if (feature == TelemetryFeature.TIMESERIES) { - String keysStr = request.getParameter("keys"); - List keys = Arrays.asList(keysStr.split(",")); - - Optional startTs = request.getLongParamValue("startTs"); - Optional endTs = request.getLongParamValue("endTs"); - Optional interval = request.getLongParamValue("interval"); - Optional limit = request.getIntParamValue("limit"); - - if (startTs.isPresent() || endTs.isPresent() || interval.isPresent() || limit.isPresent()) { - if (!startTs.isPresent() || !endTs.isPresent() || !interval.isPresent()) { - msg.getResponseHolder().setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST)); - return; - } - Aggregation agg = Aggregation.valueOf(request.getParameter("agg", Aggregation.NONE.name())); + handleHttpGetValuesMethod(ctx, msg, request, feature, scope, entityId); + } + } - List queries = keys.stream().map(key -> new BaseTsKvQuery(key, startTs.get(), endTs.get(), interval.get(), limit.orElse(TelemetryWebsocketMsgHandler.DEFAULT_LIMIT), agg)) - .collect(Collectors.toList()); - ctx.loadTimeseries(entityId, queries, getTsKvListCallback(msg)); - } else { - ctx.loadLatestTimeseries(entityId, keys, getTsKvListCallback(msg)); + private void handleHttpGetKeysMethod(PluginContext ctx, PluginRestMsg msg, TelemetryFeature feature, String scope, EntityId entityId) { + if (feature == TelemetryFeature.TIMESERIES) { + ctx.loadLatestTimeseries(entityId, new PluginCallback>() { + @Override + public void onSuccess(PluginContext ctx, List value) { + List keys = value.stream().map(tsKv -> tsKv.getKey()).collect(Collectors.toList()); + msg.getResponseHolder().setResult(new ResponseEntity<>(keys, HttpStatus.OK)); } - } else if (feature == TelemetryFeature.ATTRIBUTES) { - String keys = request.getParameter("keys", ""); - - PluginCallback> callback = getAttributeValuesPluginCallback(msg); - if (!StringUtils.isEmpty(scope)) { - if (!StringUtils.isEmpty(keys)) { - List keyList = Arrays.asList(keys.split(",")); - ctx.loadAttributes(entityId, scope, keyList, callback); - } else { - ctx.loadAttributes(entityId, scope, callback); - } - } else { - if (!StringUtils.isEmpty(keys)) { - List keyList = Arrays.asList(keys.split(",")); - ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), keyList, callback); - } else { - ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), callback); - } + + @Override + public void onFailure(PluginContext ctx, Exception e) { + msg.getResponseHolder().setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR)); } + }); + } else if (feature == TelemetryFeature.ATTRIBUTES) { + PluginCallback> callback = getAttributeKeysPluginCallback(msg); + if (!StringUtils.isEmpty(scope)) { + ctx.loadAttributes(entityId, scope, callback); + } else { + ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), callback); + } + } + } + + private void handleHttpGetValuesMethod(PluginContext ctx, PluginRestMsg msg, + RestRequest request, TelemetryFeature feature, + String scope, EntityId entityId) throws ServletException { + if (feature == TelemetryFeature.TIMESERIES) { + handleHttpGetTimeseriesValues(ctx, msg, request, entityId); + } else if (feature == TelemetryFeature.ATTRIBUTES) { + handleHttpGetAttributesValues(ctx, msg, request, scope, entityId); + } + } + + private void handleHttpGetTimeseriesValues(PluginContext ctx, PluginRestMsg msg, RestRequest request, EntityId entityId) throws ServletException { + String keysStr = request.getParameter("keys"); + List keys = Arrays.asList(keysStr.split(",")); + + Optional startTs = request.getLongParamValue("startTs"); + Optional endTs = request.getLongParamValue("endTs"); + Optional interval = request.getLongParamValue("interval"); + Optional limit = request.getIntParamValue("limit"); + + if (startTs.isPresent() || endTs.isPresent() || interval.isPresent() || limit.isPresent()) { + if (!startTs.isPresent() || !endTs.isPresent() || !interval.isPresent()) { + msg.getResponseHolder().setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST)); + return; + } + Aggregation agg = Aggregation.valueOf(request.getParameter("agg", Aggregation.NONE.name())); + + List queries = keys.stream().map(key -> new BaseTsKvQuery(key, startTs.get(), endTs.get(), interval.get(), limit.orElse(TelemetryWebsocketMsgHandler.DEFAULT_LIMIT), agg)) + .collect(Collectors.toList()); + ctx.loadTimeseries(entityId, queries, getTsKvListCallback(msg)); + } else { + ctx.loadLatestTimeseries(entityId, keys, getTsKvListCallback(msg)); + } + } + + private void handleHttpGetAttributesValues(PluginContext ctx, PluginRestMsg msg, + RestRequest request, String scope, EntityId entityId) throws ServletException { + String keys = request.getParameter("keys", ""); + + PluginCallback> callback = getAttributeValuesPluginCallback(msg); + if (!StringUtils.isEmpty(scope)) { + if (!StringUtils.isEmpty(keys)) { + List keyList = Arrays.asList(keys.split(",")); + ctx.loadAttributes(entityId, scope, keyList, callback); + } else { + ctx.loadAttributes(entityId, scope, callback); + } + } else { + if (!StringUtils.isEmpty(keys)) { + List keyList = Arrays.asList(keys.split(",")); + ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), keyList, callback); + } else { + ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), callback); } } } @@ -172,64 +191,11 @@ public class TelemetryRestMsgHandler extends DefaultRestMsgHandler { return; } if (feature == TelemetryFeature.ATTRIBUTES) { - if (DataConstants.SERVER_SCOPE.equals(scope) || - DataConstants.SHARED_SCOPE.equals(scope)) { - JsonNode jsonNode = jsonMapper.readTree(request.getRequestBody()); - if (jsonNode.isObject()) { - long ts = System.currentTimeMillis(); - List attributes = new ArrayList<>(); - jsonNode.fields().forEachRemaining(entry -> { - String key = entry.getKey(); - JsonNode value = entry.getValue(); - if (entry.getValue().isTextual()) { - attributes.add(new BaseAttributeKvEntry(new StringDataEntry(key, value.textValue()), ts)); - } else if (entry.getValue().isBoolean()) { - attributes.add(new BaseAttributeKvEntry(new BooleanDataEntry(key, value.booleanValue()), ts)); - } else if (entry.getValue().isDouble()) { - attributes.add(new BaseAttributeKvEntry(new DoubleDataEntry(key, value.doubleValue()), ts)); - } else if (entry.getValue().isNumber()) { - attributes.add(new BaseAttributeKvEntry(new LongDataEntry(key, value.longValue()), ts)); - } - }); - if (attributes.size() > 0) { - ctx.saveAttributes(ctx.getSecurityCtx().orElseThrow(() -> new IllegalArgumentException()).getTenantId(), entityId, scope, attributes, new PluginCallback() { - @Override - public void onSuccess(PluginContext ctx, Void value) { - msg.getResponseHolder().setResult(new ResponseEntity<>(HttpStatus.OK)); - subscriptionManager.onAttributesUpdateFromServer(ctx, entityId, scope, attributes); - } - - @Override - public void onFailure(PluginContext ctx, Exception e) { - log.error("Failed to save attributes", e); - msg.getResponseHolder().setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR)); - } - }); - return; - } - } + if (handleHttpPostAttributes(ctx, msg, request, entityId, scope)) { + return; } } else if (feature == TelemetryFeature.TIMESERIES) { - TelemetryUploadRequest telemetryRequest = JsonConverter.convertToTelemetry(new JsonParser().parse(request.getRequestBody())); - List entries = new ArrayList<>(); - for (Map.Entry> entry : telemetryRequest.getData().entrySet()) { - for (KvEntry kv : entry.getValue()) { - entries.add(new BasicTsKvEntry(entry.getKey(), kv)); - } - } - ctx.saveTsData(entityId, entries, ttl, new PluginCallback() { - @Override - public void onSuccess(PluginContext ctx, Void value) { - msg.getResponseHolder().setResult(new ResponseEntity<>(HttpStatus.OK)); - subscriptionManager.onTimeseriesUpdateFromServer(ctx, entityId, entries); - } - - @Override - public void onFailure(PluginContext ctx, Exception e) { - log.error("Failed to save attributes", e); - msg.getResponseHolder().setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR)); - } - }); + handleHttpPostTimeseries(ctx, msg, request, entityId, ttl); return; } } catch (IOException | RuntimeException e) { @@ -238,6 +204,71 @@ public class TelemetryRestMsgHandler extends DefaultRestMsgHandler { msg.getResponseHolder().setResult(new ResponseEntity<>(HttpStatus.BAD_REQUEST)); } + private boolean handleHttpPostAttributes(PluginContext ctx, PluginRestMsg msg, RestRequest request, + EntityId entityId, String scope) throws ServletException, IOException { + if (DataConstants.SERVER_SCOPE.equals(scope) || + DataConstants.SHARED_SCOPE.equals(scope)) { + JsonNode jsonNode = jsonMapper.readTree(request.getRequestBody()); + if (jsonNode.isObject()) { + long ts = System.currentTimeMillis(); + List attributes = new ArrayList<>(); + jsonNode.fields().forEachRemaining(entry -> { + String key = entry.getKey(); + JsonNode value = entry.getValue(); + if (entry.getValue().isTextual()) { + attributes.add(new BaseAttributeKvEntry(new StringDataEntry(key, value.textValue()), ts)); + } else if (entry.getValue().isBoolean()) { + attributes.add(new BaseAttributeKvEntry(new BooleanDataEntry(key, value.booleanValue()), ts)); + } else if (entry.getValue().isDouble()) { + attributes.add(new BaseAttributeKvEntry(new DoubleDataEntry(key, value.doubleValue()), ts)); + } else if (entry.getValue().isNumber()) { + attributes.add(new BaseAttributeKvEntry(new LongDataEntry(key, value.longValue()), ts)); + } + }); + if (attributes.size() > 0) { + ctx.saveAttributes(ctx.getSecurityCtx().orElseThrow(() -> new IllegalArgumentException()).getTenantId(), entityId, scope, attributes, new PluginCallback() { + @Override + public void onSuccess(PluginContext ctx, Void value) { + msg.getResponseHolder().setResult(new ResponseEntity<>(HttpStatus.OK)); + subscriptionManager.onAttributesUpdateFromServer(ctx, entityId, scope, attributes); + } + + @Override + public void onFailure(PluginContext ctx, Exception e) { + log.error("Failed to save attributes", e); + msg.getResponseHolder().setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR)); + } + }); + return true; + } + } + } + return false; + } + + private void handleHttpPostTimeseries(PluginContext ctx, PluginRestMsg msg, RestRequest request, EntityId entityId, long ttl) { + TelemetryUploadRequest telemetryRequest = JsonConverter.convertToTelemetry(new JsonParser().parse(request.getRequestBody())); + List entries = new ArrayList<>(); + for (Map.Entry> entry : telemetryRequest.getData().entrySet()) { + for (KvEntry kv : entry.getValue()) { + entries.add(new BasicTsKvEntry(entry.getKey(), kv)); + } + } + ctx.saveTsData(entityId, entries, ttl, new PluginCallback() { + @Override + public void onSuccess(PluginContext ctx, Void value) { + msg.getResponseHolder().setResult(new ResponseEntity<>(HttpStatus.OK)); + subscriptionManager.onTimeseriesUpdateFromServer(ctx, entityId, entries); + } + + @Override + public void onFailure(PluginContext ctx, Exception e) { + log.error("Failed to save attributes", e); + msg.getResponseHolder().setResult(new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR)); + } + }); + } + @Override public void handleHttpDeleteRequest(PluginContext ctx, PluginRestMsg msg) throws ServletException { RestRequest request = msg.getRequest(); diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRpcMsgHandler.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRpcMsgHandler.java index a1b734e991..ba5d61080e 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRpcMsgHandler.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRpcMsgHandler.java @@ -29,10 +29,7 @@ import org.thingsboard.server.extensions.core.plugin.telemetry.SubscriptionManag import org.thingsboard.server.extensions.core.plugin.telemetry.gen.TelemetryPluginProtos.*; import org.thingsboard.server.extensions.core.plugin.telemetry.sub.*; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; +import java.util.*; import java.util.stream.Collectors; /** @@ -244,16 +241,28 @@ public class TelemetryRpcMsgHandler implements RpcMsgHandler { dataBuilder.setValueType(attr.getDataType().ordinal()); switch (attr.getDataType()) { case BOOLEAN: - dataBuilder.setBoolValue(attr.getBooleanValue().get()); + Optional booleanValue = attr.getBooleanValue(); + if (booleanValue.isPresent()) { + dataBuilder.setBoolValue(booleanValue.get()); + } break; case LONG: - dataBuilder.setLongValue(attr.getLongValue().get()); + Optional longValue = attr.getLongValue(); + if (longValue.isPresent()) { + dataBuilder.setLongValue(longValue.get()); + } break; case DOUBLE: - dataBuilder.setDoubleValue(attr.getDoubleValue().get()); + Optional doubleValue = attr.getDoubleValue(); + if (doubleValue.isPresent()) { + dataBuilder.setDoubleValue(doubleValue.get()); + } break; case STRING: - dataBuilder.setStrValue(attr.getStrValue().get()); + Optional stringValue = attr.getStrValue(); + if (stringValue.isPresent()) { + dataBuilder.setStrValue(stringValue.get()); + } break; } return dataBuilder; diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRuleMsgHandler.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRuleMsgHandler.java index 242345d859..447557333c 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRuleMsgHandler.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryRuleMsgHandler.java @@ -34,6 +34,7 @@ import org.thingsboard.server.extensions.api.plugins.msg.ResponsePluginToRuleMsg import org.thingsboard.server.extensions.api.plugins.msg.TelemetryUploadRequestRuleToPluginMsg; import org.thingsboard.server.extensions.api.plugins.msg.UpdateAttributesRequestRuleToPluginMsg; import org.thingsboard.server.extensions.core.plugin.telemetry.SubscriptionManager; +import org.thingsboard.server.extensions.core.plugin.telemetry.sub.Subscription; import org.thingsboard.server.extensions.core.plugin.telemetry.sub.SubscriptionType; import java.util.*; @@ -96,17 +97,9 @@ public class TelemetryRuleMsgHandler extends DefaultRuleMsgHandler { @Override public void onSuccess(PluginContext ctx, Void data) { ctx.reply(new ResponsePluginToRuleMsg(msg.getUid(), tenantId, ruleId, BasicStatusCodeResponse.onSuccess(request.getMsgType(), request.getRequestId()))); - subscriptionManager.onLocalSubscriptionUpdate(ctx, msg.getDeviceId(), SubscriptionType.TIMESERIES, s -> { - List subscriptionUpdate = new ArrayList(); - for (Map.Entry> entry : request.getData().entrySet()) { - for (KvEntry kv : entry.getValue()) { - if (s.isAllKeys() || s.getKeyStates().containsKey((kv.getKey()))) { - subscriptionUpdate.add(new BasicTsKvEntry(entry.getKey(), kv)); - } - } - } - return subscriptionUpdate; - }); + subscriptionManager.onLocalSubscriptionUpdate(ctx, msg.getDeviceId(), SubscriptionType.TIMESERIES, s -> + prepareSubscriptionUpdate(request, s) + ); } @Override @@ -117,6 +110,18 @@ public class TelemetryRuleMsgHandler extends DefaultRuleMsgHandler { }); } + private List prepareSubscriptionUpdate(TelemetryUploadRequest request, Subscription s) { + List subscriptionUpdate = new ArrayList<>(); + for (Map.Entry> entry : request.getData().entrySet()) { + for (KvEntry kv : entry.getValue()) { + if (s.isAllKeys() || s.getKeyStates().containsKey((kv.getKey()))) { + subscriptionUpdate.add(new BasicTsKvEntry(entry.getKey(), kv)); + } + } + } + return subscriptionUpdate; + } + @Override public void handleUpdateAttributesRequest(PluginContext ctx, TenantId tenantId, RuleId ruleId, UpdateAttributesRequestRuleToPluginMsg msg) { UpdateAttributesRequest request = msg.getPayload(); @@ -127,7 +132,7 @@ public class TelemetryRuleMsgHandler extends DefaultRuleMsgHandler { ctx.reply(new ResponsePluginToRuleMsg(msg.getUid(), tenantId, ruleId, BasicStatusCodeResponse.onSuccess(request.getMsgType(), request.getRequestId()))); subscriptionManager.onLocalSubscriptionUpdate(ctx, msg.getDeviceId(), SubscriptionType.ATTRIBUTES, s -> { - List subscriptionUpdate = new ArrayList(); + List subscriptionUpdate = new ArrayList<>(); for (AttributeKvEntry kv : request.getAttributes()) { if (s.isAllKeys() || s.getKeyStates().containsKey(kv.getKey())) { subscriptionUpdate.add(new BasicTsKvEntry(kv.getLastUpdateTs(), kv)); diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryWebsocketMsgHandler.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryWebsocketMsgHandler.java index c231ffacbe..7b0e6d8fcd 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryWebsocketMsgHandler.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/telemetry/handlers/TelemetryWebsocketMsgHandler.java @@ -51,6 +51,9 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { private static final int UNKNOWN_SUBSCRIPTION_ID = 0; public static final int DEFAULT_LIMIT = 100; public static final Aggregation DEFAULT_AGGREGATION = Aggregation.NONE; + public static final String FAILED_TO_FETCH_DATA = "Failed to fetch data!"; + public static final String FAILED_TO_FETCH_ATTRIBUTES = "Failed to fetch attributes!"; + public static final String SESSION_META_DATA_NOT_FOUND = "Session meta-data not found!"; private final SubscriptionManager subscriptionManager; @@ -84,7 +87,7 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { } catch (IOException e) { log.warn("Failed to decode subscription cmd: {}", e.getMessage(), e); SubscriptionUpdate update = new SubscriptionUpdate(UNKNOWN_SUBSCRIPTION_ID, SubscriptionErrorCode.INTERNAL_ERROR, - "Session meta-data not found!"); + SESSION_META_DATA_NOT_FOUND); sendWsMsg(ctx, sessionRef, update); } } @@ -105,74 +108,83 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { EntityId entityId = EntityIdFactory.getByTypeAndId(cmd.getEntityType(), cmd.getEntityId()); log.debug("[{}] fetching latest attributes ({}) values for device: {}", sessionId, cmd.getKeys(), entityId); Optional> keysOptional = getKeys(cmd); - SubscriptionState sub; if (keysOptional.isPresent()) { List keys = new ArrayList<>(keysOptional.get()); + handleWsAttributesSubscriptionByKeys(ctx, sessionRef, cmd, sessionId, entityId, keys); + } else { + handleWsAttributesSubscription(ctx, sessionRef, cmd, sessionId, entityId); + } + } + } + } + + private void handleWsAttributesSubscriptionByKeys(PluginContext ctx, PluginWebsocketSessionRef sessionRef, + AttributesSubscriptionCmd cmd, String sessionId, EntityId entityId, + List keys) { + PluginCallback> callback = new PluginCallback>() { + @Override + public void onSuccess(PluginContext ctx, List data) { + List attributesData = data.stream().map(d -> new BasicTsKvEntry(d.getLastUpdateTs(), d)).collect(Collectors.toList()); + sendWsMsg(ctx, sessionRef, new SubscriptionUpdate(cmd.getCmdId(), attributesData)); + + Map subState = new HashMap<>(keys.size()); + keys.forEach(key -> subState.put(key, 0L)); + attributesData.forEach(v -> subState.put(v.getKey(), v.getTs())); - PluginCallback> callback = new PluginCallback>() { - @Override - public void onSuccess(PluginContext ctx, List data) { - List attributesData = data.stream().map(d -> new BasicTsKvEntry(d.getLastUpdateTs(), d)).collect(Collectors.toList()); - sendWsMsg(ctx, sessionRef, new SubscriptionUpdate(cmd.getCmdId(), attributesData)); - - Map subState = new HashMap<>(keys.size()); - keys.forEach(key -> subState.put(key, 0L)); - attributesData.forEach(v -> subState.put(v.getKey(), v.getTs())); - - SubscriptionState sub = new SubscriptionState(sessionId, cmd.getCmdId(), entityId, SubscriptionType.ATTRIBUTES, false, subState); - subscriptionManager.addLocalWsSubscription(ctx, sessionId, entityId, sub); - } - - @Override - public void onFailure(PluginContext ctx, Exception e) { - log.error("Failed to fetch attributes!", e); - SubscriptionUpdate update; - if (UnauthorizedException.class.isInstance(e)) { - update = new SubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.UNAUTHORIZED, - SubscriptionErrorCode.UNAUTHORIZED.getDefaultMsg()); - } else { - update = new SubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, - "Failed to fetch attributes!"); - } - sendWsMsg(ctx, sessionRef, update); - } - }; - - if (StringUtils.isEmpty(cmd.getScope())) { - ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), keys, callback); - } else { - ctx.loadAttributes(entityId, cmd.getScope(), keys, callback); - } + SubscriptionState sub = new SubscriptionState(sessionId, cmd.getCmdId(), entityId, SubscriptionType.ATTRIBUTES, false, subState); + subscriptionManager.addLocalWsSubscription(ctx, sessionId, entityId, sub); + } + + @Override + public void onFailure(PluginContext ctx, Exception e) { + log.error(FAILED_TO_FETCH_ATTRIBUTES, e); + SubscriptionUpdate update; + if (UnauthorizedException.class.isInstance(e)) { + update = new SubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.UNAUTHORIZED, + SubscriptionErrorCode.UNAUTHORIZED.getDefaultMsg()); } else { - PluginCallback> callback = new PluginCallback>() { - @Override - public void onSuccess(PluginContext ctx, List data) { - List attributesData = data.stream().map(d -> new BasicTsKvEntry(d.getLastUpdateTs(), d)).collect(Collectors.toList()); - sendWsMsg(ctx, sessionRef, new SubscriptionUpdate(cmd.getCmdId(), attributesData)); - - Map subState = new HashMap<>(attributesData.size()); - attributesData.forEach(v -> subState.put(v.getKey(), v.getTs())); - - SubscriptionState sub = new SubscriptionState(sessionId, cmd.getCmdId(), entityId, SubscriptionType.ATTRIBUTES, true, subState); - subscriptionManager.addLocalWsSubscription(ctx, sessionId, entityId, sub); - } - - @Override - public void onFailure(PluginContext ctx, Exception e) { - log.error("Failed to fetch attributes!", e); - SubscriptionUpdate update = new SubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, - "Failed to fetch attributes!"); - sendWsMsg(ctx, sessionRef, update); - } - }; - - if (StringUtils.isEmpty(cmd.getScope())) { - ctx.loadAttributes(entityId, Arrays.asList(DataConstants.ALL_SCOPES), callback); - } else { - ctx.loadAttributes(entityId, cmd.getScope(), callback); - } + update = new SubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, + FAILED_TO_FETCH_ATTRIBUTES); } + sendWsMsg(ctx, sessionRef, update); } + }; + + if (StringUtils.isEmpty(cmd.getScope())) { + ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), keys, callback); + } else { + ctx.loadAttributes(entityId, cmd.getScope(), keys, callback); + } + } + + private void handleWsAttributesSubscription(PluginContext ctx, PluginWebsocketSessionRef sessionRef, + AttributesSubscriptionCmd cmd, String sessionId, EntityId entityId) { + PluginCallback> callback = new PluginCallback>() { + @Override + public void onSuccess(PluginContext ctx, List data) { + List attributesData = data.stream().map(d -> new BasicTsKvEntry(d.getLastUpdateTs(), d)).collect(Collectors.toList()); + sendWsMsg(ctx, sessionRef, new SubscriptionUpdate(cmd.getCmdId(), attributesData)); + + Map subState = new HashMap<>(attributesData.size()); + attributesData.forEach(v -> subState.put(v.getKey(), v.getTs())); + + SubscriptionState sub = new SubscriptionState(sessionId, cmd.getCmdId(), entityId, SubscriptionType.ATTRIBUTES, true, subState); + subscriptionManager.addLocalWsSubscription(ctx, sessionId, entityId, sub); + } + + @Override + public void onFailure(PluginContext ctx, Exception e) { + log.error(FAILED_TO_FETCH_ATTRIBUTES, e); + SubscriptionUpdate update = new SubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, + FAILED_TO_FETCH_ATTRIBUTES); + sendWsMsg(ctx, sessionRef, update); + } + }; + + if (StringUtils.isEmpty(cmd.getScope())) { + ctx.loadAttributes(entityId, Arrays.asList(DataConstants.allScopes()), callback); + } else { + ctx.loadAttributes(entityId, cmd.getScope(), callback); } } @@ -188,49 +200,59 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { Optional> keysOptional = getKeys(cmd); if (keysOptional.isPresent()) { - long startTs; - if (cmd.getTimeWindow() > 0) { - List keys = new ArrayList<>(getKeys(cmd).orElse(Collections.emptySet())); - log.debug("[{}] fetching timeseries data for last {} ms for keys: ({}) for device : {}", sessionId, cmd.getTimeWindow(), cmd.getKeys(), entityId); - startTs = cmd.getStartTs(); - long endTs = cmd.getStartTs() + cmd.getTimeWindow(); - List queries = keys.stream().map(key -> new BaseTsKvQuery(key, startTs, endTs, cmd.getInterval(), getLimit(cmd.getLimit()), getAggregation(cmd.getAgg()))).collect(Collectors.toList()); - ctx.loadTimeseries(entityId, queries, getSubscriptionCallback(sessionRef, cmd, sessionId, entityId, startTs, keys)); - } else { - List keys = new ArrayList<>(getKeys(cmd).orElse(Collections.emptySet())); - startTs = System.currentTimeMillis(); - log.debug("[{}] fetching latest timeseries data for keys: ({}) for device : {}", sessionId, cmd.getKeys(), entityId); - ctx.loadLatestTimeseries(entityId, keys, getSubscriptionCallback(sessionRef, cmd, sessionId, entityId, startTs, keys)); - } + handleWsTimeseriesSubscriptionByKeys(ctx, sessionRef, cmd, sessionId, entityId); } else { - ctx.loadLatestTimeseries(entityId, new PluginCallback>() { - @Override - public void onSuccess(PluginContext ctx, List data) { - sendWsMsg(ctx, sessionRef, new SubscriptionUpdate(cmd.getCmdId(), data)); - Map subState = new HashMap<>(data.size()); - data.forEach(v -> subState.put(v.getKey(), v.getTs())); - SubscriptionState sub = new SubscriptionState(sessionId, cmd.getCmdId(), entityId, SubscriptionType.TIMESERIES, true, subState); - subscriptionManager.addLocalWsSubscription(ctx, sessionId, entityId, sub); - } - - @Override - public void onFailure(PluginContext ctx, Exception e) { - SubscriptionUpdate update; - if (UnauthorizedException.class.isInstance(e)) { - update = new SubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.UNAUTHORIZED, - SubscriptionErrorCode.UNAUTHORIZED.getDefaultMsg()); - } else { - update = new SubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, - "Failed to fetch data!"); - } - sendWsMsg(ctx, sessionRef, update); - } - }); + handleWsTimeseriesSubscription(ctx, sessionRef, cmd, sessionId, entityId); } } } } + private void handleWsTimeseriesSubscriptionByKeys(PluginContext ctx, PluginWebsocketSessionRef sessionRef, + TimeseriesSubscriptionCmd cmd, String sessionId, EntityId entityId) { + long startTs; + if (cmd.getTimeWindow() > 0) { + List keys = new ArrayList<>(getKeys(cmd).orElse(Collections.emptySet())); + log.debug("[{}] fetching timeseries data for last {} ms for keys: ({}) for device : {}", sessionId, cmd.getTimeWindow(), cmd.getKeys(), entityId); + startTs = cmd.getStartTs(); + long endTs = cmd.getStartTs() + cmd.getTimeWindow(); + List queries = keys.stream().map(key -> new BaseTsKvQuery(key, startTs, endTs, cmd.getInterval(), getLimit(cmd.getLimit()), getAggregation(cmd.getAgg()))).collect(Collectors.toList()); + ctx.loadTimeseries(entityId, queries, getSubscriptionCallback(sessionRef, cmd, sessionId, entityId, startTs, keys)); + } else { + List keys = new ArrayList<>(getKeys(cmd).orElse(Collections.emptySet())); + startTs = System.currentTimeMillis(); + log.debug("[{}] fetching latest timeseries data for keys: ({}) for device : {}", sessionId, cmd.getKeys(), entityId); + ctx.loadLatestTimeseries(entityId, keys, getSubscriptionCallback(sessionRef, cmd, sessionId, entityId, startTs, keys)); + } + } + + private void handleWsTimeseriesSubscription(PluginContext ctx, PluginWebsocketSessionRef sessionRef, + TimeseriesSubscriptionCmd cmd, String sessionId, EntityId entityId) { + ctx.loadLatestTimeseries(entityId, new PluginCallback>() { + @Override + public void onSuccess(PluginContext ctx, List data) { + sendWsMsg(ctx, sessionRef, new SubscriptionUpdate(cmd.getCmdId(), data)); + Map subState = new HashMap<>(data.size()); + data.forEach(v -> subState.put(v.getKey(), v.getTs())); + SubscriptionState sub = new SubscriptionState(sessionId, cmd.getCmdId(), entityId, SubscriptionType.TIMESERIES, true, subState); + subscriptionManager.addLocalWsSubscription(ctx, sessionId, entityId, sub); + } + + @Override + public void onFailure(PluginContext ctx, Exception e) { + SubscriptionUpdate update; + if (UnauthorizedException.class.isInstance(e)) { + update = new SubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.UNAUTHORIZED, + SubscriptionErrorCode.UNAUTHORIZED.getDefaultMsg()); + } else { + update = new SubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, + FAILED_TO_FETCH_DATA); + } + sendWsMsg(ctx, sessionRef, update); + } + }); + } + private PluginCallback> getSubscriptionCallback(final PluginWebsocketSessionRef sessionRef, final TimeseriesSubscriptionCmd cmd, final String sessionId, final EntityId entityId, final long startTs, final List keys) { return new PluginCallback>() { @Override @@ -246,9 +268,9 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { @Override public void onFailure(PluginContext ctx, Exception e) { - log.error("Failed to fetch data!", e); + log.error(FAILED_TO_FETCH_DATA, e); SubscriptionUpdate update = new SubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, - "Failed to fetch data!"); + FAILED_TO_FETCH_DATA); sendWsMsg(ctx, sessionRef, update); } }; @@ -260,7 +282,7 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { if (sessionMD == null) { log.warn("[{}] Session meta data not found. ", sessionId); SubscriptionUpdate update = new SubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, - "Session meta-data not found!"); + SESSION_META_DATA_NOT_FOUND); sendWsMsg(ctx, sessionRef, update); return; } @@ -294,7 +316,7 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { SubscriptionErrorCode.UNAUTHORIZED.getDefaultMsg()); } else { update = new SubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, - "Failed to fetch data!"); + FAILED_TO_FETCH_DATA); } sendWsMsg(ctx, sessionRef, update); } @@ -314,7 +336,7 @@ public class TelemetryWebsocketMsgHandler extends DefaultWebsocketMsgHandler { if (sessionMD == null) { log.warn("[{}] Session meta data not found. ", sessionId); SubscriptionUpdate update = new SubscriptionUpdate(cmd.getCmdId(), SubscriptionErrorCode.INTERNAL_ERROR, - "Session meta-data not found!"); + SESSION_META_DATA_NOT_FOUND); sendWsMsg(ctx, sessionRef, update); return false; } else { diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/time/TimePlugin.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/time/TimePlugin.java index ac168d085b..a8c257042a 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/time/TimePlugin.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/time/TimePlugin.java @@ -72,17 +72,17 @@ public class TimePlugin extends AbstractPlugin implemen @Override public void resume(PluginContext ctx) { - + //Do nothing } @Override public void suspend(PluginContext ctx) { - + //Do nothing } @Override public void stop(PluginContext ctx) { - + //Do nothing } @Override diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/processor/AlarmProcessor.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/processor/AlarmProcessor.java index 96b49ac391..9e5d5e9a6b 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/processor/AlarmProcessor.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/processor/AlarmProcessor.java @@ -15,14 +15,11 @@ */ package org.thingsboard.server.extensions.core.processor; -import java.util.Optional; - import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; import org.apache.velocity.Template; import org.apache.velocity.VelocityContext; -import org.apache.velocity.runtime.parser.ParseException; import org.springframework.util.StringUtils; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmSeverity; @@ -33,7 +30,10 @@ import org.thingsboard.server.common.msg.core.UpdateAttributesRequest; import org.thingsboard.server.common.msg.device.ToDeviceActorMsg; import org.thingsboard.server.common.msg.session.FromDeviceMsg; import org.thingsboard.server.extensions.api.component.Processor; -import org.thingsboard.server.extensions.api.rules.*; +import org.thingsboard.server.extensions.api.rules.RuleContext; +import org.thingsboard.server.extensions.api.rules.RuleException; +import org.thingsboard.server.extensions.api.rules.RuleProcessingMetaData; +import org.thingsboard.server.extensions.api.rules.RuleProcessor; import org.thingsboard.server.extensions.core.filter.NashornJsEvaluator; import org.thingsboard.server.extensions.core.utils.VelocityUtils; @@ -41,7 +41,7 @@ import javax.script.Bindings; import javax.script.ScriptException; import java.io.IOException; import java.util.List; -import java.util.concurrent.ExecutionException; +import java.util.Optional; /** * @author Andrew Shvayka @@ -129,38 +129,11 @@ public class AlarmProcessor implements RuleProcessor oldAlarmOpt = ctx.findLatestAlarm(alarm.getOriginator(), alarm.getType()); - if (oldAlarmOpt.isPresent() && !oldAlarmOpt.get().getStatus().isCleared()) { - try { - ctx.clearAlarm(oldAlarmOpt.get().getId(), oldAlarmOpt.get().getEndTs()).get(); - } catch (Exception e) { - throw new RuleException("Failed to clear old alarm", e); - } - } - } - existing = ctx.createOrUpdateAlarm(alarm); - if (existing.getStartTs() == alarm.getStartTs()) { - log.debug("[{}][{}] New Active Alarm detected", ctx.getRuleId(), existing.getId()); - md.put(IS_NEW_ALARM, Boolean.TRUE); - md.put(IS_NEW_OR_CLEARED_ALARM, Boolean.TRUE); - } else { - log.debug("[{}][{}] Existing Active Alarm detected", ctx.getRuleId(), existing.getId()); - md.put(IS_EXISTING_ALARM, Boolean.TRUE); - } + existing = processActiveAlarm(ctx, msg, md); } else { - String alarmType = VelocityUtils.merge(alarmTypeTemplate, context); - Optional alarm = ctx.findLatestAlarm(ctx.getDeviceMetaData().getDeviceId(), alarmType); - if (alarm.isPresent()) { - ctx.clearAlarm(alarm.get().getId(), System.currentTimeMillis()); - log.debug("[{}][{}] Existing Active Alarm cleared"); - md.put(IS_CLEARED_ALARM, Boolean.TRUE); - md.put(IS_NEW_OR_CLEARED_ALARM, Boolean.TRUE); - existing = alarm.get(); - } + existing = processInactiveAlarm(ctx, md, context); } if (existing != null) { @@ -181,6 +154,44 @@ public class AlarmProcessor implements RuleProcessor oldAlarmOpt = ctx.findLatestAlarm(alarm.getOriginator(), alarm.getType()); + if (oldAlarmOpt.isPresent() && !oldAlarmOpt.get().getStatus().isCleared()) { + try { + ctx.clearAlarm(oldAlarmOpt.get().getId(), oldAlarmOpt.get().getEndTs()).get(); + } catch (Exception e) { + throw new RuleException("Failed to clear old alarm", e); + } + } + } + Alarm existing = ctx.createOrUpdateAlarm(alarm); + if (existing.getStartTs() == alarm.getStartTs()) { + log.debug("[{}][{}] New Active Alarm detected", ctx.getRuleId(), existing.getId()); + md.put(IS_NEW_ALARM, Boolean.TRUE); + md.put(IS_NEW_OR_CLEARED_ALARM, Boolean.TRUE); + } else { + log.debug("[{}][{}] Existing Active Alarm detected", ctx.getRuleId(), existing.getId()); + md.put(IS_EXISTING_ALARM, Boolean.TRUE); + } + return existing; + } + + private Alarm processInactiveAlarm(RuleContext ctx, RuleProcessingMetaData md, VelocityContext context) throws RuleException { + Alarm existing = null; + String alarmType = VelocityUtils.merge(alarmTypeTemplate, context); + Optional alarm = ctx.findLatestAlarm(ctx.getDeviceMetaData().getDeviceId(), alarmType); + if (alarm.isPresent()) { + ctx.clearAlarm(alarm.get().getId(), System.currentTimeMillis()); + log.debug("[{}][{}] Existing Active Alarm cleared"); + md.put(IS_CLEARED_ALARM, Boolean.TRUE); + md.put(IS_NEW_OR_CLEARED_ALARM, Boolean.TRUE); + existing = alarm.get(); + } + return existing; + } + private Alarm buildAlarm(RuleContext ctx, FromDeviceMsg msg) throws RuleException { VelocityContext context = VelocityUtils.createContext(ctx.getDeviceMetaData(), msg); String alarmType = VelocityUtils.merge(alarmTypeTemplate, context); @@ -215,6 +226,9 @@ public class AlarmProcessor implements RuleProcessor entries : telemetryMsg.getData().values()) { bindings = NashornJsEvaluator.toBindings(bindings, entries); } + break; + default: + break; } } return bindings; diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/utils/VelocityUtils.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/utils/VelocityUtils.java index fbb7612c68..fa7ad1ab1d 100644 --- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/utils/VelocityUtils.java +++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/utils/VelocityUtils.java @@ -78,6 +78,8 @@ public class VelocityUtils { case POST_TELEMETRY_REQUEST: pushTsEntries(context, (TelemetryUploadRequest) payload); break; + default: + break; } context.put("deviceId", deviceMetaData.getDeviceId().getId().toString()); diff --git a/extensions/extension-kafka/src/main/java/org/thingsboard/server/extensions/kafka/action/KafkaPluginAction.java b/extensions/extension-kafka/src/main/java/org/thingsboard/server/extensions/kafka/action/KafkaPluginAction.java index f0ced13ad8..1c3599f115 100644 --- a/extensions/extension-kafka/src/main/java/org/thingsboard/server/extensions/kafka/action/KafkaPluginAction.java +++ b/extensions/extension-kafka/src/main/java/org/thingsboard/server/extensions/kafka/action/KafkaPluginAction.java @@ -30,7 +30,7 @@ import java.util.Optional; public class KafkaPluginAction extends AbstractTemplatePluginAction { @Override - protected Optional> buildRuleToPluginMsg(RuleContext ctx, ToDeviceActorMsg msg, FromDeviceRequestMsg payload) { + protected Optional buildRuleToPluginMsg(RuleContext ctx, ToDeviceActorMsg msg, FromDeviceRequestMsg payload) { KafkaActionPayload.KafkaActionPayloadBuilder builder = KafkaActionPayload.builder(); builder.msgType(payload.getMsgType()); builder.requestId(payload.getRequestId()); diff --git a/extensions/extension-mqtt/src/main/java/org/thingsboard/server/extensions/mqtt/action/MqttPluginAction.java b/extensions/extension-mqtt/src/main/java/org/thingsboard/server/extensions/mqtt/action/MqttPluginAction.java index 5d3ae487cb..9077f1238f 100644 --- a/extensions/extension-mqtt/src/main/java/org/thingsboard/server/extensions/mqtt/action/MqttPluginAction.java +++ b/extensions/extension-mqtt/src/main/java/org/thingsboard/server/extensions/mqtt/action/MqttPluginAction.java @@ -28,7 +28,7 @@ import java.util.Optional; public class MqttPluginAction extends AbstractTemplatePluginAction { @Override - protected Optional> buildRuleToPluginMsg(RuleContext ctx, ToDeviceActorMsg msg, FromDeviceRequestMsg payload) { + protected Optional buildRuleToPluginMsg(RuleContext ctx, ToDeviceActorMsg msg, FromDeviceRequestMsg payload) { MqttActionPayload.MqttActionPayloadBuilder builder = MqttActionPayload.builder(); builder.sync(configuration.isSync()); builder.msgType(payload.getMsgType()); diff --git a/extensions/extension-mqtt/src/main/java/org/thingsboard/server/extensions/mqtt/plugin/MqttPlugin.java b/extensions/extension-mqtt/src/main/java/org/thingsboard/server/extensions/mqtt/plugin/MqttPlugin.java index 3ff4dd0a59..206ef5f0d6 100644 --- a/extensions/extension-mqtt/src/main/java/org/thingsboard/server/extensions/mqtt/plugin/MqttPlugin.java +++ b/extensions/extension-mqtt/src/main/java/org/thingsboard/server/extensions/mqtt/plugin/MqttPlugin.java @@ -78,15 +78,17 @@ public class MqttPlugin extends AbstractPlugin { @Override public void onFailure(IMqttToken iMqttToken, Throwable e) { + //Do nothing } }).waitForCompletion(); } catch (MqttException e) { log.warn("Failed to connect to requested mqtt host [{}]!", mqttClient.getServerURI(), e); if (!mqttClient.isConnected()) { try { - Thread.sleep(retryInterval); + connectLock.wait(retryInterval); } catch (InterruptedException e1) { log.trace("Failed to wait for retry interval!", e); + Thread.currentThread().interrupt(); } } } diff --git a/extensions/extension-rabbitmq/src/main/java/org/thingsboard/server/extensions/rabbitmq/action/RabbitMqPluginAction.java b/extensions/extension-rabbitmq/src/main/java/org/thingsboard/server/extensions/rabbitmq/action/RabbitMqPluginAction.java index 2333a1df47..c194c67ad6 100644 --- a/extensions/extension-rabbitmq/src/main/java/org/thingsboard/server/extensions/rabbitmq/action/RabbitMqPluginAction.java +++ b/extensions/extension-rabbitmq/src/main/java/org/thingsboard/server/extensions/rabbitmq/action/RabbitMqPluginAction.java @@ -32,7 +32,7 @@ import java.util.Optional; public class RabbitMqPluginAction extends AbstractTemplatePluginAction { @Override - protected Optional> buildRuleToPluginMsg(RuleContext ctx, ToDeviceActorMsg msg, FromDeviceRequestMsg payload) { + protected Optional buildRuleToPluginMsg(RuleContext ctx, ToDeviceActorMsg msg, FromDeviceRequestMsg payload) { RabbitMqActionPayload.RabbitMqActionPayloadBuilder builder = RabbitMqActionPayload.builder(); builder.sync(configuration.isSync()); builder.exchange(configuration.getExchange()); diff --git a/extensions/extension-rest-api-call/src/main/java/org/thingsboard/server/extensions/rest/action/RestApiCallPluginAction.java b/extensions/extension-rest-api-call/src/main/java/org/thingsboard/server/extensions/rest/action/RestApiCallPluginAction.java index 71c87fd7f9..f537bad8f3 100644 --- a/extensions/extension-rest-api-call/src/main/java/org/thingsboard/server/extensions/rest/action/RestApiCallPluginAction.java +++ b/extensions/extension-rest-api-call/src/main/java/org/thingsboard/server/extensions/rest/action/RestApiCallPluginAction.java @@ -33,7 +33,7 @@ import java.util.Optional; public class RestApiCallPluginAction extends AbstractTemplatePluginAction { @Override - protected Optional> buildRuleToPluginMsg(RuleContext ctx, ToDeviceActorMsg msg, FromDeviceRequestMsg payload) { + protected Optional buildRuleToPluginMsg(RuleContext ctx, ToDeviceActorMsg msg, FromDeviceRequestMsg payload) { RestApiCallActionPayload.RestApiCallActionPayloadBuilder builder = RestApiCallActionPayload.builder(); builder.msgType(payload.getMsgType()); builder.requestId(payload.getRequestId()); diff --git a/pom.xml b/pom.xml index a3c15d81f1..2f92298e6a 100755 --- a/pom.xml +++ b/pom.xml @@ -77,6 +77,7 @@ 2.5.3 1.2.1 9.4.1211 + org/thingsboard/server/gen/**/*, org/thingsboard/server/extensions/core/plugin/telemetry/gen/**/* diff --git a/tools/src/main/java/org/thingsboard/client/tools/MqttSslClient.java b/tools/src/main/java/org/thingsboard/client/tools/MqttSslClient.java index 9b0fd2b812..7cba5f1468 100644 --- a/tools/src/main/java/org/thingsboard/client/tools/MqttSslClient.java +++ b/tools/src/main/java/org/thingsboard/client/tools/MqttSslClient.java @@ -21,50 +21,48 @@ package org.thingsboard.client.tools; */ import com.google.common.io.Resources; -import org.eclipse.paho.client.mqttv3.*; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.paho.client.mqttv3.MqttAsyncClient; +import org.eclipse.paho.client.mqttv3.MqttConnectOptions; +import org.eclipse.paho.client.mqttv3.MqttMessage; import javax.net.ssl.*; import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.URISyntaxException; import java.net.URL; -import java.security.*; -import java.security.cert.CertificateException; +import java.security.KeyStore; +@Slf4j public class MqttSslClient { private static final String MQTT_URL = "ssl://localhost:1883"; - private static final String clientId = "MQTT_SSL_JAVA_CLIENT"; - private static final String accessToken = "C1_TEST_TOKEN"; - private static final String keyStoreFile = "mqttclient.jks"; + private static final String CLIENT_ID = "MQTT_SSL_JAVA_CLIENT"; + private static final String KEY_STORE_FILE = "mqttclient.jks"; private static final String JKS="JKS"; private static final String TLS="TLS"; - private static final String CLIENT_KEYSTORE_PASSWORD = "client_ks_password"; - private static final String CLIENT_KEY_PASSWORD = "client_key_password"; public static void main(String[] args) { try { - - URL ksUrl = Resources.getResource(keyStoreFile); + URL ksUrl = Resources.getResource(KEY_STORE_FILE); File ksFile = new File(ksUrl.toURI()); - URL tsUrl = Resources.getResource(keyStoreFile); + URL tsUrl = Resources.getResource(KEY_STORE_FILE); File tsFile = new File(tsUrl.toURI()); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); KeyStore trustStore = KeyStore.getInstance(JKS); - trustStore.load(new FileInputStream(tsFile), CLIENT_KEYSTORE_PASSWORD.toCharArray()); + char[] ksPwd = new char[]{0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x5F, 0x6B, 0x73, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64}; + trustStore.load(new FileInputStream(tsFile), ksPwd); tmf.init(trustStore); KeyStore ks = KeyStore.getInstance(JKS); - ks.load(new FileInputStream(ksFile), CLIENT_KEYSTORE_PASSWORD.toCharArray()); + ks.load(new FileInputStream(ksFile), ksPwd); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - kmf.init(ks, CLIENT_KEY_PASSWORD.toCharArray()); + char[] clientPwd = new char[]{0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x5F, 0x6B, 0x65, 0x79, 0x5F, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6F, 0x72, 0x64}; + kmf.init(ks, clientPwd); KeyManager[] km = kmf.getKeyManagers(); TrustManager[] tm = tmf.getTrustManagers(); @@ -73,17 +71,17 @@ public class MqttSslClient { MqttConnectOptions options = new MqttConnectOptions(); options.setSocketFactory(sslContext.getSocketFactory()); - MqttAsyncClient client = new MqttAsyncClient(MQTT_URL, clientId); + MqttAsyncClient client = new MqttAsyncClient(MQTT_URL, CLIENT_ID); client.connect(options); Thread.sleep(3000); MqttMessage message = new MqttMessage(); message.setPayload("{\"key1\":\"value1\", \"key2\":true, \"key3\": 3.0, \"key4\": 4}".getBytes()); client.publish("v1/devices/me/telemetry", message); client.disconnect(); - System.out.println("Disconnected"); + log.info("Disconnected"); System.exit(0); } catch (Exception e) { - e.printStackTrace(); + log.error("Unexpected exception occurred in MqttSslClient", e); } } } \ No newline at end of file diff --git a/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java b/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java index 1089e3d3ab..834a911e77 100644 --- a/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java +++ b/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java @@ -78,19 +78,7 @@ public class CoapTransportResource extends CoapResource { log.trace("Can't fetch/subscribe to timeseries updates"); exchange.respond(ResponseCode.BAD_REQUEST); } else if (exchange.getRequestOptions().hasObserve()) { - boolean unsubscribe = exchange.getRequestOptions().getObserve() == 1; - MsgType msgType; - if (featureType.get() == FeatureType.RPC) { - msgType = unsubscribe ? MsgType.UNSUBSCRIBE_RPC_COMMANDS_REQUEST : MsgType.SUBSCRIBE_RPC_COMMANDS_REQUEST; - } else { - msgType = unsubscribe ? MsgType.UNSUBSCRIBE_ATTRIBUTES_REQUEST : MsgType.SUBSCRIBE_ATTRIBUTES_REQUEST; - } - Optional sessionId = processRequest(exchange, msgType); - if (sessionId.isPresent()) { - if (exchange.getRequestOptions().getObserve() == 1) { - exchange.respond(ResponseCode.VALID); - } - } + processExchangeGetRequest(exchange, featureType.get()); } else if (featureType.get() == FeatureType.ATTRIBUTES) { processRequest(exchange, MsgType.GET_ATTRIBUTES_REQUEST); } else { @@ -99,6 +87,22 @@ public class CoapTransportResource extends CoapResource { } } + private void processExchangeGetRequest(CoapExchange exchange, FeatureType featureType) { + boolean unsubscribe = exchange.getRequestOptions().getObserve() == 1; + MsgType msgType; + if (featureType == FeatureType.RPC) { + msgType = unsubscribe ? MsgType.UNSUBSCRIBE_RPC_COMMANDS_REQUEST : MsgType.SUBSCRIBE_RPC_COMMANDS_REQUEST; + } else { + msgType = unsubscribe ? MsgType.UNSUBSCRIBE_ATTRIBUTES_REQUEST : MsgType.SUBSCRIBE_ATTRIBUTES_REQUEST; + } + Optional sessionId = processRequest(exchange, msgType); + if (sessionId.isPresent()) { + if (exchange.getRequestOptions().getObserve() == 1) { + exchange.respond(ResponseCode.VALID); + } + } + } + @Override public void handlePOST(CoapExchange exchange) { Optional featureType = getFeatureType(exchange.advanced().getRequest()); @@ -159,6 +163,9 @@ public class CoapTransportResource extends CoapResource { case SUBSCRIBE_RPC_COMMANDS_REQUEST: ExchangeObserver systemObserver = (ExchangeObserver) observerField.get(advanced); advanced.setObserver(new CoapExchangeObserverProxy(systemObserver, ctx)); + ctx.setSessionType(SessionType.ASYNC); + msg = adaptor.convertToActorMsg(ctx, type, request); + break; case UNSUBSCRIBE_ATTRIBUTES_REQUEST: case UNSUBSCRIBE_RPC_COMMANDS_REQUEST: ctx.setSessionType(SessionType.ASYNC); diff --git a/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java b/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java index 862e4e7c0c..6e5805b9c1 100644 --- a/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java +++ b/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java @@ -167,7 +167,7 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { private FromDeviceMsg convertToGetAttributesRequest(SessionContext ctx, Request inbound) throws AdaptorException { List queryElements = inbound.getOptions().getUriQuery(); - if (queryElements != null || queryElements.size() > 0) { + if (queryElements != null && queryElements.size() > 0) { Set clientKeys = toKeys(ctx, queryElements, "clientKeys"); Set sharedKeys = toKeys(ctx, queryElements, "sharedKeys"); return new BasicGetAttributesRequest(0, clientKeys, sharedKeys); @@ -184,7 +184,7 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { keys = queryItem[1]; } } - if (!StringUtils.isEmpty(keys)) { + if (keys != null && !StringUtils.isEmpty(keys)) { return new HashSet<>(Arrays.asList(keys.split(","))); } else { return null; @@ -202,14 +202,14 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { private Response convertStatusCodeResponse(StatusCodeResponse msg) { if (msg.isSuccess()) { - Integer code = msg.getData().get(); - if (code == 200) { + Optional code = msg.getData(); + if (code.isPresent() && code.get() == 200) { return new Response(ResponseCode.VALID); } else { return new Response(ResponseCode.CREATED); } } else { - return convertError(msg.getError().get()); + return convertError(msg.getError()); } } @@ -229,30 +229,34 @@ public class JsonCoapAdaptor implements CoapTransportAdaptor { response.setPayload(result.toString()); return response; } else { - return convertError(new RuntimeException("Server RPC response is empty!")); + return convertError(Optional.of(new RuntimeException("Server RPC response is empty!"))); } } private Response convertGetAttributesResponse(GetAttributesResponse msg) { if (msg.isSuccess()) { - AttributesKVMsg payload = msg.getData().get(); - if (payload.getClientAttributes().isEmpty() && payload.getSharedAttributes().isEmpty()) { + Optional payload = msg.getData(); + if (!payload.isPresent() || (payload.get().getClientAttributes().isEmpty() && payload.get().getSharedAttributes().isEmpty())) { return new Response(ResponseCode.NOT_FOUND); } else { Response response = new Response(ResponseCode.CONTENT); - JsonObject result = JsonConverter.toJson(payload, false); + JsonObject result = JsonConverter.toJson(payload.get(), false); response.setPayload(result.toString()); return response; } } else { - return convertError(msg.getError().get()); + return convertError(msg.getError()); } } - private Response convertError(Exception exception) { - log.warn("Converting exception: {}", exception.getMessage(), exception); - if (exception instanceof ProcessingTimeoutException) { - return new Response(ResponseCode.SERVICE_UNAVAILABLE); + private Response convertError(Optional exception) { + if (exception.isPresent()) { + log.warn("Converting exception: {}", exception.get().getMessage(), exception.get()); + if (exception.get() instanceof ProcessingTimeoutException) { + return new Response(ResponseCode.SERVICE_UNAVAILABLE); + } else { + return new Response(ResponseCode.INTERNAL_SERVER_ERROR); + } } else { return new Response(ResponseCode.INTERNAL_SERVER_ERROR); } diff --git a/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DeviceEmulator.java b/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DeviceEmulator.java index f46e35fff4..13506f4dcf 100644 --- a/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DeviceEmulator.java +++ b/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DeviceEmulator.java @@ -80,7 +80,7 @@ public class DeviceEmulator { Thread.sleep(1000); } } catch (Exception e) { - e.printStackTrace(); + log.error("Error occurred while sending COAP requests", e); } } @@ -113,18 +113,18 @@ public class DeviceEmulator { @Override public void onError() { - + //Do nothing } }, mapper.writeValueAsString(response), MediaTypeRegistry.APPLICATION_JSON); } catch (IOException e) { - e.printStackTrace(); + log.error("Error occurred while processing COAP response", e); } } @Override public void onError() { - + //Do nothing } }); } diff --git a/transport/http/src/main/java/org/thingsboard/server/transport/http/session/HttpSessionCtx.java b/transport/http/src/main/java/org/thingsboard/server/transport/http/session/HttpSessionCtx.java index 4bee59533d..a3fc4d370d 100644 --- a/transport/http/src/main/java/org/thingsboard/server/transport/http/session/HttpSessionCtx.java +++ b/transport/http/src/main/java/org/thingsboard/server/transport/http/session/HttpSessionCtx.java @@ -29,6 +29,7 @@ import org.thingsboard.server.common.transport.adaptor.JsonConverter; import org.thingsboard.server.common.transport.auth.DeviceAuthService; import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext; +import java.util.Optional; import java.util.function.Consumer; /** @@ -75,6 +76,8 @@ public class HttpSessionCtx extends DeviceAwareSessionContext { case RULE_ENGINE_ERROR: reply((RuleEngineErrorMsg) msg); return; + default: + break; } } @@ -94,10 +97,14 @@ public class HttpSessionCtx extends DeviceAwareSessionContext { } private void reply(ResponseMsg msg, Consumer f) { - if (!msg.getError().isPresent()) { - f.accept(msg.getData().get()); + Optional msgError = msg.getError(); + if (!msgError.isPresent()) { + Optional msgData = msg.getData(); + if (msgData.isPresent()) { + f.accept(msgData.get()); + } } else { - Exception e = msg.getError().get(); + Exception e = msgError.get(); responseWriter.setResult(new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR)); } } @@ -137,7 +144,7 @@ public class HttpSessionCtx extends DeviceAwareSessionContext { @Override public void onMsg(SessionCtrlMsg msg) throws SessionException { - + //Do nothing } @Override diff --git a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java index fe86f81049..f1f0266fa6 100644 --- a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java +++ b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java @@ -32,6 +32,7 @@ import javax.net.ssl.*; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.io.InputStream; import java.net.URL; import java.security.KeyStore; import java.security.cert.CertificateException; @@ -69,12 +70,15 @@ public class MqttSslHandlerProvider { TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); KeyStore trustStore = KeyStore.getInstance(keyStoreType); - trustStore.load(new FileInputStream(tsFile), keyStorePassword.toCharArray()); + try (InputStream tsFileInputStream = new FileInputStream(tsFile)) { + trustStore.load(tsFileInputStream, keyStorePassword.toCharArray()); + } tmFactory.init(trustStore); KeyStore ks = KeyStore.getInstance(keyStoreType); - - ks.load(new FileInputStream(ksFile), keyStorePassword.toCharArray()); + try (InputStream ksFileInputStream = new FileInputStream(ksFile)) { + ks.load(ksFileInputStream, keyStorePassword.toCharArray()); + } KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); kmf.init(ks, keyPassword.toCharArray()); diff --git a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index 3fd1696988..2e6abfde96 100644 --- a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -127,6 +127,8 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement processDisconnect(ctx); } break; + default: + break; } } } @@ -142,29 +144,33 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement if (topicName.startsWith(BASE_GATEWAY_API_TOPIC)) { if (gatewaySessionCtx != null) { gatewaySessionCtx.setChannel(ctx); - try { - if (topicName.equals(GATEWAY_TELEMETRY_TOPIC)) { - gatewaySessionCtx.onDeviceTelemetry(mqttMsg); - } else if (topicName.equals(GATEWAY_ATTRIBUTES_TOPIC)) { - gatewaySessionCtx.onDeviceAttributes(mqttMsg); - } else if (topicName.equals(GATEWAY_ATTRIBUTES_REQUEST_TOPIC)) { - gatewaySessionCtx.onDeviceAttributesRequest(mqttMsg); - } else if (topicName.equals(GATEWAY_RPC_TOPIC)) { - gatewaySessionCtx.onDeviceRpcResponse(mqttMsg); - } else if (topicName.equals(GATEWAY_CONNECT_TOPIC)) { - gatewaySessionCtx.onDeviceConnect(mqttMsg); - } else if (topicName.equals(GATEWAY_DISCONNECT_TOPIC)) { - gatewaySessionCtx.onDeviceDisconnect(mqttMsg); - } - } catch (RuntimeException | AdaptorException e) { - log.warn("[{}] Failed to process publish msg [{}][{}]", sessionId, topicName, msgId, e); - } + handleMqttPublishMsg(topicName, msgId, mqttMsg); } } else { processDevicePublish(ctx, mqttMsg, topicName, msgId); } } + private void handleMqttPublishMsg(String topicName, int msgId, MqttPublishMessage mqttMsg) { + try { + if (topicName.equals(GATEWAY_TELEMETRY_TOPIC)) { + gatewaySessionCtx.onDeviceTelemetry(mqttMsg); + } else if (topicName.equals(GATEWAY_ATTRIBUTES_TOPIC)) { + gatewaySessionCtx.onDeviceAttributes(mqttMsg); + } else if (topicName.equals(GATEWAY_ATTRIBUTES_REQUEST_TOPIC)) { + gatewaySessionCtx.onDeviceAttributesRequest(mqttMsg); + } else if (topicName.equals(GATEWAY_RPC_TOPIC)) { + gatewaySessionCtx.onDeviceRpcResponse(mqttMsg); + } else if (topicName.equals(GATEWAY_CONNECT_TOPIC)) { + gatewaySessionCtx.onDeviceConnect(mqttMsg); + } else if (topicName.equals(GATEWAY_DISCONNECT_TOPIC)) { + gatewaySessionCtx.onDeviceDisconnect(mqttMsg); + } + } catch (RuntimeException | AdaptorException e) { + log.warn("[{}] Failed to process publish msg [{}][{}]", sessionId, topicName, msgId, e); + } + } + private void processDevicePublish(ChannelHandlerContext ctx, MqttPublishMessage mqttMsg, String topicName, int msgId) { AdaptorToSessionActorMsg msg = null; try { diff --git a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java index 36769d7536..a66147583f 100644 --- a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java +++ b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/adaptors/JsonMqttAdaptor.java @@ -98,26 +98,12 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor { case STATUS_CODE_RESPONSE: case GET_ATTRIBUTES_RESPONSE: ResponseMsg responseMsg = (ResponseMsg) msg; + Optional responseError = responseMsg.getError(); if (responseMsg.isSuccess()) { - MsgType requestMsgType = responseMsg.getRequestMsgType(); - Integer requestId = responseMsg.getRequestId(); - if (requestId >= 0) { - if (requestMsgType == MsgType.POST_ATTRIBUTES_REQUEST || requestMsgType == MsgType.POST_TELEMETRY_REQUEST) { - result = MqttTransportHandler.createMqttPubAckMsg(requestId); - } else if (requestMsgType == MsgType.GET_ATTRIBUTES_REQUEST) { - GetAttributesResponse response = (GetAttributesResponse) msg; - if (response.isSuccess()) { - result = createMqttPublishMsg(ctx, - MqttTopics.DEVICE_ATTRIBUTES_RESPONSE_TOPIC_PREFIX + requestId, - response.getData().get(), true); - } else { - throw new AdaptorException(response.getError().get()); - } - } - } + result = convertResponseMsg(ctx, msg, responseMsg, responseError); } else { - if (responseMsg.getError().isPresent()) { - throw new AdaptorException(responseMsg.getError().get()); + if (responseError.isPresent()) { + throw new AdaptorException(responseError.get()); } } break; @@ -139,10 +125,37 @@ public class JsonMqttAdaptor implements MqttTransportAdaptor { RuleEngineErrorMsg errorMsg = (RuleEngineErrorMsg) msg; result = createMqttPublishMsg(ctx, "errors", JsonConverter.toErrorJson(errorMsg.getErrorMsg())); break; + default: + break; } return Optional.ofNullable(result); } + private MqttMessage convertResponseMsg(DeviceSessionCtx ctx, ToDeviceMsg msg, + ResponseMsg responseMsg, Optional responseError) throws AdaptorException { + MqttMessage result = null; + MsgType requestMsgType = responseMsg.getRequestMsgType(); + Integer requestId = responseMsg.getRequestId(); + if (requestId >= 0) { + if (requestMsgType == MsgType.POST_ATTRIBUTES_REQUEST || requestMsgType == MsgType.POST_TELEMETRY_REQUEST) { + result = MqttTransportHandler.createMqttPubAckMsg(requestId); + } else if (requestMsgType == MsgType.GET_ATTRIBUTES_REQUEST) { + GetAttributesResponse response = (GetAttributesResponse) msg; + Optional responseData = response.getData(); + if (response.isSuccess() && responseData.isPresent()) { + result = createMqttPublishMsg(ctx, + MqttTopics.DEVICE_ATTRIBUTES_RESPONSE_TOPIC_PREFIX + requestId, + responseData.get(), true); + } else { + if (responseError.isPresent()) { + throw new AdaptorException(responseError.get()); + } + } + } + } + return result; + } + private MqttPublishMessage createMqttPublishMsg(DeviceSessionCtx ctx, String topic, AttributesKVMsg msg, boolean asMap) { return createMqttPublishMsg(ctx, topic, JsonConverter.toJson(msg, asMap)); } diff --git a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java index 163b0cdfbc..7b527dff83 100644 --- a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java +++ b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java @@ -46,6 +46,7 @@ public class GatewayDeviceSessionCtx extends DeviceAwareSessionContext { private static final Gson GSON = new Gson(); private static final Charset UTF8 = Charset.forName("UTF-8"); private static final ByteBufAllocator ALLOCATOR = new UnpooledByteBufAllocator(false); + public static final String DEVICE_PROPERTY = "device"; private GatewaySessionCtx parent; private final MqttSessionId sessionId; @@ -101,13 +102,15 @@ public class GatewayDeviceSessionCtx extends DeviceAwareSessionContext { case TO_DEVICE_RPC_REQUEST: ToDeviceRpcRequestMsg rpcRequest = (ToDeviceRpcRequestMsg) msg; return Optional.of(createMqttPublishMsg(MqttTopics.GATEWAY_RPC_TOPIC, rpcRequest)); + default: + break; } return Optional.empty(); } @Override public void onMsg(SessionCtrlMsg msg) throws SessionException { - + //Do nothing } @Override @@ -127,9 +130,10 @@ public class GatewayDeviceSessionCtx extends DeviceAwareSessionContext { private MqttMessage createMqttPublishMsg(String topic, GetAttributesResponse response) { JsonObject result = new JsonObject(); result.addProperty("id", response.getRequestId()); - result.addProperty("device", device.getName()); - if (response.getData().isPresent()) { - AttributesKVMsg msg = response.getData().get(); + result.addProperty(DEVICE_PROPERTY, device.getName()); + Optional responseData = response.getData(); + if (responseData.isPresent()) { + AttributesKVMsg msg = responseData.get(); if (msg.getClientAttributes() != null) { msg.getClientAttributes().forEach(v -> addValueToJson(result, "value", v)); } @@ -143,30 +147,42 @@ public class GatewayDeviceSessionCtx extends DeviceAwareSessionContext { private void addValueToJson(JsonObject json, String name, KvEntry entry) { switch (entry.getDataType()) { case BOOLEAN: - json.addProperty(name, entry.getBooleanValue().get()); + Optional booleanValue = entry.getBooleanValue(); + if (booleanValue.isPresent()) { + json.addProperty(name, booleanValue.get()); + } break; case STRING: - json.addProperty(name, entry.getStrValue().get()); + Optional stringValue = entry.getStrValue(); + if (stringValue.isPresent()) { + json.addProperty(name, stringValue.get()); + } break; case DOUBLE: - json.addProperty(name, entry.getDoubleValue().get()); + Optional doubleValue = entry.getDoubleValue(); + if (doubleValue.isPresent()) { + json.addProperty(name, doubleValue.get()); + } break; case LONG: - json.addProperty(name, entry.getLongValue().get()); + Optional longValue = entry.getLongValue(); + if (longValue.isPresent()) { + json.addProperty(name, longValue.get()); + } break; } } private MqttMessage createMqttPublishMsg(String topic, AttributesKVMsg data) { JsonObject result = new JsonObject(); - result.addProperty("device", device.getName()); + result.addProperty(DEVICE_PROPERTY, device.getName()); result.add("data", JsonConverter.toJson(data, false)); return createMqttPublishMsg(topic, result); } private MqttMessage createMqttPublishMsg(String topic, ToDeviceRpcRequestMsg data) { JsonObject result = new JsonObject(); - result.addProperty("device", device.getName()); + result.addProperty(DEVICE_PROPERTY, device.getName()); result.add("data", JsonConverter.toJson(data, true)); return createMqttPublishMsg(topic, result); } diff --git a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionCtx.java b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionCtx.java index 2dd1c5df21..00d1f0c6d7 100644 --- a/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionCtx.java +++ b/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionCtx.java @@ -56,6 +56,8 @@ import static org.thingsboard.server.transport.mqtt.adaptors.JsonMqttAdaptor.val public class GatewaySessionCtx { private static final String DEFAULT_DEVICE_TYPE = "default"; + public static final String CAN_T_PARSE_VALUE = "Can't parse value: "; + public static final String DEVICE_PROPERTY = "device"; private final Device gateway; private final SessionId gatewaySessionId; private final SessionMsgProcessor processor; @@ -92,7 +94,7 @@ public class GatewaySessionCtx { newDevice.setName(deviceName); newDevice.setType(deviceType); newDevice = deviceService.saveDevice(newDevice); - relationService.saveRelation(new EntityRelation(gateway.getId(), newDevice.getId(), "Created")); + relationService.saveRelationAsync(new EntityRelation(gateway.getId(), newDevice.getId(), "Created")); return newDevice; }); GatewayDeviceSessionCtx ctx = new GatewayDeviceSessionCtx(this, device); @@ -130,7 +132,7 @@ public class GatewaySessionCtx { for (Map.Entry deviceEntry : jsonObj.entrySet()) { String deviceName = checkDeviceConnected(deviceEntry.getKey()); if (!deviceEntry.getValue().isJsonArray()) { - throw new JsonSyntaxException("Can't parse value: " + json); + throw new JsonSyntaxException(CAN_T_PARSE_VALUE + json); } BasicTelemetryUploadRequest request = new BasicTelemetryUploadRequest(requestId); JsonArray deviceData = deviceEntry.getValue().getAsJsonArray(); @@ -142,7 +144,7 @@ public class GatewaySessionCtx { new BasicAdaptorToSessionActorMsg(deviceSessionCtx, request))); } } else { - throw new JsonSyntaxException("Can't parse value: " + json); + throw new JsonSyntaxException(CAN_T_PARSE_VALUE + json); } } @@ -150,14 +152,14 @@ public class GatewaySessionCtx { JsonElement json = validateJsonPayload(gatewaySessionId, mqttMsg.payload()); if (json.isJsonObject()) { JsonObject jsonObj = json.getAsJsonObject(); - String deviceName = checkDeviceConnected(jsonObj.get("device").getAsString()); + String deviceName = checkDeviceConnected(jsonObj.get(DEVICE_PROPERTY).getAsString()); Integer requestId = jsonObj.get("id").getAsInt(); String data = jsonObj.get("data").toString(); GatewayDeviceSessionCtx deviceSessionCtx = devices.get(deviceName); processor.process(new BasicToDeviceActorSessionMsg(deviceSessionCtx.getDevice(), new BasicAdaptorToSessionActorMsg(deviceSessionCtx, new ToDeviceRpcResponseMsg(requestId, data)))); } else { - throw new JsonSyntaxException("Can't parse value: " + json); + throw new JsonSyntaxException(CAN_T_PARSE_VALUE + json); } } @@ -169,7 +171,7 @@ public class GatewaySessionCtx { for (Map.Entry deviceEntry : jsonObj.entrySet()) { String deviceName = checkDeviceConnected(deviceEntry.getKey()); if (!deviceEntry.getValue().isJsonObject()) { - throw new JsonSyntaxException("Can't parse value: " + json); + throw new JsonSyntaxException(CAN_T_PARSE_VALUE + json); } long ts = System.currentTimeMillis(); BasicUpdateAttributesRequest request = new BasicUpdateAttributesRequest(requestId); @@ -180,7 +182,7 @@ public class GatewaySessionCtx { new BasicAdaptorToSessionActorMsg(deviceSessionCtx, request))); } } else { - throw new JsonSyntaxException("Can't parse value: " + json); + throw new JsonSyntaxException(CAN_T_PARSE_VALUE + json); } } @@ -189,7 +191,7 @@ public class GatewaySessionCtx { if (json.isJsonObject()) { JsonObject jsonObj = json.getAsJsonObject(); int requestId = jsonObj.get("id").getAsInt(); - String deviceName = jsonObj.get("device").getAsString(); + String deviceName = jsonObj.get(DEVICE_PROPERTY).getAsString(); boolean clientScope = jsonObj.get("client").getAsBoolean(); String key = jsonObj.get("key").getAsString(); @@ -203,7 +205,7 @@ public class GatewaySessionCtx { processor.process(new BasicToDeviceActorSessionMsg(deviceSessionCtx.getDevice(), new BasicAdaptorToSessionActorMsg(deviceSessionCtx, request))); } else { - throw new JsonSyntaxException("Can't parse value: " + json); + throw new JsonSyntaxException(CAN_T_PARSE_VALUE + json); } } @@ -224,7 +226,7 @@ public class GatewaySessionCtx { } private String getDeviceName(JsonElement json) throws AdaptorException { - return json.getAsJsonObject().get("device").getAsString(); + return json.getAsJsonObject().get(DEVICE_PROPERTY).getAsString(); } private String getDeviceType(JsonElement json) throws AdaptorException { diff --git a/ui/src/app/api/entity.service.js b/ui/src/app/api/entity.service.js index fc09a4016c..c8a59cfc77 100644 --- a/ui/src/app/api/entity.service.js +++ b/ui/src/app/api/entity.service.js @@ -824,17 +824,27 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device var subscriptionInfo = validateSubscriptionInfo(subscriptionsInfo[index]); if (subscriptionInfo.type === types.datasourceType.entity) { if (subscriptionInfo.entityId) { - getEntity(subscriptionInfo.entityType, subscriptionInfo.entityId, {ignoreLoading: true}).then( - function success(entity) { - createDatasourceFromSubscription(subscriptionInfo, datasources, entity); - index++; - processSubscriptionsInfo(index, subscriptionsInfo, datasources, deferred); - }, - function fail() { - index++; - processSubscriptionsInfo(index, subscriptionsInfo, datasources, deferred); - } - ); + if (subscriptionInfo.entityName) { + var entity = { + id: {id: subscriptionInfo.entityId, entityType: subscriptionInfo.entityType}, + name: subscriptionInfo.entityName + }; + createDatasourceFromSubscription(subscriptionInfo, datasources, entity); + index++; + processSubscriptionsInfo(index, subscriptionsInfo, datasources, deferred); + } else { + getEntity(subscriptionInfo.entityType, subscriptionInfo.entityId, {ignoreLoading: true}).then( + function success(entity) { + createDatasourceFromSubscription(subscriptionInfo, datasources, entity); + index++; + processSubscriptionsInfo(index, subscriptionsInfo, datasources, deferred); + }, + function fail() { + index++; + processSubscriptionsInfo(index, subscriptionsInfo, datasources, deferred); + } + ); + } } else if (subscriptionInfo.entityName || subscriptionInfo.entityNamePrefix || subscriptionInfo.entityIds) { var promise; diff --git a/ui/src/app/components/contact.tpl.html b/ui/src/app/components/contact.tpl.html index 2c52fd31d9..7b360f7631 100644 --- a/ui/src/app/components/contact.tpl.html +++ b/ui/src/app/components/contact.tpl.html @@ -54,6 +54,6 @@ - - + + \ No newline at end of file diff --git a/ui/src/app/components/dashboard.directive.js b/ui/src/app/components/dashboard.directive.js index 417ddb1656..b4912eacc9 100644 --- a/ui/src/app/components/dashboard.directive.js +++ b/ui/src/app/components/dashboard.directive.js @@ -234,54 +234,68 @@ function DashboardController($scope, $rootScope, $element, $timeout, $mdMedia, $ removeResizeListener(gridsterParent[0], onGirdsterParentResize); // eslint-disable-line no-undef }); + watchWidgets(); + function onGirdsterParentResize() { if (gridsterParent.height() && autofillHeight()) { updateMobileOpts(); } } - $scope.$watchCollection('vm.widgets', function () { - sortWidgets(); - var ids = []; - for (var i=0;i { + $mdUtil.nextTick(() => { + moveToIndex(preservedTopIndex); + }); + }; + vm.itemRows.getItemAtIndex(preservedTopIndex+pageSize); } function addItem($event) { diff --git a/ui/src/app/components/grid.scss b/ui/src/app/components/grid.scss index 573c736ad7..6af1f67eba 100644 --- a/ui/src/app/components/grid.scss +++ b/ui/src/app/components/grid.scss @@ -22,10 +22,20 @@ .tb-card-item { @include transition(all .2s ease-in-out); md-card-content { + padding-top: 0px; max-height: 53px; } - md-card-title-text { - max-height: 32px; + md-card-title { + width: 100%; + md-card-title-text { + max-height: 32px; + min-width: 50%; + .md-headline { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } } } diff --git a/ui/src/app/dashboard/states/default-state-controller.js b/ui/src/app/dashboard/states/default-state-controller.js index fb02147789..8d85c59aeb 100644 --- a/ui/src/app/dashboard/states/default-state-controller.js +++ b/ui/src/app/dashboard/states/default-state-controller.js @@ -28,6 +28,8 @@ export default function DefaultStateController($scope, $timeout, $location, $sta vm.getStateObject = getStateObject; vm.navigatePrevState = navigatePrevState; vm.getStateId = getStateId; + vm.getStateIndex = getStateIndex; + vm.getStateIdAtIndex = getStateIdAtIndex; vm.getStateParams = getStateParams; vm.getStateParamsByStateId = getStateParamsByStateId; vm.getEntityId = getEntityId; @@ -100,6 +102,22 @@ export default function DefaultStateController($scope, $timeout, $location, $sta } } + function getStateIndex() { + if (vm.stateObject && vm.stateObject.length) { + return vm.stateObject.length-1; + } else { + return -1; + } + } + + function getStateIdAtIndex(index) { + if (vm.stateObject && vm.stateObject[index]) { + return vm.stateObject[index].id; + } else { + return ''; + } + } + function getStateParams() { if (vm.stateObject && vm.stateObject.length) { return vm.stateObject[vm.stateObject.length - 1].params; diff --git a/ui/src/app/dashboard/states/entity-state-controller.js b/ui/src/app/dashboard/states/entity-state-controller.js index cfa664da34..ba2bc64149 100644 --- a/ui/src/app/dashboard/states/entity-state-controller.js +++ b/ui/src/app/dashboard/states/entity-state-controller.js @@ -30,6 +30,8 @@ export default function EntityStateController($scope, $timeout, $location, $stat vm.getStateObject = getStateObject; vm.navigatePrevState = navigatePrevState; vm.getStateId = getStateId; + vm.getStateIndex = getStateIndex; + vm.getStateIdAtIndex = getStateIdAtIndex; vm.getStateParams = getStateParams; vm.getStateParamsByStateId = getStateParamsByStateId; vm.getEntityId = getEntityId; @@ -108,6 +110,22 @@ export default function EntityStateController($scope, $timeout, $location, $stat } } + function getStateIndex() { + if (vm.stateObject && vm.stateObject.length) { + return vm.stateObject.length-1; + } else { + return -1; + } + } + + function getStateIdAtIndex(index) { + if (vm.stateObject && vm.stateObject[index]) { + return vm.stateObject[index].id; + } else { + return ''; + } + } + function getStateParams() { if (vm.stateObject && vm.stateObject.length) { return vm.stateObject[vm.stateObject.length - 1].params; diff --git a/ui/src/app/dashboard/states/states-component.directive.js b/ui/src/app/dashboard/states/states-component.directive.js index 1f83a6187e..8864d7417f 100644 --- a/ui/src/app/dashboard/states/states-component.directive.js +++ b/ui/src/app/dashboard/states/states-component.directive.js @@ -72,6 +72,22 @@ export default function StatesComponent($compile, $templateCache, $controller, s } } + stateController.getStateIndex = function() { + if (scope.statesController) { + return scope.statesController.getStateIndex(); + } else { + return -1; + } + } + + stateController.getStateIdAtIndex = function(index) { + if (scope.statesController) { + return scope.statesController.getStateIdAtIndex(index); + } else { + return ''; + } + } + stateController.getStateParams = function() { if (scope.statesController) { return scope.statesController.getStateParams(); diff --git a/ui/src/app/user/user-fieldset.tpl.html b/ui/src/app/user/user-fieldset.tpl.html index e02e6a4b3b..d03b462249 100644 --- a/ui/src/app/user/user-fieldset.tpl.html +++ b/ui/src/app/user/user-fieldset.tpl.html @@ -30,7 +30,7 @@
user.email-required