Browse Source

No more rules and plugins

pull/804/head
Andrew Shvayka 8 years ago
parent
commit
db4e1289c9
  1. 51
      application/pom.xml
  2. 7
      application/src/main/data/upgrade/1.5.0/schema_update.cql
  3. 5
      application/src/main/data/upgrade/1.5.0/schema_update.sql
  4. 18
      application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java
  5. 14
      application/src/main/java/org/thingsboard/server/actors/app/AppActor.java
  6. 4
      application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java
  7. 12
      application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java
  8. 1
      application/src/main/java/org/thingsboard/server/actors/device/DeviceActorToRuleEngineMsg.java
  9. 1
      application/src/main/java/org/thingsboard/server/actors/device/SessionInfo.java
  10. 159
      application/src/main/java/org/thingsboard/server/actors/plugin/PluginActor.java
  11. 252
      application/src/main/java/org/thingsboard/server/actors/plugin/PluginActorMessageProcessor.java
  12. 53
      application/src/main/java/org/thingsboard/server/actors/plugin/PluginCallbackMessage.java
  13. 576
      application/src/main/java/org/thingsboard/server/actors/plugin/PluginProcessingContext.java
  14. 30
      application/src/main/java/org/thingsboard/server/actors/plugin/PluginTerminationMsg.java
  15. 66
      application/src/main/java/org/thingsboard/server/actors/plugin/RuleToPluginMsgWrapper.java
  16. 142
      application/src/main/java/org/thingsboard/server/actors/plugin/SharedPluginProcessingContext.java
  17. 27
      application/src/main/java/org/thingsboard/server/actors/plugin/TimeoutScheduler.java
  18. 71
      application/src/main/java/org/thingsboard/server/actors/plugin/ValidationCallback.java
  19. 6
      application/src/main/java/org/thingsboard/server/actors/rpc/RpcManagerActor.java
  20. 1
      application/src/main/java/org/thingsboard/server/actors/rpc/RpcSessionTellMsg.java
  21. 18
      application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java
  22. 4
      application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainManagerActor.java
  23. 1
      application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainToRuleChainMsg.java
  24. 3
      application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java
  25. 1
      application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeToSelfMsg.java
  26. 7
      application/src/main/java/org/thingsboard/server/actors/service/ActorService.java
  27. 3
      application/src/main/java/org/thingsboard/server/actors/service/ContextBasedCreator.java
  28. 28
      application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java
  29. 24
      application/src/main/java/org/thingsboard/server/actors/service/RestMsgProcessor.java
  30. 24
      application/src/main/java/org/thingsboard/server/actors/service/WebSocketMsgProcessor.java
  31. 18
      application/src/main/java/org/thingsboard/server/actors/session/ASyncMsgProcessor.java
  32. 15
      application/src/main/java/org/thingsboard/server/actors/session/AbstractSessionActorMsgProcessor.java
  33. 7
      application/src/main/java/org/thingsboard/server/actors/session/SessionActor.java
  34. 20
      application/src/main/java/org/thingsboard/server/actors/session/SessionManagerActor.java
  35. 10
      application/src/main/java/org/thingsboard/server/actors/session/SyncMsgProcessor.java
  36. 49
      application/src/main/java/org/thingsboard/server/actors/shared/AbstractContextAwareMsgProcessor.java
  37. 1
      application/src/main/java/org/thingsboard/server/actors/shared/ComponentMsgProcessor.java
  38. 2
      application/src/main/java/org/thingsboard/server/actors/shared/EntityActorsManager.java
  39. 42
      application/src/main/java/org/thingsboard/server/actors/shared/plugin/PluginManager.java
  40. 45
      application/src/main/java/org/thingsboard/server/actors/shared/plugin/SystemPluginManager.java
  41. 57
      application/src/main/java/org/thingsboard/server/actors/shared/plugin/TenantPluginManager.java
  42. 7
      application/src/main/java/org/thingsboard/server/actors/shared/rulechain/SystemRuleChainManager.java
  43. 7
      application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java
  44. 2
      application/src/main/java/org/thingsboard/server/config/AuditLogLevelProperties.java
  45. 6
      application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java
  46. 8
      application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java
  47. 12
      application/src/main/java/org/thingsboard/server/config/WebSocketConfiguration.java
  48. 11
      application/src/main/java/org/thingsboard/server/controller/AdminController.java
  49. 24
      application/src/main/java/org/thingsboard/server/controller/AlarmController.java
  50. 15
      application/src/main/java/org/thingsboard/server/controller/AssetController.java
  51. 9
      application/src/main/java/org/thingsboard/server/controller/AuditLogController.java
  52. 12
      application/src/main/java/org/thingsboard/server/controller/AuthController.java
  53. 96
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  54. 21
      application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java
  55. 11
      application/src/main/java/org/thingsboard/server/controller/CustomerController.java
  56. 17
      application/src/main/java/org/thingsboard/server/controller/DashboardController.java
  57. 13
      application/src/main/java/org/thingsboard/server/controller/DeviceController.java
  58. 14
      application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java
  59. 14
      application/src/main/java/org/thingsboard/server/controller/EventController.java
  60. 240
      application/src/main/java/org/thingsboard/server/controller/PluginController.java
  61. 18
      application/src/main/java/org/thingsboard/server/controller/RpcController.java
  62. 13
      application/src/main/java/org/thingsboard/server/controller/RuleChainController.java
  63. 239
      application/src/main/java/org/thingsboard/server/controller/RuleController.java
  64. 7
      application/src/main/java/org/thingsboard/server/controller/TbUrlConstants.java
  65. 13
      application/src/main/java/org/thingsboard/server/controller/TelemetryController.java
  66. 15
      application/src/main/java/org/thingsboard/server/controller/UserController.java
  67. 11
      application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java
  68. 11
      application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java
  69. 85
      application/src/main/java/org/thingsboard/server/controller/plugin/PluginApiController.java
  70. 30
      application/src/main/java/org/thingsboard/server/controller/plugin/PluginNotFoundException.java
  71. 28
      application/src/main/java/org/thingsboard/server/controller/plugin/PluginWebSocketMsgEndpoint.java
  72. 46
      application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java
  73. 7
      application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java
  74. 1
      application/src/main/java/org/thingsboard/server/service/cluster/discovery/DummyDiscoveryService.java
  75. 1
      application/src/main/java/org/thingsboard/server/service/cluster/discovery/ServerInstance.java
  76. 2
      application/src/main/java/org/thingsboard/server/service/cluster/routing/ClusterRoutingService.java
  77. 1
      application/src/main/java/org/thingsboard/server/service/cluster/routing/ConsistentClusterRoutingService.java
  78. 2
      application/src/main/java/org/thingsboard/server/service/cluster/rpc/ClusterGrpcService.java
  79. 74
      application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java
  80. 2
      application/src/main/java/org/thingsboard/server/service/component/ComponentDiscoveryService.java
  81. 1
      application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseSchemaService.java
  82. 13
      application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseUpgradeService.java
  83. 6
      application/src/main/java/org/thingsboard/server/service/install/DatabaseHelper.java
  84. 22
      application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java
  85. 1
      application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java
  86. 1
      application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseSchemaService.java
  87. 10
      application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java
  88. 17
      application/src/main/java/org/thingsboard/server/service/install/cql/CassandraDbHelper.java
  89. 7
      application/src/main/java/org/thingsboard/server/service/install/sql/SqlDbHelper.java
  90. 21
      application/src/main/java/org/thingsboard/server/service/rpc/DefaultDeviceRpcService.java
  91. 1
      application/src/main/java/org/thingsboard/server/service/rpc/DeviceRpcService.java
  92. 3
      application/src/main/java/org/thingsboard/server/service/rpc/FromDeviceRpcResponse.java
  93. 2
      application/src/main/java/org/thingsboard/server/service/rpc/ToDeviceRpcRequestActorMsg.java
  94. 2
      application/src/main/java/org/thingsboard/server/service/rpc/ToServerRpcResponseActorMsg.java
  95. 6
      application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java
  96. 10
      application/src/main/java/org/thingsboard/server/service/security/ValidationCallback.java
  97. 2
      application/src/main/java/org/thingsboard/server/service/security/ValidationResult.java
  98. 5
      application/src/main/java/org/thingsboard/server/service/security/ValidationResultCode.java
  99. 8
      application/src/main/java/org/thingsboard/server/service/security/auth/jwt/JwtAuthenticationProvider.java
  100. 1
      application/src/main/java/org/thingsboard/server/service/security/auth/jwt/JwtTokenAuthenticationProcessingFilter.java

51
application/pom.xml

@ -23,7 +23,6 @@
<version>2.0.0-SNAPSHOT</version>
<artifactId>thingsboard</artifactId>
</parent>
<groupId>org.thingsboard</groupId>
<artifactId>application</artifactId>
<packaging>jar</packaging>
@ -49,10 +48,6 @@
<!-- Explicitly bring in the linux classifier, test may fail on 32-bit linux -->
<classifier>linux-x86_64</classifier>
</dependency>
<dependency>
<groupId>org.thingsboard</groupId>
<artifactId>extensions-api</artifactId>
</dependency>
<dependency>
<groupId>org.thingsboard.rule-engine</groupId>
<artifactId>rule-engine-api</artifactId>
@ -61,10 +56,6 @@
<groupId>org.thingsboard.rule-engine</groupId>
<artifactId>rule-engine-components</artifactId>
</dependency>
<dependency>
<groupId>org.thingsboard</groupId>
<artifactId>extensions-core</artifactId>
</dependency>
<dependency>
<groupId>org.thingsboard.common</groupId>
<artifactId>transport</artifactId>
@ -471,48 +462,6 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-extensions</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/extensions</outputDirectory>
<artifactItems>
<artifactItem>
<groupId>org.thingsboard.extensions</groupId>
<artifactId>extension-rabbitmq</artifactId>
<classifier>extension</classifier>
</artifactItem>
<artifactItem>
<groupId>org.thingsboard.extensions</groupId>
<artifactId>extension-rest-api-call</artifactId>
<classifier>extension</classifier>
</artifactItem>
<artifactItem>
<groupId>org.thingsboard.extensions</groupId>
<artifactId>extension-kafka</artifactId>
<classifier>extension</classifier>
</artifactItem>
<artifactItem>
<groupId>org.thingsboard.extensions</groupId>
<artifactId>extension-mqtt</artifactId>
<classifier>extension</classifier>
</artifactItem>
<artifactItem>
<groupId>org.thingsboard.extensions</groupId>
<artifactId>extension-sqs</artifactId>
<classifier>extension</classifier>
</artifactItem>
<artifactItem>
<groupId>org.thingsboard.extensions</groupId>
<artifactId>extension-sns</artifactId>
<classifier>extension</classifier>
</artifactItem>
</artifactItems>
</configuration>
</execution>
<execution>
<id>copy-winsw-service</id>
<phase>package</phase>

7
application/src/main/data/upgrade/1.5.0/schema_update.cql

@ -94,3 +94,10 @@ CREATE TABLE IF NOT EXISTS thingsboard.rule_node (
PRIMARY KEY (id)
);
DROP MATERIALIZED VIEW IF EXISTS rule_by_plugin_token;
DROP MATERIALIZED VIEW IF EXISTS rule_by_tenant_and_search_text;
DROP MATERIALIZED VIEW IF EXISTS plugin_by_api_token;
DROP MATERIALIZED VIEW IF EXISTS plugin_by_tenant_and_search_text;
DROP TABLE IF EXISTS rule;
DROP TABLE IF EXISTS plugin;

5
application/src/main/data/upgrade/1.5.0/schema_update.sql

@ -35,4 +35,7 @@ CREATE TABLE IF NOT EXISTS rule_node (
name varchar(255),
debug_mode boolean,
search_text varchar(255)
);
);
DROP TABLE rule;
DROP TABLE plugin;

18
application/src/main/java/org/thingsboard/server/actors/ActorSystemContext.java

@ -29,7 +29,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.thingsboard.rule.engine.api.ListeningExecutor;
import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.server.actors.service.ActorService;
import org.thingsboard.server.common.data.DataConstants;
@ -40,7 +39,6 @@ import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.transport.auth.DeviceAuthService;
import org.thingsboard.server.controller.plugin.PluginWebSocketMsgEndpoint;
import org.thingsboard.server.dao.alarm.AlarmService;
import org.thingsboard.server.dao.asset.AssetService;
import org.thingsboard.server.dao.attributes.AttributesService;
@ -48,11 +46,8 @@ import org.thingsboard.server.dao.audit.AuditLogService;
import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.event.EventService;
import org.thingsboard.server.dao.plugin.PluginService;
import org.thingsboard.server.dao.queue.MsgQueue;
import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.rule.RuleService;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.dao.timeseries.TimeseriesService;
import org.thingsboard.server.dao.user.UserService;
@ -131,18 +126,10 @@ public class ActorSystemContext {
@Getter
private UserService userService;
@Autowired
@Getter
private RuleService ruleService;
@Autowired
@Getter
private RuleChainService ruleChainService;
@Autowired
@Getter
private PluginService pluginService;
@Autowired
@Getter
private TimeseriesService tsService;
@ -175,11 +162,6 @@ public class ActorSystemContext {
@Getter
private DeviceRpcService deviceRpcService;
@Autowired
@Getter
@Setter
private PluginWebSocketMsgEndpoint wsMsgEndpoint;
@Autowired
@Getter
private JsExecutorService jsExecutor;

14
application/src/main/java/org/thingsboard/server/actors/app/AppActor.java

@ -15,24 +15,26 @@
*/
package org.thingsboard.server.actors.app;
import akka.actor.*;
import akka.actor.ActorRef;
import akka.actor.LocalActorRef;
import akka.actor.OneForOneStrategy;
import akka.actor.Props;
import akka.actor.SupervisorStrategy;
import akka.actor.SupervisorStrategy.Directive;
import akka.actor.Terminated;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import akka.japi.Function;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.plugin.PluginTerminationMsg;
import org.thingsboard.server.actors.ruleChain.RuleChainManagerActor;
import org.thingsboard.server.actors.service.ContextBasedCreator;
import org.thingsboard.server.actors.service.DefaultActorService;
import org.thingsboard.server.actors.shared.plugin.SystemPluginManager;
import org.thingsboard.server.actors.shared.rulechain.SystemRuleChainManager;
import org.thingsboard.server.actors.tenant.TenantActor;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageDataIterable;
import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.aware.DeviceAwareMsg;
import org.thingsboard.server.common.msg.aware.TenantAwareMsg;
import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
@ -41,8 +43,6 @@ import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.extensions.api.device.ToDeviceActorNotificationMsg;
import org.thingsboard.server.extensions.api.plugins.msg.ToPluginActorMsg;
import scala.concurrent.duration.Duration;
import java.util.HashMap;
@ -58,7 +58,7 @@ public class AppActor extends RuleChainManagerActor {
private final Map<TenantId, ActorRef> tenantActors;
private AppActor(ActorSystemContext systemContext) {
super(systemContext, new SystemRuleChainManager(systemContext), new SystemPluginManager(systemContext));
super(systemContext, new SystemRuleChainManager(systemContext));
this.tenantService = systemContext.getTenantService();
this.tenantActors = new HashMap<>();
}

4
application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java

@ -17,6 +17,8 @@ package org.thingsboard.server.actors.device;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg;
import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.service.ContextAwareActor;
import org.thingsboard.server.actors.service.ContextBasedCreator;
@ -28,8 +30,6 @@ import org.thingsboard.server.common.msg.device.DeviceToDeviceActorMsg;
import org.thingsboard.server.common.msg.timeout.DeviceActorClientSideRpcTimeoutMsg;
import org.thingsboard.server.common.msg.timeout.DeviceActorQueueTimeoutMsg;
import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeoutMsg;
import org.thingsboard.server.extensions.api.device.DeviceAttributesEventNotificationMsg;
import org.thingsboard.server.extensions.api.device.DeviceNameOrTypeUpdateMsg;
import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg;
import org.thingsboard.server.service.rpc.ToServerRpcResponseActorMsg;

12
application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java

@ -25,6 +25,9 @@ import com.google.common.util.concurrent.ListenableFuture;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.thingsboard.rule.engine.api.RpcError;
import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg;
import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor;
import org.thingsboard.server.common.data.DataConstants;
@ -41,12 +44,13 @@ import org.thingsboard.server.common.msg.TbMsgDataType;
import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.core.ActorSystemToDeviceSessionActorMsg;
import org.thingsboard.server.common.msg.core.AttributesUpdateNotification;
import org.thingsboard.server.common.msg.core.AttributesUpdateRequest;
import org.thingsboard.server.common.msg.core.BasicActorSystemToDeviceSessionActorMsg;
import org.thingsboard.server.common.msg.core.BasicCommandAckResponse;
import org.thingsboard.server.common.msg.core.BasicGetAttributesResponse;
import org.thingsboard.server.common.msg.core.BasicStatusCodeResponse;
import org.thingsboard.server.common.msg.core.BasicActorSystemToDeviceSessionActorMsg;
import org.thingsboard.server.common.msg.core.GetAttributesRequest;
import org.thingsboard.server.common.msg.core.RuleEngineError;
import org.thingsboard.server.common.msg.core.RuleEngineErrorMsg;
@ -56,7 +60,6 @@ import org.thingsboard.server.common.msg.core.SessionOpenMsg;
import org.thingsboard.server.common.msg.core.TelemetryUploadRequest;
import org.thingsboard.server.common.msg.core.ToDeviceRpcRequestMsg;
import org.thingsboard.server.common.msg.core.ToDeviceRpcResponseMsg;
import org.thingsboard.server.common.msg.core.ActorSystemToDeviceSessionActorMsg;
import org.thingsboard.server.common.msg.core.ToServerRpcRequestMsg;
import org.thingsboard.server.common.msg.device.DeviceToDeviceActorMsg;
import org.thingsboard.server.common.msg.kv.BasicAttributeKVMsg;
@ -68,10 +71,7 @@ import org.thingsboard.server.common.msg.session.ToDeviceMsg;
import org.thingsboard.server.common.msg.timeout.DeviceActorClientSideRpcTimeoutMsg;
import org.thingsboard.server.common.msg.timeout.DeviceActorQueueTimeoutMsg;
import org.thingsboard.server.common.msg.timeout.DeviceActorServerSideRpcTimeoutMsg;
import org.thingsboard.server.extensions.api.device.DeviceAttributesEventNotificationMsg;
import org.thingsboard.server.extensions.api.device.DeviceNameOrTypeUpdateMsg;
import org.thingsboard.server.extensions.api.plugins.msg.FromDeviceRpcResponse;
import org.thingsboard.server.extensions.api.plugins.msg.RpcError;
import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg;
import org.thingsboard.server.service.rpc.ToServerRpcResponseActorMsg;

1
application/src/main/java/org/thingsboard/server/actors/device/DeviceActorToRuleEngineMsg.java

@ -17,7 +17,6 @@ package org.thingsboard.server.actors.device;
import akka.actor.ActorRef;
import lombok.Data;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.MsgType;
import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.TbMsg;

1
application/src/main/java/org/thingsboard/server/actors/device/SessionInfo.java

@ -16,7 +16,6 @@
package org.thingsboard.server.actors.device;
import lombok.Data;
import org.thingsboard.server.common.data.id.SessionId;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.session.SessionType;

159
application/src/main/java/org/thingsboard/server/actors/plugin/PluginActor.java

@ -1,159 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.actors.plugin;
import akka.actor.ActorContext;
import akka.actor.ActorRef;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.service.ComponentActor;
import org.thingsboard.server.actors.service.ContextBasedCreator;
import org.thingsboard.server.actors.stats.StatsPersistTick;
import org.thingsboard.server.common.data.id.PluginId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
import org.thingsboard.server.common.msg.timeout.TimeoutMsg;
import org.thingsboard.server.extensions.api.plugins.msg.ToPluginRpcResponseDeviceMsg;
import org.thingsboard.server.extensions.api.plugins.rest.PluginRestMsg;
import org.thingsboard.server.extensions.api.plugins.rpc.PluginRpcMsg;
import org.thingsboard.server.extensions.api.plugins.ws.msg.PluginWebsocketMsg;
import org.thingsboard.server.extensions.api.rules.RuleException;
public class PluginActor extends ComponentActor<PluginId, PluginActorMessageProcessor> {
private PluginActor(ActorSystemContext systemContext, TenantId tenantId, PluginId pluginId) {
super(systemContext, tenantId, pluginId);
setProcessor(new PluginActorMessageProcessor(tenantId, pluginId, systemContext,
logger, context().parent(), context().self()));
}
@Override
protected boolean process(TbActorMsg msg) {
//TODO Move everything here, to work with TbActorMsg
return false;
}
@Override
public void onReceive(Object msg) throws Exception {
if (msg instanceof PluginWebsocketMsg) {
onWebsocketMsg((PluginWebsocketMsg<?>) msg);
} else if (msg instanceof PluginRestMsg) {
onRestMsg((PluginRestMsg) msg);
} else if (msg instanceof PluginCallbackMessage) {
onPluginCallback((PluginCallbackMessage) msg);
} else if (msg instanceof RuleToPluginMsgWrapper) {
onRuleToPluginMsg((RuleToPluginMsgWrapper) msg);
} else if (msg instanceof PluginRpcMsg) {
onRpcMsg((PluginRpcMsg) msg);
} else if (msg instanceof ClusterEventMsg) {
onClusterEventMsg((ClusterEventMsg) msg);
} else if (msg instanceof ComponentLifecycleMsg) {
onComponentLifecycleMsg((ComponentLifecycleMsg) msg);
} else if (msg instanceof ToPluginRpcResponseDeviceMsg) {
onRpcResponse((ToPluginRpcResponseDeviceMsg) msg);
} else if (msg instanceof PluginTerminationMsg) {
logger.info("[{}][{}] Going to terminate plugin actor.", tenantId, id);
context().parent().tell(msg, ActorRef.noSender());
context().stop(self());
} else if (msg instanceof TimeoutMsg) {
onTimeoutMsg(context(), (TimeoutMsg) msg);
} else if (msg instanceof StatsPersistTick) {
onStatsPersistTick(id);
} else {
logger.debug("[{}][{}] Unknown msg type.", tenantId, id, msg.getClass().getName());
}
}
private void onPluginCallback(PluginCallbackMessage msg) {
try {
processor.onPluginCallbackMsg(msg);
} catch (Exception e) {
logAndPersist("onPluginCallbackMsg", e);
}
}
private void onTimeoutMsg(ActorContext context, TimeoutMsg msg) {
processor.onTimeoutMsg(context, msg);
}
private void onRpcResponse(ToPluginRpcResponseDeviceMsg msg) {
processor.onDeviceRpcMsg(msg.getResponse());
}
private void onRuleToPluginMsg(RuleToPluginMsgWrapper msg) throws RuleException {
logger.debug("[{}] Going to process rule msg: {}", id, msg.getMsg());
try {
processor.onRuleToPluginMsg(msg);
increaseMessagesProcessedCount();
} catch (Exception e) {
logAndPersist("onRuleMsg", e);
}
}
private void onWebsocketMsg(PluginWebsocketMsg<?> msg) {
logger.debug("[{}] Going to process web socket msg: {}", id, msg);
try {
processor.onWebsocketMsg(msg);
increaseMessagesProcessedCount();
} catch (Exception e) {
logAndPersist("onWebsocketMsg", e);
}
}
private void onRestMsg(PluginRestMsg msg) {
logger.debug("[{}] Going to process rest msg: {}", id, msg);
try {
processor.onRestMsg(msg);
increaseMessagesProcessedCount();
} catch (Exception e) {
logAndPersist("onRestMsg", e);
}
}
private void onRpcMsg(PluginRpcMsg msg) {
try {
logger.debug("[{}] Going to process rpc msg: {}", id, msg);
processor.onRpcMsg(msg);
} catch (Exception e) {
logAndPersist("onRpcMsg", e);
}
}
public static class ActorCreator extends ContextBasedCreator<PluginActor> {
private static final long serialVersionUID = 1L;
private final TenantId tenantId;
private final PluginId pluginId;
public ActorCreator(ActorSystemContext context, TenantId tenantId, PluginId pluginId) {
super(context);
this.tenantId = tenantId;
this.pluginId = pluginId;
}
@Override
public PluginActor create() throws Exception {
return new PluginActor(context, tenantId, pluginId);
}
}
@Override
protected long getErrorPersistFrequency() {
return 0;
// return systemContext.getPluginErrorPersistFrequency();
}
}

252
application/src/main/java/org/thingsboard/server/actors/plugin/PluginActorMessageProcessor.java

@ -1,252 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.actors.plugin;
import akka.actor.ActorContext;
import akka.actor.ActorRef;
import akka.event.LoggingAdapter;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.shared.ComponentMsgProcessor;
import org.thingsboard.server.common.data.id.PluginId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.plugin.PluginMetaData;
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.core.BasicStatusCodeResponse;
import org.thingsboard.server.common.msg.session.FromDeviceRequestMsg;
import org.thingsboard.server.common.msg.session.SessionMsgType;
import org.thingsboard.server.common.msg.session.SessionMsgType;
import org.thingsboard.server.extensions.api.plugins.Plugin;
import org.thingsboard.server.extensions.api.plugins.PluginInitializationException;
import org.thingsboard.server.extensions.api.plugins.msg.FromDeviceRpcResponse;
import org.thingsboard.server.extensions.api.plugins.msg.ResponsePluginToRuleMsg;
import org.thingsboard.server.extensions.api.plugins.msg.RuleToPluginMsg;
import org.thingsboard.server.common.msg.timeout.TimeoutMsg;
import org.thingsboard.server.extensions.api.plugins.rest.PluginRestMsg;
import org.thingsboard.server.extensions.api.plugins.rpc.PluginRpcMsg;
import org.thingsboard.server.extensions.api.plugins.ws.msg.PluginWebsocketMsg;
import org.thingsboard.server.extensions.api.rules.RuleException;
/**
* @author Andrew Shvayka
*/
public class PluginActorMessageProcessor extends ComponentMsgProcessor<PluginId> {
private final SharedPluginProcessingContext pluginCtx;
private final PluginProcessingContext trustedCtx;
private PluginMetaData pluginMd;
private Plugin pluginImpl;
private ComponentLifecycleState state;
protected PluginActorMessageProcessor(TenantId tenantId, PluginId pluginId, ActorSystemContext systemContext
, LoggingAdapter logger, ActorRef parent, ActorRef self) {
super(systemContext, logger, tenantId, pluginId);
this.pluginCtx = new SharedPluginProcessingContext(systemContext, tenantId, pluginId, parent, self);
this.trustedCtx = new PluginProcessingContext(pluginCtx, null);
}
@Override
public void start(ActorContext context) throws Exception {
logger.info("[{}] Going to start plugin actor.", entityId);
pluginMd = systemContext.getPluginService().findPluginById(entityId);
if (pluginMd == null) {
throw new PluginInitializationException("Plugin not found!");
}
if (pluginMd.getConfiguration() == null) {
throw new PluginInitializationException("Plugin metadata is empty!");
}
state = pluginMd.getState();
if (state == ComponentLifecycleState.ACTIVE) {
logger.info("[{}] Plugin is active. Going to initialize plugin.", entityId);
initComponent();
} else {
logger.info("[{}] Plugin is suspended. Skipping plugin initialization.", entityId);
}
}
@Override
public void stop(ActorContext context) throws Exception {
onStop();
}
private void initComponent() {
try {
pluginImpl = initComponent(pluginMd.getClazz(), ComponentType.PLUGIN, mapper.writeValueAsString(pluginMd.getConfiguration()));
} catch (InstantiationException e) {
throw new PluginInitializationException("No default constructor for plugin implementation!", e);
} catch (IllegalAccessException e) {
throw new PluginInitializationException("Illegal Access Exception during plugin initialization!", e);
} catch (ClassNotFoundException e) {
throw new PluginInitializationException("Plugin Class not found!", e);
} catch (JsonProcessingException e) {
throw new PluginInitializationException("Plugin Configuration is invalid!", e);
} catch (Exception e) {
throw new PluginInitializationException(e.getMessage(), e);
}
}
public void onRuleToPluginMsg(RuleToPluginMsgWrapper msg) throws RuleException {
if (state == ComponentLifecycleState.ACTIVE) {
try {
pluginImpl.process(trustedCtx, msg.getRuleTenantId(), msg.getRuleId(), msg.getMsg());
} catch (Exception ex) {
logger.debug("[{}] Failed to process RuleToPlugin msg: [{}] [{}]", tenantId, msg.getMsg(), ex);
RuleToPluginMsg ruleMsg = msg.getMsg();
SessionMsgType responceMsgType = SessionMsgType.RULE_ENGINE_ERROR;
Integer requestId = 0;
if (ruleMsg.getPayload() instanceof FromDeviceRequestMsg) {
requestId = ((FromDeviceRequestMsg) ruleMsg.getPayload()).getRequestId();
}
trustedCtx.reply(
new ResponsePluginToRuleMsg(ruleMsg.getUid(), tenantId, msg.getRuleId(),
BasicStatusCodeResponse.onError(responceMsgType, requestId, ex)));
}
} else {
//TODO: reply with plugin suspended message
}
}
public void onWebsocketMsg(PluginWebsocketMsg<?> msg) {
if (state == ComponentLifecycleState.ACTIVE) {
pluginImpl.process(new PluginProcessingContext(pluginCtx, msg.getSecurityCtx()), msg);
} else {
//TODO: reply with plugin suspended message
}
}
public void onRestMsg(PluginRestMsg msg) {
if (state == ComponentLifecycleState.ACTIVE) {
pluginImpl.process(new PluginProcessingContext(pluginCtx, msg.getSecurityCtx()), msg);
}
}
public void onRpcMsg(PluginRpcMsg msg) {
if (state == ComponentLifecycleState.ACTIVE) {
pluginImpl.process(trustedCtx, msg.getRpcMsg());
} else {
//TODO: reply with plugin suspended message
}
}
public void onPluginCallbackMsg(PluginCallbackMessage msg) {
if (state == ComponentLifecycleState.ACTIVE) {
if (msg.isSuccess()) {
msg.getCallback().onSuccess(trustedCtx, msg.getV());
} else {
msg.getCallback().onFailure(trustedCtx, msg.getE());
}
} else {
//TODO: reply with plugin suspended message
}
}
public void onTimeoutMsg(ActorContext context, TimeoutMsg<?> msg) {
if (state == ComponentLifecycleState.ACTIVE) {
pluginImpl.process(trustedCtx, msg);
}
}
public void onDeviceRpcMsg(FromDeviceRpcResponse response) {
if (state == ComponentLifecycleState.ACTIVE) {
pluginImpl.process(trustedCtx, response);
}
}
@Override
public void onClusterEventMsg(ClusterEventMsg msg) {
if (state == ComponentLifecycleState.ACTIVE) {
ServerAddress address = msg.getServerAddress();
if (msg.isAdded()) {
logger.debug("[{}] Going to process server add msg: {}", entityId, address);
pluginImpl.onServerAdded(trustedCtx, address);
} else {
logger.debug("[{}] Going to process server remove msg: {}", entityId, address);
pluginImpl.onServerRemoved(trustedCtx, address);
}
}
}
@Override
public void onCreated(ActorContext context) {
logger.info("[{}] Going to process onCreated plugin.", entityId);
}
@Override
public void onUpdate(ActorContext context) throws Exception {
PluginMetaData oldPluginMd = pluginMd;
pluginMd = systemContext.getPluginService().findPluginById(entityId);
boolean requiresRestart = false;
logger.info("[{}] Plugin configuration was updated from {} to {}.", entityId, oldPluginMd, pluginMd);
if (!oldPluginMd.getClazz().equals(pluginMd.getClazz())) {
logger.info("[{}] Plugin requires restart due to clazz change from {} to {}.",
entityId, oldPluginMd.getClazz(), pluginMd.getClazz());
requiresRestart = true;
} else if (!oldPluginMd.getConfiguration().equals(pluginMd.getConfiguration())) {
logger.info("[{}] Plugin requires restart due to configuration change from {} to {}.",
entityId, oldPluginMd.getConfiguration(), pluginMd.getConfiguration());
requiresRestart = true;
}
if (requiresRestart) {
this.state = ComponentLifecycleState.SUSPENDED;
if (pluginImpl != null) {
pluginImpl.stop(trustedCtx);
}
start(context);
}
}
@Override
public void onStop(ActorContext context) {
onStop();
// scheduleMsgWithDelay(context, new PluginTerminationMsg(entityId), systemContext.getPluginActorTerminationDelay());
}
private void onStop() {
logger.info("[{}] Going to process onStop plugin.", entityId);
this.state = ComponentLifecycleState.SUSPENDED;
if (pluginImpl != null) {
pluginImpl.stop(trustedCtx);
}
}
@Override
public void onActivate(ActorContext context) throws Exception {
logger.info("[{}] Going to process onActivate plugin.", entityId);
this.state = ComponentLifecycleState.ACTIVE;
if (pluginImpl != null) {
pluginImpl.resume(trustedCtx);
logger.info("[{}] Plugin resumed.", entityId);
} else {
start(context);
}
}
@Override
public void onSuspend(ActorContext context) {
logger.info("[{}] Going to process onSuspend plugin.", entityId);
this.state = ComponentLifecycleState.SUSPENDED;
if (pluginImpl != null) {
pluginImpl.suspend(trustedCtx);
}
}
}

53
application/src/main/java/org/thingsboard/server/actors/plugin/PluginCallbackMessage.java

@ -1,53 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.actors.plugin;
import lombok.Data;
import lombok.Getter;
import lombok.ToString;
import org.thingsboard.server.extensions.api.plugins.PluginCallback;
import java.util.Optional;
/**
* @author Andrew Shvayka
*/
@ToString
public final class PluginCallbackMessage<V> {
@Getter
private final PluginCallback<V> callback;
@Getter
private final boolean success;
@Getter
private final V v;
@Getter
private final Exception e;
public static <V> PluginCallbackMessage<V> onSuccess(PluginCallback<V> callback, V data) {
return new PluginCallbackMessage<V>(true, callback, data, null);
}
public static <V> PluginCallbackMessage<V> onError(PluginCallback<V> callback, Exception e) {
return new PluginCallbackMessage<V>(false, callback, null, e);
}
private PluginCallbackMessage(boolean success, PluginCallback<V> callback, V v, Exception e) {
this.success = success;
this.callback = callback;
this.v = v;
this.e = e;
}
}

576
application/src/main/java/org/thingsboard/server/actors/plugin/PluginProcessingContext.java

@ -1,576 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.actors.plugin;
import akka.actor.ActorRef;
import com.google.common.base.Function;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.id.*;
import org.thingsboard.server.common.data.kv.AttributeKey;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.kv.TsKvQuery;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.plugin.PluginMetaData;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleMetaData;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
import org.thingsboard.server.common.msg.timeout.TimeoutMsg;
import org.thingsboard.server.extensions.api.device.DeviceAttributesEventNotificationMsg;
import org.thingsboard.server.extensions.api.plugins.PluginApiCallSecurityContext;
import org.thingsboard.server.extensions.api.plugins.PluginCallback;
import org.thingsboard.server.extensions.api.plugins.PluginContext;
import org.thingsboard.server.extensions.api.plugins.msg.*;
import org.thingsboard.server.extensions.api.plugins.rpc.PluginRpcMsg;
import org.thingsboard.server.extensions.api.plugins.rpc.RpcMsg;
import org.thingsboard.server.extensions.api.plugins.ws.PluginWebsocketSessionRef;
import org.thingsboard.server.extensions.api.plugins.ws.msg.PluginWebsocketMsg;
import javax.annotation.Nullable;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
@Slf4j
public final class PluginProcessingContext implements PluginContext {
private static final Executor executor = Executors.newSingleThreadExecutor();
public static final String CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "Customer user is not allowed to perform this operation!";
public static final String SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION = "System administrator is not allowed to perform this operation!";
public static final String DEVICE_WITH_REQUESTED_ID_NOT_FOUND = "Device with requested id wasn't found!";
private final SharedPluginProcessingContext pluginCtx;
private final Optional<PluginApiCallSecurityContext> securityCtx;
public PluginProcessingContext(SharedPluginProcessingContext pluginCtx, PluginApiCallSecurityContext securityCtx) {
super();
this.pluginCtx = pluginCtx;
this.securityCtx = Optional.ofNullable(securityCtx);
}
public void persistError(String method, Exception e) {
pluginCtx.persistError(method, e);
}
@Override
public void sendPluginRpcMsg(RpcMsg msg) {
//ToDO is this a cluster messsage?
// this.pluginCtx.rpcService.tell(new PluginRpcMsg(pluginCtx.tenantId, pluginCtx.pluginId, msg));
}
@Override
public void send(PluginWebsocketMsg<?> wsMsg) throws IOException {
pluginCtx.msgEndpoint.send(wsMsg);
}
@Override
public void close(PluginWebsocketSessionRef sessionRef) throws IOException {
pluginCtx.msgEndpoint.close(sessionRef);
}
@Override
public void saveAttributes(final TenantId tenantId, final EntityId entityId, final String scope, final List<AttributeKvEntry> attributes, final PluginCallback<Void> callback) {
validate(entityId, new ValidationCallback(callback, ctx -> {
ListenableFuture<List<Void>> futures = pluginCtx.attributesService.save(entityId, scope, attributes);
Futures.addCallback(futures, getListCallback(callback, v -> {
if (entityId.getEntityType() == EntityType.DEVICE) {
onDeviceAttributesChanged(tenantId, new DeviceId(entityId.getId()), scope, attributes);
}
return null;
}), executor);
}));
}
@Override
public void removeAttributes(final TenantId tenantId, final EntityId entityId, final String scope, final List<String> keys, final PluginCallback<Void> callback) {
validate(entityId, new ValidationCallback(callback, ctx -> {
ListenableFuture<List<Void>> futures = pluginCtx.attributesService.removeAll(entityId, scope, keys);
Futures.addCallback(futures, getCallback(callback, v -> null), executor);
if (entityId.getEntityType() == EntityType.DEVICE) {
onDeviceAttributesDeleted(tenantId, new DeviceId(entityId.getId()), keys.stream().map(key -> new AttributeKey(scope, key)).collect(Collectors.toSet()));
}
}));
}
@Override
public void loadAttribute(EntityId entityId, String attributeType, String attributeKey, final PluginCallback<Optional<AttributeKvEntry>> callback) {
validate(entityId, new ValidationCallback(callback, ctx -> {
ListenableFuture<Optional<AttributeKvEntry>> future = pluginCtx.attributesService.find(entityId, attributeType, attributeKey);
Futures.addCallback(future, getCallback(callback, v -> v), executor);
}));
}
@Override
public void loadAttributes(EntityId entityId, String attributeType, Collection<String> attributeKeys, final PluginCallback<List<AttributeKvEntry>> callback) {
validate(entityId, new ValidationCallback(callback, ctx -> {
ListenableFuture<List<AttributeKvEntry>> future = pluginCtx.attributesService.find(entityId, attributeType, attributeKeys);
Futures.addCallback(future, getCallback(callback, v -> v), executor);
}));
}
@Override
public void loadAttributes(EntityId entityId, String attributeType, PluginCallback<List<AttributeKvEntry>> callback) {
validate(entityId, new ValidationCallback(callback, ctx -> {
ListenableFuture<List<AttributeKvEntry>> future = pluginCtx.attributesService.findAll(entityId, attributeType);
Futures.addCallback(future, getCallback(callback, v -> v), executor);
}));
}
@Override
public void loadAttributes(final EntityId entityId, final Collection<String> attributeTypes, final PluginCallback<List<AttributeKvEntry>> callback) {
validate(entityId, new ValidationCallback(callback, ctx -> {
List<ListenableFuture<List<AttributeKvEntry>>> futures = new ArrayList<>();
attributeTypes.forEach(attributeType -> futures.add(pluginCtx.attributesService.findAll(entityId, attributeType)));
convertFuturesAndAddCallback(callback, futures);
}));
}
@Override
public void loadAttributes(final EntityId entityId, final Collection<String> attributeTypes, final Collection<String> attributeKeys, final PluginCallback<List<AttributeKvEntry>> callback) {
validate(entityId, new ValidationCallback(callback, ctx -> {
List<ListenableFuture<List<AttributeKvEntry>>> futures = new ArrayList<>();
attributeTypes.forEach(attributeType -> futures.add(pluginCtx.attributesService.find(entityId, attributeType, attributeKeys)));
convertFuturesAndAddCallback(callback, futures);
}));
}
@Override
public void saveTsData(final EntityId entityId, final TsKvEntry entry, final PluginCallback<Void> callback) {
validate(entityId, new ValidationCallback(callback, ctx -> {
ListenableFuture<List<Void>> rsListFuture = pluginCtx.tsService.save(entityId, entry);
Futures.addCallback(rsListFuture, getListCallback(callback, v -> null), executor);
}));
}
@Override
public void saveTsData(final EntityId entityId, final List<TsKvEntry> entries, final PluginCallback<Void> callback) {
saveTsData(entityId, entries, 0L, callback);
}
@Override
public void saveTsData(final EntityId entityId, final List<TsKvEntry> entries, long ttl, final PluginCallback<Void> callback) {
validate(entityId, new ValidationCallback(callback, ctx -> {
ListenableFuture<List<Void>> rsListFuture = pluginCtx.tsService.save(entityId, entries, ttl);
Futures.addCallback(rsListFuture, getListCallback(callback, v -> null), executor);
}));
}
@Override
public void loadTimeseries(final EntityId entityId, final List<TsKvQuery> queries, final PluginCallback<List<TsKvEntry>> callback) {
validate(entityId, new ValidationCallback(callback, ctx -> {
ListenableFuture<List<TsKvEntry>> future = pluginCtx.tsService.findAll(entityId, queries);
Futures.addCallback(future, getCallback(callback, v -> v), executor);
}));
}
@Override
public void loadLatestTimeseries(final EntityId entityId, final PluginCallback<List<TsKvEntry>> callback) {
validate(entityId, new ValidationCallback(callback, ctx -> {
ListenableFuture<List<TsKvEntry>> future = pluginCtx.tsService.findAllLatest(entityId);
Futures.addCallback(future, getCallback(callback, v -> v), executor);
}));
}
@Override
public void logAttributesUpdated(PluginApiCallSecurityContext ctx, EntityId entityId, String attributeType,
List<AttributeKvEntry> attributes, Exception e) {
pluginCtx.auditLogService.logEntityAction(
ctx.getTenantId(),
ctx.getCustomerId(),
ctx.getUserId(),
ctx.getUserName(),
(UUIDBased & EntityId)entityId,
null,
ActionType.ATTRIBUTES_UPDATED,
e,
attributeType,
attributes);
}
@Override
public void logAttributesDeleted(PluginApiCallSecurityContext ctx, EntityId entityId, String attributeType, List<String> keys, Exception e) {
pluginCtx.auditLogService.logEntityAction(
ctx.getTenantId(),
ctx.getCustomerId(),
ctx.getUserId(),
ctx.getUserName(),
(UUIDBased & EntityId)entityId,
null,
ActionType.ATTRIBUTES_DELETED,
e,
attributeType,
keys);
}
@Override
public void logAttributesRead(PluginApiCallSecurityContext ctx, EntityId entityId, String attributeType, List<String> keys, Exception e) {
pluginCtx.auditLogService.logEntityAction(
ctx.getTenantId(),
ctx.getCustomerId(),
ctx.getUserId(),
ctx.getUserName(),
(UUIDBased & EntityId)entityId,
null,
ActionType.ATTRIBUTES_READ,
e,
attributeType,
keys);
}
@Override
public void loadLatestTimeseries(final EntityId entityId, final Collection<String> keys, final PluginCallback<List<TsKvEntry>> callback) {
validate(entityId, new ValidationCallback(callback, ctx -> {
ListenableFuture<List<TsKvEntry>> rsListFuture = pluginCtx.tsService.findLatest(entityId, keys);
Futures.addCallback(rsListFuture, getCallback(callback, v -> v), executor);
}));
}
@Override
public void reply(PluginToRuleMsg<?> msg) {
pluginCtx.parentActor.tell(msg, ActorRef.noSender());
}
@Override
public PluginId getPluginId() {
return pluginCtx.pluginId;
}
@Override
public Optional<PluginApiCallSecurityContext> getSecurityCtx() {
return securityCtx;
}
private void onDeviceAttributesDeleted(TenantId tenantId, DeviceId deviceId, Set<AttributeKey> keys) {
pluginCtx.toDeviceActor(DeviceAttributesEventNotificationMsg.onDelete(tenantId, deviceId, keys));
}
private void onDeviceAttributesChanged(TenantId tenantId, DeviceId deviceId, String scope, List<AttributeKvEntry> values) {
pluginCtx.toDeviceActor(DeviceAttributesEventNotificationMsg.onUpdate(tenantId, deviceId, scope, values));
}
private <T, R> FutureCallback<List<T>> getListCallback(final PluginCallback<R> callback, Function<List<T>, R> transformer) {
return new FutureCallback<List<T>>() {
@Override
public void onSuccess(@Nullable List<T> result) {
pluginCtx.self().tell(PluginCallbackMessage.onSuccess(callback, transformer.apply(result)), ActorRef.noSender());
}
@Override
public void onFailure(Throwable t) {
if (t instanceof Exception) {
pluginCtx.self().tell(PluginCallbackMessage.onError(callback, (Exception) t), ActorRef.noSender());
} else {
log.error("Critical error: {}", t.getMessage(), t);
}
}
};
}
private <T, R> FutureCallback<R> getCallback(final PluginCallback<T> callback, Function<R, T> transformer) {
return new FutureCallback<R>() {
@Override
public void onSuccess(@Nullable R result) {
try {
pluginCtx.self().tell(PluginCallbackMessage.onSuccess(callback, transformer.apply(result)), ActorRef.noSender());
} catch (Exception e) {
pluginCtx.self().tell(PluginCallbackMessage.onError(callback, e), ActorRef.noSender());
}
}
@Override
public void onFailure(Throwable t) {
if (t instanceof Exception) {
pluginCtx.self().tell(PluginCallbackMessage.onError(callback, (Exception) t), ActorRef.noSender());
} else {
log.error("Critical error: {}", t.getMessage(), t);
}
}
};
}
@Override
public void checkAccess(DeviceId deviceId, PluginCallback<Void> callback) {
validate(deviceId, new ValidationCallback(callback, ctx -> callback.onSuccess(ctx, null)));
}
private void validate(EntityId entityId, ValidationCallback callback) {
if (securityCtx.isPresent()) {
final PluginApiCallSecurityContext ctx = securityCtx.get();
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 RULE_CHAIN:
validateRuleChain(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, ValidationResult.ok(null));
}
}
private void validateDevice(final PluginApiCallSecurityContext ctx, EntityId entityId, ValidationCallback callback) {
if (ctx.isSystemAdmin()) {
callback.onSuccess(this, ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else {
ListenableFuture<Device> deviceFuture = pluginCtx.deviceService.findDeviceByIdAsync(new DeviceId(entityId.getId()));
Futures.addCallback(deviceFuture, getCallback(callback, device -> {
if (device == null) {
return ValidationResult.entityNotFound(DEVICE_WITH_REQUESTED_ID_NOT_FOUND);
} else {
if (!device.getTenantId().equals(ctx.getTenantId())) {
return ValidationResult.accessDenied("Device doesn't belong to the current Tenant!");
} else if (ctx.isCustomerUser() && !device.getCustomerId().equals(ctx.getCustomerId())) {
return ValidationResult.accessDenied("Device doesn't belong to the current Customer!");
} else {
return ValidationResult.ok(null);
}
}
}));
}
}
private void validateAsset(final PluginApiCallSecurityContext ctx, EntityId entityId, ValidationCallback callback) {
if (ctx.isSystemAdmin()) {
callback.onSuccess(this, ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else {
ListenableFuture<Asset> assetFuture = pluginCtx.assetService.findAssetByIdAsync(new AssetId(entityId.getId()));
Futures.addCallback(assetFuture, getCallback(callback, asset -> {
if (asset == null) {
return ValidationResult.entityNotFound("Asset with requested id wasn't found!");
} else {
if (!asset.getTenantId().equals(ctx.getTenantId())) {
return ValidationResult.accessDenied("Asset doesn't belong to the current Tenant!");
} else if (ctx.isCustomerUser() && !asset.getCustomerId().equals(ctx.getCustomerId())) {
return ValidationResult.accessDenied("Asset doesn't belong to the current Customer!");
} else {
return ValidationResult.ok(null);
}
}
}));
}
}
private void validateRule(final PluginApiCallSecurityContext ctx, EntityId entityId, ValidationCallback callback) {
if (ctx.isCustomerUser()) {
callback.onSuccess(this, ValidationResult.accessDenied(CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else {
ListenableFuture<RuleMetaData> ruleFuture = pluginCtx.ruleService.findRuleByIdAsync(new RuleId(entityId.getId()));
Futures.addCallback(ruleFuture, getCallback(callback, rule -> {
if (rule == null) {
return ValidationResult.entityNotFound("Rule with requested id wasn't found!");
} else {
if (ctx.isTenantAdmin() && !rule.getTenantId().equals(ctx.getTenantId())) {
return ValidationResult.accessDenied("Rule doesn't belong to the current Tenant!");
} else if (ctx.isSystemAdmin() && !rule.getTenantId().isNullUid()) {
return ValidationResult.accessDenied("Rule is not in system scope!");
} else {
return ValidationResult.ok(null);
}
}
}));
}
}
private void validateRuleChain(final PluginApiCallSecurityContext ctx, EntityId entityId, ValidationCallback callback) {
if (ctx.isCustomerUser()) {
callback.onSuccess(this, ValidationResult.accessDenied(CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else {
ListenableFuture<RuleChain> ruleChainFuture = pluginCtx.ruleChainService.findRuleChainByIdAsync(new RuleChainId(entityId.getId()));
Futures.addCallback(ruleChainFuture, getCallback(callback, ruleChain -> {
if (ruleChain == null) {
return ValidationResult.entityNotFound("Rule chain with requested id wasn't found!");
} else {
if (ctx.isTenantAdmin() && !ruleChain.getTenantId().equals(ctx.getTenantId())) {
return ValidationResult.accessDenied("Rule chain doesn't belong to the current Tenant!");
} else if (ctx.isSystemAdmin() && !ruleChain.getTenantId().isNullUid()) {
return ValidationResult.accessDenied("Rule chain is not in system scope!");
} else {
return ValidationResult.ok(null);
}
}
}));
}
}
private void validatePlugin(final PluginApiCallSecurityContext ctx, EntityId entityId, ValidationCallback callback) {
if (ctx.isCustomerUser()) {
callback.onSuccess(this, ValidationResult.accessDenied(CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else {
ListenableFuture<PluginMetaData> pluginFuture = pluginCtx.pluginService.findPluginByIdAsync(new PluginId(entityId.getId()));
Futures.addCallback(pluginFuture, getCallback(callback, plugin -> {
if (plugin == null) {
return ValidationResult.entityNotFound("Plugin with requested id wasn't found!");
} else {
if (ctx.isTenantAdmin() && !plugin.getTenantId().equals(ctx.getTenantId())) {
return ValidationResult.accessDenied("Plugin doesn't belong to the current Tenant!");
} else if (ctx.isSystemAdmin() && !plugin.getTenantId().isNullUid()) {
return ValidationResult.accessDenied("Plugin is not in system scope!");
} else {
return ValidationResult.ok(null);
}
}
}));
}
}
private void validateCustomer(final PluginApiCallSecurityContext ctx, EntityId entityId, ValidationCallback callback) {
if (ctx.isSystemAdmin()) {
callback.onSuccess(this, ValidationResult.accessDenied(SYSTEM_ADMINISTRATOR_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else {
ListenableFuture<Customer> customerFuture = pluginCtx.customerService.findCustomerByIdAsync(new CustomerId(entityId.getId()));
Futures.addCallback(customerFuture, getCallback(callback, customer -> {
if (customer == null) {
return ValidationResult.entityNotFound("Customer with requested id wasn't found!");
} else {
if (!customer.getTenantId().equals(ctx.getTenantId())) {
return ValidationResult.accessDenied("Customer doesn't belong to the current Tenant!");
} else if (ctx.isCustomerUser() && !customer.getId().equals(ctx.getCustomerId())) {
return ValidationResult.accessDenied("Customer doesn't relate to the currently authorized customer user!");
} else {
return ValidationResult.ok(null);
}
}
}));
}
}
private void validateTenant(final PluginApiCallSecurityContext ctx, EntityId entityId, ValidationCallback callback) {
if (ctx.isCustomerUser()) {
callback.onSuccess(this, ValidationResult.accessDenied(CUSTOMER_USER_IS_NOT_ALLOWED_TO_PERFORM_THIS_OPERATION));
} else if (ctx.isSystemAdmin()) {
callback.onSuccess(this, ValidationResult.ok(null));
} else {
ListenableFuture<Tenant> tenantFuture = pluginCtx.tenantService.findTenantByIdAsync(new TenantId(entityId.getId()));
Futures.addCallback(tenantFuture, getCallback(callback, tenant -> {
if (tenant == null) {
return ValidationResult.entityNotFound("Tenant with requested id wasn't found!");
} else if (!tenant.getId().equals(ctx.getTenantId())) {
return ValidationResult.accessDenied("Tenant doesn't relate to the currently authorized user!");
} else {
return ValidationResult.ok(null);
}
}));
}
}
@Override
public ListenableFuture<List<EntityRelation>> findByFromAndType(EntityId from, String relationType) {
return this.pluginCtx.relationService.findByFromAndTypeAsync(from, relationType, RelationTypeGroup.COMMON);
}
@Override
public ListenableFuture<List<EntityRelation>> findByToAndType(EntityId from, String relationType) {
return this.pluginCtx.relationService.findByToAndTypeAsync(from, relationType, RelationTypeGroup.COMMON);
}
@Override
public Optional<ServerAddress> resolve(EntityId entityId) {
return pluginCtx.routingService.resolveById(entityId);
}
@Override
public void getDevice(DeviceId deviceId, PluginCallback<Device> callback) {
ListenableFuture<Device> deviceFuture = pluginCtx.deviceService.findDeviceByIdAsync(deviceId);
Futures.addCallback(deviceFuture, getCallback(callback, v -> v));
}
@Override
public void getCustomerDevices(TenantId tenantId, CustomerId customerId, int limit, PluginCallback<List<Device>> callback) {
//TODO: add caching here with async api.
List<Device> devices = pluginCtx.deviceService.findDevicesByTenantIdAndCustomerId(tenantId, customerId, new TextPageLink(limit)).getData();
pluginCtx.self().tell(PluginCallbackMessage.onSuccess(callback, devices), ActorRef.noSender());
}
@Override
public void sendRpcRequest(ToDeviceRpcRequest msg) {
pluginCtx.sendRpcRequest(msg);
}
@Override
public void logRpcRequest(PluginApiCallSecurityContext ctx, DeviceId deviceId, ToDeviceRpcRequestBody body, boolean oneWay, Optional<RpcError> rpcError, Exception e) {
String rpcErrorStr = "";
if (rpcError.isPresent()) {
rpcErrorStr = "RPC Error: " + rpcError.get().name();
}
String method = body.getMethod();
String params = body.getParams();
pluginCtx.auditLogService.logEntityAction(
ctx.getTenantId(),
ctx.getCustomerId(),
ctx.getUserId(),
ctx.getUserName(),
deviceId,
null,
ActionType.RPC_CALL,
e,
rpcErrorStr,
new Boolean(oneWay),
method,
params);
}
@Override
public void scheduleTimeoutMsg(TimeoutMsg msg) {
pluginCtx.scheduleTimeoutMsg(msg);
}
private void convertFuturesAndAddCallback(PluginCallback<List<AttributeKvEntry>> callback, List<ListenableFuture<List<AttributeKvEntry>>> futures) {
ListenableFuture<List<AttributeKvEntry>> future = Futures.transform(Futures.successfulAsList(futures),
(Function<? super List<List<AttributeKvEntry>>, ? extends List<AttributeKvEntry>>) input -> {
List<AttributeKvEntry> result = new ArrayList<>();
input.forEach(r -> result.addAll(r));
return result;
}, executor);
Futures.addCallback(future, getCallback(callback, v -> v), executor);
}
}

30
application/src/main/java/org/thingsboard/server/actors/plugin/PluginTerminationMsg.java

@ -1,30 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.actors.plugin;
import org.thingsboard.server.actors.shared.ActorTerminationMsg;
import org.thingsboard.server.common.data.id.PluginId;
import org.thingsboard.server.common.data.id.SessionId;
/**
* @author Andrew Shvayka
*/
public class PluginTerminationMsg extends ActorTerminationMsg<PluginId> {
public PluginTerminationMsg(PluginId id) {
super(id);
}
}

66
application/src/main/java/org/thingsboard/server/actors/plugin/RuleToPluginMsgWrapper.java

@ -1,66 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.actors.plugin;
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.aware.RuleAwareMsg;
import org.thingsboard.server.extensions.api.plugins.msg.RuleToPluginMsg;
import org.thingsboard.server.extensions.api.plugins.msg.ToPluginActorMsg;
public class RuleToPluginMsgWrapper implements ToPluginActorMsg, RuleAwareMsg {
private final TenantId pluginTenantId;
private final PluginId pluginId;
private final TenantId ruleTenantId;
private final RuleId ruleId;
private final RuleToPluginMsg<?> msg;
public RuleToPluginMsgWrapper(TenantId pluginTenantId, PluginId pluginId, TenantId ruleTenantId, RuleId ruleId, RuleToPluginMsg<?> msg) {
super();
this.pluginTenantId = pluginTenantId;
this.pluginId = pluginId;
this.ruleTenantId = ruleTenantId;
this.ruleId = ruleId;
this.msg = msg;
}
@Override
public TenantId getPluginTenantId() {
return pluginTenantId;
}
@Override
public PluginId getPluginId() {
return pluginId;
}
public TenantId getRuleTenantId() {
return ruleTenantId;
}
@Override
public RuleId getRuleId() {
return ruleId;
}
public RuleToPluginMsg getMsg() {
return msg;
}
}

142
application/src/main/java/org/thingsboard/server/actors/plugin/SharedPluginProcessingContext.java

@ -1,142 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.actors.plugin;
import akka.actor.ActorRef;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.PluginId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
import org.thingsboard.server.common.msg.timeout.TimeoutMsg;
import org.thingsboard.server.controller.plugin.PluginWebSocketMsgEndpoint;
import org.thingsboard.server.dao.asset.AssetService;
import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.audit.AuditLogService;
import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.plugin.PluginService;
import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.rule.RuleService;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.dao.timeseries.TimeseriesService;
import org.thingsboard.server.extensions.api.device.DeviceAttributesEventNotificationMsg;
import org.thingsboard.server.service.cluster.routing.ClusterRoutingService;
import org.thingsboard.server.service.cluster.rpc.ClusterRpcService;
import scala.concurrent.duration.Duration;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
@Slf4j
public final class SharedPluginProcessingContext {
final ActorRef parentActor;
final ActorRef currentActor;
final ActorSystemContext systemContext;
final PluginWebSocketMsgEndpoint msgEndpoint;
final AssetService assetService;
final DeviceService deviceService;
final RuleService ruleService;
final RuleChainService ruleChainService;
final PluginService pluginService;
final CustomerService customerService;
final TenantService tenantService;
final TimeseriesService tsService;
final AttributesService attributesService;
final ClusterRpcService rpcService;
final ClusterRoutingService routingService;
final RelationService relationService;
final AuditLogService auditLogService;
final PluginId pluginId;
final TenantId tenantId;
public SharedPluginProcessingContext(ActorSystemContext sysContext, TenantId tenantId, PluginId pluginId,
ActorRef parentActor, ActorRef self) {
super();
this.tenantId = tenantId;
this.pluginId = pluginId;
this.parentActor = parentActor;
this.currentActor = self;
this.systemContext = sysContext;
this.msgEndpoint = sysContext.getWsMsgEndpoint();
this.tsService = sysContext.getTsService();
this.attributesService = sysContext.getAttributesService();
this.assetService = sysContext.getAssetService();
this.deviceService = sysContext.getDeviceService();
this.rpcService = sysContext.getRpcService();
this.routingService = sysContext.getRoutingService();
this.ruleService = sysContext.getRuleService();
this.ruleChainService = sysContext.getRuleChainService();
this.pluginService = sysContext.getPluginService();
this.customerService = sysContext.getCustomerService();
this.tenantService = sysContext.getTenantService();
this.relationService = sysContext.getRelationService();
this.auditLogService = sysContext.getAuditLogService();
}
public PluginId getPluginId() {
return pluginId;
}
public TenantId getPluginTenantId() {
return tenantId;
}
public void toDeviceActor(DeviceAttributesEventNotificationMsg msg) {
forward(msg.getDeviceId(), msg);
}
public void sendRpcRequest(ToDeviceRpcRequest msg) {
log.trace("[{}] Forwarding msg {} to device actor!", pluginId, msg);
// ToDeviceRpcRequestPluginMsg rpcMsg = new ToDeviceRpcRequestPluginMsg(pluginId, tenantId, msg);
// forward(msg.getDeviceId(), rpcMsg, rpcService::tell);
}
private <T extends TbActorMsg> void forward(DeviceId deviceId, T msg) {
Optional<ServerAddress> instance = routingService.resolveById(deviceId);
if (instance.isPresent()) {
log.trace("[{}] Forwarding msg {} to remote device actor!", pluginId, msg);
rpcService.tell(systemContext.getEncodingService().convertToProtoDataMessage(instance.get(), msg));
} else {
log.trace("[{}] Forwarding msg {} to local device actor!", pluginId, msg);
parentActor.tell(msg, ActorRef.noSender());
}
}
public void scheduleTimeoutMsg(TimeoutMsg msg) {
log.debug("Scheduling msg {} with delay {} ms", msg, msg.getTimeout());
systemContext.getScheduler().scheduleOnce(
Duration.create(msg.getTimeout(), TimeUnit.MILLISECONDS),
currentActor,
msg,
systemContext.getActorSystem().dispatcher(),
ActorRef.noSender());
}
public void persistError(String method, Exception e) {
systemContext.persistError(tenantId, pluginId, method, e);
}
public ActorRef self() {
return currentActor;
}
}

27
application/src/main/java/org/thingsboard/server/actors/plugin/TimeoutScheduler.java

@ -1,27 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.actors.plugin;
import akka.actor.ActorRef;
/**
* @author Andrew Shvayka
*/
public interface TimeoutScheduler {
void scheduleMsgWithDelay(Object msg, long delayInMs);
}

71
application/src/main/java/org/thingsboard/server/actors/plugin/ValidationCallback.java

@ -1,71 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.actors.plugin;
import java.util.function.Consumer;
import org.thingsboard.server.extensions.api.exception.AccessDeniedException;
import org.thingsboard.server.extensions.api.exception.EntityNotFoundException;
import org.thingsboard.server.extensions.api.exception.InternalErrorException;
import org.thingsboard.server.extensions.api.exception.UnauthorizedException;
import org.thingsboard.server.extensions.api.plugins.PluginCallback;
import org.thingsboard.server.extensions.api.plugins.PluginContext;
/**
* Created by ashvayka on 21.02.17.
*/
public class ValidationCallback implements PluginCallback<ValidationResult> {
private final PluginCallback<?> callback;
private final Consumer<PluginContext> action;
public ValidationCallback(PluginCallback<?> callback, Consumer<PluginContext> action) {
this.callback = callback;
this.action = action;
}
@Override
public void onSuccess(PluginContext ctx, ValidationResult result) {
ValidationResultCode resultCode = result.getResultCode();
if (resultCode == ValidationResultCode.OK) {
action.accept(ctx);
} else {
Exception e;
switch (resultCode) {
case ENTITY_NOT_FOUND:
e = new EntityNotFoundException(result.getMessage());
break;
case UNAUTHORIZED:
e = new UnauthorizedException(result.getMessage());
break;
case ACCESS_DENIED:
e = new AccessDeniedException(result.getMessage());
break;
case INTERNAL_ERROR:
e = new InternalErrorException(result.getMessage());
break;
default:
e = new UnauthorizedException("Permission denied.");
break;
}
onFailure(ctx, e);
}
}
@Override
public void onFailure(PluginContext ctx, Exception e) {
callback.onFailure(ctx, e);
}
}

6
application/src/main/java/org/thingsboard/server/actors/rpc/RpcManagerActor.java

@ -29,7 +29,11 @@ import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.gen.cluster.ClusterAPIProtos;
import org.thingsboard.server.service.cluster.discovery.ServerInstance;
import java.util.*;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.UUID;
/**
* @author Andrew Shvayka

1
application/src/main/java/org/thingsboard/server/actors/rpc/RpcSessionTellMsg.java

@ -16,7 +16,6 @@
package org.thingsboard.server.actors.rpc;
import lombok.Data;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.gen.cluster.ClusterAPIProtos;
/**

18
application/src/main/java/org/thingsboard/server/actors/ruleChain/DefaultTbContext.java

@ -17,8 +17,14 @@ package org.thingsboard.server.actors.ruleChain;
import akka.actor.ActorRef;
import com.datastax.driver.core.utils.UUIDs;
import com.google.common.base.Function;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.rule.engine.api.ListeningExecutor;
import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.rule.engine.api.RuleEngineDeviceRpcRequest;
import org.thingsboard.rule.engine.api.RuleEngineDeviceRpcResponse;
import org.thingsboard.rule.engine.api.RuleEngineRpcService;
import org.thingsboard.rule.engine.api.RuleEngineTelemetryService;
import org.thingsboard.rule.engine.api.ScriptEngine;
import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId;
@ -28,14 +34,12 @@ import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
import org.thingsboard.server.dao.alarm.AlarmService;
import org.thingsboard.server.dao.asset.AssetService;
import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.plugin.PluginService;
import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.timeseries.TimeseriesService;
@ -44,7 +48,6 @@ import org.thingsboard.server.service.script.NashornJsEngine;
import scala.concurrent.duration.Duration;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
@ -167,11 +170,6 @@ class DefaultTbContext implements TbContext {
return mainCtx.getUserService();
}
@Override
public PluginService getPluginService() {
return mainCtx.getPluginService();
}
@Override
public AssetService getAssetService() {
return mainCtx.getAssetService();

4
application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainManagerActor.java

@ -18,10 +18,8 @@ package org.thingsboard.server.actors.ruleChain;
import akka.actor.ActorRef;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.service.ContextAwareActor;
import org.thingsboard.server.actors.shared.plugin.PluginManager;
import org.thingsboard.server.actors.shared.rulechain.RuleChainManager;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.PluginId;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.dao.rule.RuleChainService;
@ -33,7 +31,7 @@ public abstract class RuleChainManagerActor extends ContextAwareActor {
protected final RuleChainManager ruleChainManager;
protected final RuleChainService ruleChainService;
public RuleChainManagerActor(ActorSystemContext systemContext, RuleChainManager ruleChainManager, PluginManager pluginManager) {
public RuleChainManagerActor(ActorSystemContext systemContext, RuleChainManager ruleChainManager) {
super(systemContext);
this.ruleChainManager = ruleChainManager;
this.ruleChainService = systemContext.getRuleChainService();

1
application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleChainToRuleChainMsg.java

@ -16,7 +16,6 @@
package org.thingsboard.server.actors.ruleChain;
import lombok.Data;
import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.msg.MsgType;
import org.thingsboard.server.common.msg.TbActorMsg;

3
application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeActorMessageProcessor.java

@ -21,7 +21,6 @@ import akka.event.LoggingAdapter;
import org.thingsboard.rule.engine.api.TbContext;
import org.thingsboard.rule.engine.api.TbNode;
import org.thingsboard.rule.engine.api.TbNodeConfiguration;
import org.thingsboard.rule.engine.api.TbNodeException;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.shared.ComponentMsgProcessor;
import org.thingsboard.server.common.data.id.RuleChainId;
@ -32,8 +31,6 @@ import org.thingsboard.server.common.data.rule.RuleNode;
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
import org.thingsboard.server.dao.rule.RuleChainService;
import java.util.concurrent.ExecutionException;
/**
* @author Andrew Shvayka
*/

1
application/src/main/java/org/thingsboard/server/actors/ruleChain/RuleNodeToSelfMsg.java

@ -16,7 +16,6 @@
package org.thingsboard.server.actors.ruleChain;
import lombok.Data;
import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.msg.MsgType;
import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.TbMsg;

7
application/src/main/java/org/thingsboard/server/actors/service/ActorService.java

@ -15,16 +15,17 @@
*/
package org.thingsboard.server.actors.service;
import org.thingsboard.server.common.data.id.*;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
import org.thingsboard.server.common.transport.SessionMsgProcessor;
import org.thingsboard.server.service.cluster.discovery.DiscoveryServiceListener;
import org.thingsboard.server.service.cluster.rpc.RpcMsgListener;
public interface ActorService extends SessionMsgProcessor, WebSocketMsgProcessor, RestMsgProcessor, RpcMsgListener, DiscoveryServiceListener {
public interface ActorService extends SessionMsgProcessor, RpcMsgListener, DiscoveryServiceListener {
void onEntityStateChange(TenantId tenantId, EntityId entityId, ComponentLifecycleEvent state);

3
application/src/main/java/org/thingsboard/server/actors/service/ContextBasedCreator.java

@ -15,9 +15,8 @@
*/
package org.thingsboard.server.actors.service;
import org.thingsboard.server.actors.ActorSystemContext;
import akka.japi.Creator;
import org.thingsboard.server.actors.ActorSystemContext;
public abstract class ContextBasedCreator<T> implements Creator<T> {

28
application/src/main/java/org/thingsboard/server/actors/service/DefaultActorService.java

@ -23,6 +23,8 @@ import com.google.protobuf.ByteString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thingsboard.rule.engine.api.msg.DeviceCredentialsUpdateNotificationMsg;
import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.app.AppActor;
import org.thingsboard.server.actors.rpc.RpcBroadcastMsg;
@ -30,7 +32,9 @@ import org.thingsboard.server.actors.rpc.RpcManagerActor;
import org.thingsboard.server.actors.rpc.RpcSessionCreateRequestMsg;
import org.thingsboard.server.actors.session.SessionManagerActor;
import org.thingsboard.server.actors.stats.StatsActor;
import org.thingsboard.server.common.data.id.*;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.aware.SessionAwareMsg;
@ -38,12 +42,8 @@ import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.cluster.ToAllNodesMsg;
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
import org.thingsboard.server.extensions.api.device.DeviceNameOrTypeUpdateMsg;
import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
import org.thingsboard.server.extensions.api.device.DeviceCredentialsUpdateNotificationMsg;
import org.thingsboard.server.extensions.api.plugins.rest.PluginRestMsg;
import org.thingsboard.server.extensions.api.plugins.ws.msg.PluginWebsocketMsg;
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
import org.thingsboard.server.gen.cluster.ClusterAPIProtos;
import org.thingsboard.server.service.cluster.discovery.DiscoveryService;
import org.thingsboard.server.service.cluster.discovery.ServerInstance;
@ -91,7 +91,7 @@ public class DefaultActorService implements ActorService {
@PostConstruct
public void initActorSystem() {
log.info("Initializing Actor system. {}", actorContext.getRuleService());
log.info("Initializing Actor system. {}", actorContext.getRuleChainService());
actorContext.setActorService(this);
system = ActorSystem.create(ACTOR_SYSTEM_NAME, actorContext.getConfig());
actorContext.setActorSystem(system);
@ -137,19 +137,6 @@ public class DefaultActorService implements ActorService {
sessionManagerActor.tell(msg, ActorRef.noSender());
}
@Override
public void process(PluginWebsocketMsg<?> msg) {
log.debug("Processing websocket msg: {}", msg);
appActor.tell(msg, ActorRef.noSender());
}
@Override
public void process(PluginRestMsg msg) {
log.debug("Processing rest msg: {}", msg);
appActor.tell(msg, ActorRef.noSender());
}
@Override
public void onServerAdded(ServerInstance server) {
log.trace("Processing onServerAdded msg: {}", server);
@ -263,4 +250,5 @@ public class DefaultActorService implements ActorService {
public void onBroadcastMsg(RpcBroadcastMsg msg) {
rpcManagerActor.tell(msg, ActorRef.noSender());
}
}

24
application/src/main/java/org/thingsboard/server/actors/service/RestMsgProcessor.java

@ -1,24 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.actors.service;
import org.thingsboard.server.extensions.api.plugins.rest.PluginRestMsg;
public interface RestMsgProcessor {
void process(PluginRestMsg msg);
}

24
application/src/main/java/org/thingsboard/server/actors/service/WebSocketMsgProcessor.java

@ -1,24 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.actors.service;
import org.thingsboard.server.extensions.api.plugins.ws.msg.PluginWebsocketMsg;
public interface WebSocketMsgProcessor {
void process(PluginWebsocketMsg<?> msg);
}

18
application/src/main/java/org/thingsboard/server/actors/session/ASyncMsgProcessor.java

@ -15,18 +15,26 @@
*/
package org.thingsboard.server.actors.session;
import akka.actor.ActorContext;
import akka.event.LoggingAdapter;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.shared.SessionTimeoutMsg;
import org.thingsboard.server.common.data.id.SessionId;
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.core.*;
import org.thingsboard.server.common.msg.core.AttributesSubscribeMsg;
import org.thingsboard.server.common.msg.core.ResponseMsg;
import org.thingsboard.server.common.msg.core.RpcSubscribeMsg;
import org.thingsboard.server.common.msg.core.SessionCloseMsg;
import org.thingsboard.server.common.msg.core.SessionOpenMsg;
import org.thingsboard.server.common.msg.device.DeviceToDeviceActorMsg;
import org.thingsboard.server.common.msg.session.*;
import akka.actor.ActorContext;
import akka.event.LoggingAdapter;
import org.thingsboard.server.common.msg.session.BasicSessionActorToAdaptorMsg;
import org.thingsboard.server.common.msg.session.FromDeviceMsg;
import org.thingsboard.server.common.msg.session.FromDeviceRequestMsg;
import org.thingsboard.server.common.msg.session.SessionMsgType;
import org.thingsboard.server.common.msg.session.SessionType;
import org.thingsboard.server.common.msg.session.ToDeviceMsg;
import org.thingsboard.server.common.msg.session.TransportToDeviceSessionActorMsg;
import org.thingsboard.server.common.msg.session.ex.SessionException;
import java.util.HashMap;

15
application/src/main/java/org/thingsboard/server/actors/session/AbstractSessionActorMsgProcessor.java

@ -15,6 +15,9 @@
*/
package org.thingsboard.server.actors.session;
import akka.actor.ActorContext;
import akka.actor.ActorRef;
import akka.event.LoggingAdapter;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.shared.AbstractContextAwareMsgProcessor;
import org.thingsboard.server.actors.shared.SessionTimeoutMsg;
@ -25,13 +28,15 @@ import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.device.BasicDeviceToDeviceActorMsg;
import org.thingsboard.server.common.msg.device.DeviceToDeviceActorMsg;
import org.thingsboard.server.common.msg.session.*;
import org.thingsboard.server.common.msg.session.AdaptorToSessionActorMsg;
import org.thingsboard.server.common.msg.session.FromDeviceMsg;
import org.thingsboard.server.common.msg.session.SessionContext;
import org.thingsboard.server.common.msg.session.SessionCtrlMsg;
import org.thingsboard.server.common.msg.session.SessionType;
import org.thingsboard.server.common.msg.session.ToDeviceMsg;
import org.thingsboard.server.common.msg.session.TransportToDeviceSessionActorMsg;
import org.thingsboard.server.common.msg.session.ctrl.SessionCloseMsg;
import akka.actor.ActorContext;
import akka.actor.ActorRef;
import akka.event.LoggingAdapter;
import java.util.Optional;
abstract class AbstractSessionActorMsgProcessor extends AbstractContextAwareMsgProcessor {

7
application/src/main/java/org/thingsboard/server/actors/session/SessionActor.java

@ -17,6 +17,8 @@ package org.thingsboard.server.actors.session;
import akka.actor.OneForOneStrategy;
import akka.actor.SupervisorStrategy;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.service.ContextAwareActor;
import org.thingsboard.server.actors.service.ContextBasedCreator;
@ -25,14 +27,11 @@ import org.thingsboard.server.common.data.id.SessionId;
import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
import org.thingsboard.server.common.msg.core.ActorSystemToDeviceSessionActorMsg;
import org.thingsboard.server.common.msg.session.TransportToDeviceSessionActorMsg;
import org.thingsboard.server.common.msg.session.SessionCtrlMsg;
import org.thingsboard.server.common.msg.session.SessionMsg;
import org.thingsboard.server.common.msg.session.SessionType;
import org.thingsboard.server.common.msg.session.TransportToDeviceSessionActorMsg;
import org.thingsboard.server.common.msg.session.ctrl.SessionCloseMsg;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import scala.concurrent.duration.Duration;
public class SessionActor extends ContextAwareActor {

20
application/src/main/java/org/thingsboard/server/actors/session/SessionManagerActor.java

@ -15,10 +15,13 @@
*/
package org.thingsboard.server.actors.session;
import java.util.HashMap;
import java.util.Map;
import akka.actor.*;
import akka.actor.ActorRef;
import akka.actor.InvalidActorNameException;
import akka.actor.LocalActorRef;
import akka.actor.Props;
import akka.actor.Terminated;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.service.ContextAwareActor;
import org.thingsboard.server.actors.service.ContextBasedCreator;
@ -27,14 +30,13 @@ import org.thingsboard.server.actors.shared.SessionTimeoutMsg;
import org.thingsboard.server.common.data.id.SessionId;
import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.aware.SessionAwareMsg;
import akka.event.Logging;
import akka.event.LoggingAdapter;
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
import org.thingsboard.server.common.msg.core.SessionCloseMsg;
import org.thingsboard.server.common.msg.core.ActorSystemToDeviceSessionActorMsg;
import org.thingsboard.server.common.msg.core.SessionCloseMsg;
import org.thingsboard.server.common.msg.session.SessionCtrlMsg;
import org.thingsboard.server.common.msg.session.TransportToDeviceSessionActorMsg;
import java.util.HashMap;
import java.util.Map;
public class SessionManagerActor extends ContextAwareActor {

10
application/src/main/java/org/thingsboard/server/actors/session/SyncMsgProcessor.java

@ -15,20 +15,22 @@
*/
package org.thingsboard.server.actors.session;
import akka.actor.ActorContext;
import akka.event.LoggingAdapter;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.shared.SessionTimeoutMsg;
import org.thingsboard.server.common.data.id.SessionId;
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.device.DeviceToDeviceActorMsg;
import org.thingsboard.server.common.msg.session.*;
import org.thingsboard.server.common.msg.session.BasicSessionActorToAdaptorMsg;
import org.thingsboard.server.common.msg.session.SessionContext;
import org.thingsboard.server.common.msg.session.SessionType;
import org.thingsboard.server.common.msg.session.ToDeviceMsg;
import org.thingsboard.server.common.msg.session.TransportToDeviceSessionActorMsg;
import org.thingsboard.server.common.msg.session.ctrl.SessionCloseMsg;
import org.thingsboard.server.common.msg.session.ex.SessionException;
import akka.actor.ActorContext;
import akka.event.LoggingAdapter;
import java.util.Optional;
class SyncMsgProcessor extends AbstractSessionActorMsgProcessor {

49
application/src/main/java/org/thingsboard/server/actors/shared/AbstractContextAwareMsgProcessor.java

@ -19,18 +19,13 @@ import akka.actor.ActorContext;
import akka.actor.ActorRef;
import akka.actor.Scheduler;
import akka.event.LoggingAdapter;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.extensions.api.component.*;
import scala.concurrent.ExecutionContextExecutor;
import scala.concurrent.duration.Duration;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
public abstract class AbstractContextAwareMsgProcessor {
@ -76,50 +71,6 @@ public abstract class AbstractContextAwareMsgProcessor {
getScheduler().scheduleOnce(Duration.create(delayInMs, TimeUnit.MILLISECONDS), target, msg, getSystemDispatcher(), null);
}
protected <T extends ConfigurableComponent> T initComponent(JsonNode componentNode) throws Exception {
ComponentConfiguration configuration = new ComponentConfiguration(
componentNode.get("clazz").asText(),
componentNode.get("name").asText(),
mapper.writeValueAsString(componentNode.get("configuration"))
);
logger.info("Initializing [{}][{}] component", configuration.getName(), configuration.getClazz());
ComponentDescriptor componentDescriptor = systemContext.getComponentService().getComponent(configuration.getClazz())
.orElseThrow(() -> new InstantiationException("Component Not found!"));
return initComponent(componentDescriptor, configuration);
}
protected <T extends ConfigurableComponent> T initComponent(ComponentDescriptor componentDefinition, ComponentConfiguration configuration)
throws Exception {
return initComponent(componentDefinition.getClazz(), componentDefinition.getType(), configuration.getConfiguration());
}
protected <T extends ConfigurableComponent> T initComponent(String clazz, ComponentType type, String configuration)
throws Exception {
Class<?> componentClazz = Class.forName(clazz);
T component = (T) (componentClazz.newInstance());
Class<?> configurationClazz;
switch (type) {
case FILTER:
configurationClazz = ((Filter) componentClazz.getAnnotation(Filter.class)).configuration();
break;
case ACTION:
configurationClazz = ((Action) componentClazz.getAnnotation(Action.class)).configuration();
break;
case PLUGIN:
configurationClazz = ((Plugin) componentClazz.getAnnotation(Plugin.class)).configuration();
break;
default:
throw new IllegalStateException("Component with type: " + type + " is not supported!");
}
component.init(decode(configuration, configurationClazz));
return component;
}
public <C> C decode(String configuration, Class<C> configurationClazz) throws IOException, RuntimeException {
logger.info("Initializing using configuration: {}", configuration);
return mapper.readValue(configuration, configurationClazz);
}
@Data
@AllArgsConstructor
private static class ComponentConfiguration {

1
application/src/main/java/org/thingsboard/server/actors/shared/ComponentMsgProcessor.java

@ -26,7 +26,6 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.cluster.ClusterEventMsg;
import org.thingsboard.server.dao.queue.MsgQueue;
import org.thingsboard.server.service.queue.MsgQueueService;
import javax.annotation.Nullable;

2
application/src/main/java/org/thingsboard/server/actors/shared/EntityActorsManager.java

@ -24,12 +24,10 @@ import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.service.ContextAwareActor;
import org.thingsboard.server.common.data.SearchTextBased;
import org.thingsboard.server.common.data.SearchTextBasedWithAdditionalInfo;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.data.page.PageDataIterable;
import org.thingsboard.server.common.data.plugin.PluginMetaData;
import java.util.HashMap;
import java.util.Map;

42
application/src/main/java/org/thingsboard/server/actors/shared/plugin/PluginManager.java

@ -1,42 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.actors.shared.plugin;
import akka.japi.Creator;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.plugin.PluginActor;
import org.thingsboard.server.actors.shared.EntityActorsManager;
import org.thingsboard.server.common.data.id.PluginId;
import org.thingsboard.server.common.data.plugin.PluginMetaData;
import org.thingsboard.server.dao.plugin.PluginService;
@Slf4j
public abstract class PluginManager extends EntityActorsManager<PluginId, PluginActor, PluginMetaData> {
protected final PluginService pluginService;
public PluginManager(ActorSystemContext systemContext) {
super(systemContext);
this.pluginService = systemContext.getPluginService();
}
@Override
public Creator<PluginActor> creator(PluginId entityId){
return new PluginActor.ActorCreator(systemContext, getTenantId(), entityId);
}
}

45
application/src/main/java/org/thingsboard/server/actors/shared/plugin/SystemPluginManager.java

@ -1,45 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.actors.shared.plugin;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.service.DefaultActorService;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageDataIterable.FetchFunction;
import org.thingsboard.server.common.data.plugin.PluginMetaData;
import org.thingsboard.server.dao.plugin.BasePluginService;
public class SystemPluginManager extends PluginManager {
public SystemPluginManager(ActorSystemContext systemContext) {
super(systemContext);
}
@Override
protected FetchFunction<PluginMetaData> getFetchEntitiesFunction() {
return pluginService::findSystemPlugins;
}
@Override
protected TenantId getTenantId() {
return BasePluginService.SYSTEM_TENANT;
}
@Override
protected String getDispatcherName() {
return DefaultActorService.SYSTEM_PLUGIN_DISPATCHER_NAME;
}
}

57
application/src/main/java/org/thingsboard/server/actors/shared/plugin/TenantPluginManager.java

@ -1,57 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.actors.shared.plugin;
import akka.actor.ActorContext;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.service.DefaultActorService;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageDataIterable;
import org.thingsboard.server.common.data.page.PageDataIterable.FetchFunction;
import org.thingsboard.server.common.data.plugin.PluginMetaData;
public class TenantPluginManager extends PluginManager {
private final TenantId tenantId;
public TenantPluginManager(ActorSystemContext systemContext, TenantId tenantId) {
super(systemContext);
this.tenantId = tenantId;
}
@Override
public void init(ActorContext context) {
if (systemContext.isTenantComponentsInitEnabled()) {
super.init(context);
}
}
@Override
protected FetchFunction<PluginMetaData> getFetchEntitiesFunction() {
return link -> pluginService.findTenantPlugins(tenantId, link);
}
@Override
protected TenantId getTenantId() {
return tenantId;
}
@Override
protected String getDispatcherName() {
return DefaultActorService.TENANT_PLUGIN_DISPATCHER_NAME;
}
}

7
application/src/main/java/org/thingsboard/server/actors/shared/rulechain/SystemRuleChainManager.java

@ -17,14 +17,11 @@ package org.thingsboard.server.actors.shared.rulechain;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.service.DefaultActorService;
import org.thingsboard.server.actors.shared.plugin.PluginManager;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageDataIterable.FetchFunction;
import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.plugin.PluginMetaData;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.dao.plugin.BasePluginService;
import org.thingsboard.server.dao.model.ModelConstants;
import java.util.Collections;
@ -41,7 +38,7 @@ public class SystemRuleChainManager extends RuleChainManager {
@Override
protected TenantId getTenantId() {
return BasePluginService.SYSTEM_TENANT;
return ModelConstants.SYSTEM_TENANT;
}
@Override

7
application/src/main/java/org/thingsboard/server/actors/tenant/TenantActor.java

@ -23,12 +23,10 @@ import akka.japi.Function;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.device.DeviceActor;
import org.thingsboard.server.actors.device.DeviceActorToRuleEngineMsg;
import org.thingsboard.server.actors.plugin.PluginTerminationMsg;
import org.thingsboard.server.actors.ruleChain.RuleChainManagerActor;
import org.thingsboard.server.actors.ruleChain.RuleChainToRuleChainMsg;
import org.thingsboard.server.actors.service.ContextBasedCreator;
import org.thingsboard.server.actors.service.DefaultActorService;
import org.thingsboard.server.actors.shared.plugin.TenantPluginManager;
import org.thingsboard.server.actors.shared.rulechain.TenantRuleChainManager;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.id.DeviceId;
@ -37,11 +35,8 @@ import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.aware.DeviceAwareMsg;
import org.thingsboard.server.common.msg.device.DeviceToDeviceActorMsg;
import org.thingsboard.server.common.msg.plugin.ComponentLifecycleMsg;
import org.thingsboard.server.common.msg.system.ServiceToRuleEngineMsg;
import org.thingsboard.server.extensions.api.device.ToDeviceActorNotificationMsg;
import org.thingsboard.server.extensions.api.plugins.msg.ToPluginActorMsg;
import scala.concurrent.duration.Duration;
import java.util.HashMap;
@ -53,7 +48,7 @@ public class TenantActor extends RuleChainManagerActor {
private final Map<DeviceId, ActorRef> deviceActors;
private TenantActor(ActorSystemContext systemContext, TenantId tenantId) {
super(systemContext, new TenantRuleChainManager(systemContext, tenantId), new TenantPluginManager(systemContext, tenantId));
super(systemContext, new TenantRuleChainManager(systemContext, tenantId));
this.tenantId = tenantId;
this.deviceActors = new HashMap<>();
}

2
application/src/main/java/org/thingsboard/server/config/AuditLogLevelProperties.java

@ -17,8 +17,6 @@ package org.thingsboard.server.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.audit.ActionType;
import java.util.HashMap;
import java.util.Map;

6
application/src/main/java/org/thingsboard/server/config/SwaggerConfiguration.java

@ -24,7 +24,11 @@ import org.springframework.context.annotation.Configuration;
import org.thingsboard.server.common.data.security.Authority;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.schema.AlternateTypeRule;
import springfox.documentation.service.*;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.AuthorizationScope;
import springfox.documentation.service.Contact;
import springfox.documentation.service.SecurityReference;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;

8
application/src/main/java/org/thingsboard/server/config/ThingsboardSecurityConfiguration.java

@ -40,10 +40,14 @@ import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.thingsboard.server.dao.audit.AuditLogLevelFilter;
import org.thingsboard.server.exception.ThingsboardErrorResponseHandler;
import org.thingsboard.server.service.security.auth.jwt.JwtAuthenticationProvider;
import org.thingsboard.server.service.security.auth.jwt.JwtTokenAuthenticationProcessingFilter;
import org.thingsboard.server.service.security.auth.jwt.RefreshTokenAuthenticationProvider;
import org.thingsboard.server.service.security.auth.jwt.RefreshTokenProcessingFilter;
import org.thingsboard.server.service.security.auth.jwt.SkipPathRequestMatcher;
import org.thingsboard.server.service.security.auth.jwt.extractor.TokenExtractor;
import org.thingsboard.server.service.security.auth.rest.RestAuthenticationProvider;
import org.thingsboard.server.service.security.auth.rest.RestLoginProcessingFilter;
import org.thingsboard.server.service.security.auth.jwt.*;
import org.thingsboard.server.service.security.auth.jwt.extractor.TokenExtractor;
import org.thingsboard.server.service.security.auth.rest.RestPublicLoginProcessingFilter;
import java.util.ArrayList;

12
application/src/main/java/org/thingsboard/server/config/WebSocketConfiguration.java

@ -15,12 +15,6 @@
*/
package org.thingsboard.server.config;
import java.util.Map;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.controller.plugin.TbWebSocketHandler;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
@ -35,6 +29,12 @@ import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry
import org.springframework.web.socket.server.HandshakeInterceptor;
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.controller.plugin.TbWebSocketHandler;
import org.thingsboard.server.service.security.model.SecurityUser;
import java.util.Map;
@Configuration
@EnableWebSocket

11
application/src/main/java/org/thingsboard/server/controller/AdminController.java

@ -17,11 +17,16 @@ package org.thingsboard.server.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.server.common.data.AdminSettings;
import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.service.update.UpdateService;
import org.thingsboard.server.service.update.model.UpdateMessage;

24
application/src/main/java/org/thingsboard/server/controller/AlarmController.java

@ -18,13 +18,27 @@ package org.thingsboard.server.controller;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.thingsboard.server.common.data.alarm.*;
import org.thingsboard.server.common.data.id.*;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmId;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.alarm.AlarmQuery;
import org.thingsboard.server.common.data.alarm.AlarmSearchStatus;
import org.thingsboard.server.common.data.alarm.AlarmSeverity;
import org.thingsboard.server.common.data.alarm.AlarmStatus;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
@RestController
@RequestMapping("/api")

15
application/src/main/java/org/thingsboard/server/controller/AssetController.java

@ -18,23 +18,30 @@ package org.thingsboard.server.controller;
import com.google.common.util.concurrent.ListenableFuture;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.asset.AssetSearchQuery;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.CustomerId;
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.asset.AssetSearchQuery;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.service.security.model.SecurityUser;
import java.util.ArrayList;

9
application/src/main/java/org/thingsboard/server/controller/AuditLogController.java

@ -16,15 +16,20 @@
package org.thingsboard.server.controller;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.audit.AuditLog;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import java.util.UUID;

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

@ -25,12 +25,18 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.service.security.auth.jwt.RefreshTokenRepository;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.model.UserPrincipal;

96
application/src/main/java/org/thingsboard/server/controller/BaseController.java

@ -22,20 +22,38 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.thingsboard.server.actors.service.ActorService;
import org.thingsboard.server.common.data.*;
import org.thingsboard.server.common.data.BaseData;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.DashboardInfo;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.HasName;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.alarm.Alarm;
import org.thingsboard.server.common.data.alarm.AlarmId;
import org.thingsboard.server.common.data.alarm.AlarmInfo;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.id.*;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.data.id.UserId;
import org.thingsboard.server.common.data.id.WidgetTypeId;
import org.thingsboard.server.common.data.id.WidgetsBundleId;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.plugin.PluginMetaData;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleMetaData;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.widget.WidgetType;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
@ -49,17 +67,13 @@ import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.exception.DataValidationException;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.plugin.PluginService;
import org.thingsboard.server.dao.relation.RelationService;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.rule.RuleService;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.dao.widget.WidgetTypeService;
import org.thingsboard.server.dao.widget.WidgetsBundleService;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.exception.ThingsboardErrorResponseHandler;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.service.component.ComponentDiscoveryService;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.state.DeviceStateService;
@ -116,12 +130,6 @@ public abstract class BaseController {
@Autowired
protected ComponentDiscoveryService componentDescriptorService;
@Autowired
protected RuleService ruleService;
@Autowired
protected PluginService pluginService;
@Autowired
protected RuleChainService ruleChainService;
@ -299,12 +307,6 @@ public abstract class BaseController {
case TENANT:
checkTenantId(new TenantId(entityId.getId()));
return;
case PLUGIN:
checkPlugin(new PluginId(entityId.getId()));
return;
case RULE:
checkRule(new RuleId(entityId.getId()));
return;
case RULE_CHAIN:
checkRuleChain(new RuleChainId(entityId.getId()));
return;
@ -494,60 +496,6 @@ public abstract class BaseController {
}
}
List<ComponentDescriptor> checkPluginActionsByPluginClazz(String pluginClazz) throws ThingsboardException {
try {
checkComponentDescriptorByClazz(pluginClazz);
log.debug("[{}] Lookup plugin actions", pluginClazz);
return componentDescriptorService.getPluginActions(pluginClazz);
} catch (Exception e) {
throw handleException(e, false);
}
}
protected PluginMetaData checkPlugin(PluginMetaData plugin) throws ThingsboardException {
checkNotNull(plugin);
SecurityUser authUser = getCurrentUser();
TenantId tenantId = plugin.getTenantId();
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,
ThingsboardErrorCode.PERMISSION_DENIED);
} else if (tenantId.getId().equals(ModelConstants.NULL_UUID)) {
plugin.setConfiguration(null);
}
}
return plugin;
}
protected PluginMetaData checkPlugin(PluginId pluginId) throws ThingsboardException {
checkNotNull(pluginId);
return checkPlugin(pluginService.findPluginById(pluginId));
}
protected RuleMetaData checkRule(RuleId ruleId) throws ThingsboardException {
checkNotNull(ruleId);
return checkRule(ruleService.findRuleById(ruleId));
}
protected RuleMetaData checkRule(RuleMetaData rule) throws ThingsboardException {
checkNotNull(rule);
SecurityUser authUser = getCurrentUser();
TenantId tenantId = rule.getTenantId();
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,
ThingsboardErrorCode.PERMISSION_DENIED);
}
}
return rule;
}
protected RuleChain checkRuleChain(RuleChainId ruleChainId) throws ThingsboardException {
checkNotNull(ruleChainId);
return checkRuleChain(ruleChainService.findRuleChainById(ruleChainId));

21
application/src/main/java/org/thingsboard/server/controller/ComponentDescriptorController.java

@ -16,10 +16,15 @@
package org.thingsboard.server.controller;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import java.util.HashSet;
import java.util.List;
@ -69,16 +74,4 @@ public class ComponentDescriptorController extends BaseController {
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN','TENANT_ADMIN')")
@RequestMapping(value = "/components/actions/{pluginClazz:.+}", method = RequestMethod.GET)
@ResponseBody
public List<ComponentDescriptor> getPluginActionsByPluginClazz(@PathVariable("pluginClazz") String pluginClazz) throws ThingsboardException {
checkParameter("pluginClazz", pluginClazz);
try {
return checkPluginActionsByPluginClazz(pluginClazz);
} catch (Exception e) {
throw handleException(e);
}
}
}

11
application/src/main/java/org/thingsboard/server/controller/CustomerController.java

@ -20,15 +20,22 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.CustomerId;
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.exception.ThingsboardException;
@RestController
@RequestMapping("/api")

17
application/src/main/java/org/thingsboard/server/controller/DashboardController.java

@ -17,9 +17,21 @@ package org.thingsboard.server.controller;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.thingsboard.server.common.data.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Dashboard;
import org.thingsboard.server.common.data.DashboardInfo;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.ShortCustomerInfo;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DashboardId;
import org.thingsboard.server.common.data.id.TenantId;
@ -27,7 +39,6 @@ import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import java.util.HashSet;
import java.util.Set;

13
application/src/main/java/org/thingsboard/server/controller/DeviceController.java

@ -18,13 +18,22 @@ package org.thingsboard.server.controller;
import com.google.common.util.concurrent.ListenableFuture;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.device.DeviceSearchQuery;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
@ -34,8 +43,6 @@ import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.dao.exception.IncorrectParameterException;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.service.security.model.SecurityUser;
import java.util.ArrayList;

14
application/src/main/java/org/thingsboard/server/controller/EntityRelationController.java

@ -17,15 +17,21 @@ package org.thingsboard.server.controller;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntityRelationInfo;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.relation.RelationTypeGroup;
import java.util.List;

14
application/src/main/java/org/thingsboard/server/controller/EventController.java

@ -17,15 +17,21 @@ package org.thingsboard.server.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.Event;
import org.thingsboard.server.common.data.id.*;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TimePageData;
import org.thingsboard.server.common.data.page.TimePageLink;
import org.thingsboard.server.dao.event.EventService;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
@RestController
@RequestMapping("/api")

240
application/src/main/java/org/thingsboard/server/controller/PluginController.java

@ -1,240 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.controller;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.id.PluginId;
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.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.plugin.PluginMetaData;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import java.util.List;
@RestController
@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(PLUGIN_ID) String strPluginId) throws ThingsboardException {
checkParameter(PLUGIN_ID, strPluginId);
try {
PluginId pluginId = new PluginId(toUUID(strPluginId));
return checkPlugin(pluginService.findPluginById(pluginId));
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/plugin/token/{pluginToken}", method = RequestMethod.GET)
@ResponseBody
public PluginMetaData getPluginByToken(@PathVariable("pluginToken") String pluginToken) throws ThingsboardException {
checkParameter("pluginToken", pluginToken);
try {
return checkPlugin(pluginService.findPluginByApiToken(pluginToken));
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/plugin", method = RequestMethod.POST)
@ResponseBody
public PluginMetaData savePlugin(@RequestBody PluginMetaData source) throws ThingsboardException {
try {
boolean created = source.getId() == null;
source.setTenantId(getCurrentUser().getTenantId());
PluginMetaData plugin = checkNotNull(pluginService.savePlugin(source));
actorService.onEntityStateChange(plugin.getTenantId(), plugin.getId(),
created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
logEntityAction(plugin.getId(), plugin,
null,
created ? ActionType.ADDED : ActionType.UPDATED, null);
return plugin;
} catch (Exception e) {
logEntityAction(emptyId(EntityType.PLUGIN), source,
null, source.getId() == null ? ActionType.ADDED : ActionType.UPDATED, e);
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/plugin/{pluginId}/activate", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
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));
pluginService.activatePluginById(pluginId);
actorService.onEntityStateChange(plugin.getTenantId(), plugin.getId(), ComponentLifecycleEvent.ACTIVATED);
logEntityAction(plugin.getId(), plugin,
null,
ActionType.ACTIVATED, null, strPluginId);
} catch (Exception e) {
logEntityAction(emptyId(EntityType.PLUGIN),
null,
null,
ActionType.ACTIVATED, e, strPluginId);
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/plugin/{pluginId}/suspend", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
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));
pluginService.suspendPluginById(pluginId);
actorService.onEntityStateChange(plugin.getTenantId(), plugin.getId(), ComponentLifecycleEvent.SUSPENDED);
logEntityAction(plugin.getId(), plugin,
null,
ActionType.SUSPENDED, null, strPluginId);
} catch (Exception e) {
logEntityAction(emptyId(EntityType.PLUGIN),
null,
null,
ActionType.SUSPENDED, e, strPluginId);
throw handleException(e);
}
}
@PreAuthorize("hasAuthority('SYS_ADMIN')")
@RequestMapping(value = "/plugin/system", params = {"limit"}, method = RequestMethod.GET)
@ResponseBody
public TextPageData<PluginMetaData> getSystemPlugins(
@RequestParam int limit,
@RequestParam(required = false) String textSearch,
@RequestParam(required = false) String idOffset,
@RequestParam(required = false) String textOffset) throws ThingsboardException {
try {
TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
return checkNotNull(pluginService.findSystemPlugins(pageLink));
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAuthority('SYS_ADMIN')")
@RequestMapping(value = "/plugin/tenant/{tenantId}", params = {"limit"}, method = RequestMethod.GET)
@ResponseBody
public TextPageData<PluginMetaData> getTenantPlugins(
@PathVariable("tenantId") String strTenantId,
@RequestParam int limit,
@RequestParam(required = false) String textSearch,
@RequestParam(required = false) String idOffset,
@RequestParam(required = false) String textOffset) throws ThingsboardException {
checkParameter("tenantId", strTenantId);
try {
TenantId tenantId = new TenantId(toUUID(strTenantId));
TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
return checkNotNull(pluginService.findTenantPlugins(tenantId, pageLink));
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/plugins", method = RequestMethod.GET)
@ResponseBody
public List<PluginMetaData> getPlugins() throws ThingsboardException {
try {
if (getCurrentUser().getAuthority() == Authority.SYS_ADMIN) {
return checkNotNull(pluginService.findSystemPlugins());
} else {
TenantId tenantId = getCurrentUser().getTenantId();
List<PluginMetaData> plugins = checkNotNull(pluginService.findAllTenantPluginsByTenantId(tenantId));
plugins.stream()
.filter(plugin -> plugin.getTenantId().getId().equals(ModelConstants.NULL_UUID))
.forEach(plugin -> plugin.setConfiguration(null));
return plugins;
}
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/plugin", params = {"limit"}, method = RequestMethod.GET)
@ResponseBody
public TextPageData<PluginMetaData> getTenantPlugins(
@RequestParam int limit,
@RequestParam(required = false) String textSearch,
@RequestParam(required = false) String idOffset,
@RequestParam(required = false) String textOffset) throws ThingsboardException {
try {
TenantId tenantId = getCurrentUser().getTenantId();
TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
return checkNotNull(pluginService.findTenantPlugins(tenantId, pageLink));
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/plugin/{pluginId}", method = RequestMethod.DELETE)
@ResponseStatus(value = HttpStatus.OK)
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));
pluginService.deletePluginById(pluginId);
actorService.onEntityStateChange(plugin.getTenantId(), plugin.getId(), ComponentLifecycleEvent.DELETED);
logEntityAction(pluginId, plugin,
null,
ActionType.DELETED, null, strPluginId);
} catch (Exception e) {
logEntityAction(emptyId(EntityType.PLUGIN),
null,
null,
ActionType.DELETED, e, strPluginId);
throw handleException(e);
}
}
}

18
application/src/main/java/org/thingsboard/server/controller/RpcController.java

@ -31,6 +31,7 @@ import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import org.thingsboard.rule.engine.api.RpcError;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
@ -41,14 +42,12 @@ import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.data.rpc.RpcRequest;
import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
import org.thingsboard.server.extensions.api.exception.ToErrorResponseEntity;
import org.thingsboard.server.extensions.api.plugins.PluginConstants;
import org.thingsboard.server.extensions.api.plugins.msg.FromDeviceRpcResponse;
import org.thingsboard.server.extensions.api.plugins.msg.RpcError;
import org.thingsboard.server.service.rpc.DeviceRpcService;
import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
import org.thingsboard.server.service.rpc.LocalRequestMetaData;
import org.thingsboard.server.service.security.AccessValidator;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.telemetry.exception.ToErrorResponseEntity;
import javax.annotation.Nullable;
import javax.annotation.PostConstruct;
@ -58,13 +57,12 @@ import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;
/**
* Created by ashvayka on 22.03.18.
*/
@RestController
@RequestMapping(PluginConstants.RPC_URL_PREFIX)
@RequestMapping(TbUrlConstants.RPC_URL_PREFIX)
@Slf4j
public class RpcController extends BaseController {
@ -130,13 +128,7 @@ public class RpcController extends BaseController {
timeout,
body
);
deviceRpcService.process(rpcRequest, new Consumer<FromDeviceRpcResponse>(){
@Override
public void accept(FromDeviceRpcResponse fromDeviceRpcResponse) {
reply(new LocalRequestMetaData(rpcRequest, currentUser, result), fromDeviceRpcResponse);
}
});
deviceRpcService.process(rpcRequest, fromDeviceRpcResponse -> reply(new LocalRequestMetaData(rpcRequest, currentUser, result), fromDeviceRpcResponse));
}
@Override

13
application/src/main/java/org/thingsboard/server/controller/RuleChainController.java

@ -25,12 +25,20 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.rule.engine.api.ScriptEngine;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.Event;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.id.RuleNodeId;
import org.thingsboard.server.common.data.id.TenantId;
@ -39,12 +47,9 @@ import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.rule.RuleChainMetaData;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.msg.TbMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.dao.event.EventService;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.service.script.NashornJsEngine;
import java.util.List;

239
application/src/main/java/org/thingsboard/server/controller/RuleController.java

@ -1,239 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.controller;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.id.RuleId;
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.plugin.ComponentLifecycleEvent;
import org.thingsboard.server.common.data.plugin.PluginMetaData;
import org.thingsboard.server.common.data.rule.RuleMetaData;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import java.util.List;
@RestController
@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(RULE_ID) String strRuleId) throws ThingsboardException {
checkParameter(RULE_ID, strRuleId);
try {
RuleId ruleId = new RuleId(toUUID(strRuleId));
return checkRule(ruleService.findRuleById(ruleId));
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/rule/token/{pluginToken}", method = RequestMethod.GET)
@ResponseBody
public List<RuleMetaData> getRulesByPluginToken(@PathVariable("pluginToken") String pluginToken) throws ThingsboardException {
checkParameter("pluginToken", pluginToken);
try {
PluginMetaData plugin = checkPlugin(pluginService.findPluginByApiToken(pluginToken));
return ruleService.findPluginRules(plugin.getApiToken());
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/rule", method = RequestMethod.POST)
@ResponseBody
public RuleMetaData saveRule(@RequestBody RuleMetaData source) throws ThingsboardException {
try {
boolean created = source.getId() == null;
source.setTenantId(getCurrentUser().getTenantId());
RuleMetaData rule = checkNotNull(ruleService.saveRule(source));
actorService.onEntityStateChange(rule.getTenantId(), rule.getId(),
created ? ComponentLifecycleEvent.CREATED : ComponentLifecycleEvent.UPDATED);
logEntityAction(rule.getId(), rule,
null,
created ? ActionType.ADDED : ActionType.UPDATED, null);
return rule;
} catch (Exception e) {
logEntityAction(emptyId(EntityType.RULE), source,
null, source.getId() == null ? ActionType.ADDED : ActionType.UPDATED, e);
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/rule/{ruleId}/activate", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
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));
ruleService.activateRuleById(ruleId);
actorService.onEntityStateChange(rule.getTenantId(), rule.getId(), ComponentLifecycleEvent.ACTIVATED);
logEntityAction(rule.getId(), rule,
null,
ActionType.ACTIVATED, null, strRuleId);
} catch (Exception e) {
logEntityAction(emptyId(EntityType.RULE),
null,
null,
ActionType.ACTIVATED, e, strRuleId);
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/rule/{ruleId}/suspend", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
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));
ruleService.suspendRuleById(ruleId);
actorService.onEntityStateChange(rule.getTenantId(), rule.getId(), ComponentLifecycleEvent.SUSPENDED);
logEntityAction(rule.getId(), rule,
null,
ActionType.SUSPENDED, null, strRuleId);
} catch (Exception e) {
logEntityAction(emptyId(EntityType.RULE),
null,
null,
ActionType.SUSPENDED, e, strRuleId);
throw handleException(e);
}
}
@PreAuthorize("hasAuthority('SYS_ADMIN')")
@RequestMapping(value = "/rule/system", params = {"limit"}, method = RequestMethod.GET)
@ResponseBody
public TextPageData<RuleMetaData> getSystemRules(
@RequestParam int limit,
@RequestParam(required = false) String textSearch,
@RequestParam(required = false) String idOffset,
@RequestParam(required = false) String textOffset) throws ThingsboardException {
try {
TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
return checkNotNull(ruleService.findSystemRules(pageLink));
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAuthority('SYS_ADMIN')")
@RequestMapping(value = "/rule/tenant/{tenantId}", params = {"limit"}, method = RequestMethod.GET)
@ResponseBody
public TextPageData<RuleMetaData> getTenantRules(
@PathVariable("tenantId") String strTenantId,
@RequestParam int limit,
@RequestParam(required = false) String textSearch,
@RequestParam(required = false) String idOffset,
@RequestParam(required = false) String textOffset) throws ThingsboardException {
checkParameter("tenantId", strTenantId);
try {
TenantId tenantId = new TenantId(toUUID(strTenantId));
TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
return checkNotNull(ruleService.findTenantRules(tenantId, pageLink));
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/rules", method = RequestMethod.GET)
@ResponseBody
public List<RuleMetaData> getRules() throws ThingsboardException {
try {
if (getCurrentUser().getAuthority() == Authority.SYS_ADMIN) {
return checkNotNull(ruleService.findSystemRules());
} else {
TenantId tenantId = getCurrentUser().getTenantId();
return checkNotNull(ruleService.findAllTenantRulesByTenantId(tenantId));
}
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/rule", params = {"limit"}, method = RequestMethod.GET)
@ResponseBody
public TextPageData<RuleMetaData> getTenantRules(
@RequestParam int limit,
@RequestParam(required = false) String textSearch,
@RequestParam(required = false) String idOffset,
@RequestParam(required = false) String textOffset) throws ThingsboardException {
try {
TenantId tenantId = getCurrentUser().getTenantId();
TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
return checkNotNull(ruleService.findTenantRules(tenantId, pageLink));
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
@RequestMapping(value = "/rule/{ruleId}", method = RequestMethod.DELETE)
@ResponseStatus(value = HttpStatus.OK)
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));
ruleService.deleteRuleById(ruleId);
actorService.onEntityStateChange(rule.getTenantId(), rule.getId(), ComponentLifecycleEvent.DELETED);
logEntityAction(ruleId, rule,
null,
ActionType.DELETED, null, strRuleId);
} catch (Exception e) {
logEntityAction(emptyId(EntityType.RULE),
null,
null,
ActionType.DELETED, e, strRuleId);
throw handleException(e);
}
}
}

7
extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/PluginConstants.java → application/src/main/java/org/thingsboard/server/controller/TbUrlConstants.java

@ -13,13 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.extensions.api.plugins;
package org.thingsboard.server.controller;
/**
* @author Andrew Shvayka
* Created by ashvayka on 17.05.18.
*/
public class PluginConstants {
public class TbUrlConstants {
public static final String TELEMETRY_URL_PREFIX = "/api/plugins/telemetry";
public static final String RPC_URL_PREFIX = "/api/plugins/rpc";
public static final String PLUGIN_URL_PREFIX = "/api/plugins";
}

13
application/src/main/java/org/thingsboard/server/controller/TelemetryController.java

@ -39,6 +39,7 @@ import org.springframework.web.context.request.async.DeferredResult;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.UUIDBased;
@ -58,15 +59,13 @@ import org.thingsboard.server.common.msg.core.TelemetryUploadRequest;
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
import org.thingsboard.server.dao.attributes.AttributesService;
import org.thingsboard.server.dao.timeseries.TimeseriesService;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.extensions.api.exception.InvalidParametersException;
import org.thingsboard.server.extensions.api.exception.UncheckedApiException;
import org.thingsboard.server.extensions.api.plugins.PluginConstants;
import org.thingsboard.server.extensions.core.plugin.telemetry.AttributeData;
import org.thingsboard.server.extensions.core.plugin.telemetry.TsData;
import org.thingsboard.server.service.security.AccessValidator;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.telemetry.AttributeData;
import org.thingsboard.server.service.telemetry.TelemetrySubscriptionService;
import org.thingsboard.server.service.telemetry.TsData;
import org.thingsboard.server.service.telemetry.exception.InvalidParametersException;
import org.thingsboard.server.service.telemetry.exception.UncheckedApiException;
import javax.annotation.Nullable;
import javax.annotation.PostConstruct;
@ -84,7 +83,7 @@ import java.util.stream.Collectors;
* Created by ashvayka on 22.03.18.
*/
@RestController
@RequestMapping(PluginConstants.TELEMETRY_URL_PREFIX)
@RequestMapping(TbUrlConstants.TELEMETRY_URL_PREFIX)
@Slf4j
public class TelemetryController extends BaseController {

15
application/src/main/java/org/thingsboard/server/controller/UserController.java

@ -18,10 +18,20 @@ package org.thingsboard.server.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UserId;
@ -29,9 +39,6 @@ import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.common.data.exception.ThingsboardErrorCode;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.rule.engine.api.MailService;
import org.thingsboard.server.service.security.model.SecurityUser;
import javax.servlet.http.HttpServletRequest;

11
application/src/main/java/org/thingsboard/server/controller/WidgetTypeController.java

@ -17,13 +17,20 @@ package org.thingsboard.server.controller;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetTypeId;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.widget.WidgetType;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import java.util.List;

11
application/src/main/java/org/thingsboard/server/controller/WidgetsBundleController.java

@ -17,7 +17,15 @@ package org.thingsboard.server.controller;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.WidgetsBundleId;
import org.thingsboard.server.common.data.page.TextPageData;
@ -25,7 +33,6 @@ import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import java.util.List;

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

@ -1,85 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.controller.plugin;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.thingsboard.server.controller.BaseController;
import org.thingsboard.server.extensions.api.plugins.PluginConstants;
@RestController
@RequestMapping(PluginConstants.PLUGIN_URL_PREFIX)
@Slf4j
public class PluginApiController extends BaseController {
// @SuppressWarnings("rawtypes")
// @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
// @RequestMapping(value = "/{pluginToken}/**")
// @ResponseStatus(value = HttpStatus.OK)
// public DeferredResult<ResponseEntity> processRequest(
// @PathVariable("pluginToken") String pluginToken,
// RequestEntity<byte[]> requestEntity,
// HttpServletRequest request)
// throws ThingsboardException {
// log.debug("[{}] Going to process requst uri: {}", pluginToken, requestEntity.getUrl());
// DeferredResult<ResponseEntity> result = new DeferredResult<ResponseEntity>();
// PluginMetaData pluginMd = pluginService.findPluginByApiToken(pluginToken);
// if (pluginMd == null) {
// result.setErrorResult(new PluginNotFoundException("Plugin with token: " + pluginToken + " not found!"));
// } else {
// TenantId tenantId = getCurrentUser().getTenantId();
// CustomerId customerId = getCurrentUser().getCustomerId();
// if (validatePluginAccess(pluginMd, tenantId, customerId)) {
// if(tenantId != null && ModelConstants.NULL_UUID.equals(tenantId.getId())){
// tenantId = null;
// }
// UserId userId = getCurrentUser().getId();
// String userName = getCurrentUser().getName();
// PluginApiCallSecurityContext securityCtx = new PluginApiCallSecurityContext(pluginMd.getTenantId(), pluginMd.getId(),
// tenantId, customerId, userId, userName);
// actorService.process(new BasicPluginRestMsg(securityCtx, new RestRequest(requestEntity, request), result));
// } else {
// result.setResult(new ResponseEntity<>(HttpStatus.FORBIDDEN));
// }
//
// }
// return result;
// }
//
// public static boolean validatePluginAccess(PluginMetaData pluginMd, TenantId tenantId, CustomerId customerId) {
// boolean systemAdministrator = tenantId == null || ModelConstants.NULL_UUID.equals(tenantId.getId());
// boolean tenantAdministrator = !systemAdministrator && (customerId == null || ModelConstants.NULL_UUID.equals(customerId.getId()));
// boolean systemPlugin = ModelConstants.NULL_UUID.equals(pluginMd.getTenantId().getId());
//
// boolean validUser = false;
// if (systemPlugin) {
// if (pluginMd.isPublicAccess() || systemAdministrator) {
// // All users can access public system plugins. Only system
// // users can access private system plugins
// validUser = true;
// }
// } else {
// 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;
// }
// }
// return validUser;
// }
}

30
application/src/main/java/org/thingsboard/server/controller/plugin/PluginNotFoundException.java

@ -1,30 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.controller.plugin;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(HttpStatus.NOT_FOUND)
public class PluginNotFoundException extends RuntimeException {
private static final long serialVersionUID = 1L;
public PluginNotFoundException(String message){
super(message);
}
}

28
application/src/main/java/org/thingsboard/server/controller/plugin/PluginWebSocketMsgEndpoint.java

@ -1,28 +0,0 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.controller.plugin;
import java.io.IOException;
import org.thingsboard.server.extensions.api.plugins.ws.PluginWebsocketSessionRef;
import org.thingsboard.server.extensions.api.plugins.ws.msg.PluginWebsocketMsg;
public interface PluginWebSocketMsgEndpoint {
void send(PluginWebsocketMsg<?> wsMsg) throws IOException;
void close(PluginWebsocketSessionRef sessionRef) throws IOException;
}

46
application/src/main/java/org/thingsboard/server/controller/plugin/TbWebSocketHandler.java

@ -25,11 +25,8 @@ import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import org.thingsboard.server.config.WebSocketConfiguration;
import org.thingsboard.server.extensions.api.plugins.ws.PluginWebsocketSessionRef;
import org.thingsboard.server.extensions.api.plugins.ws.SessionEvent;
import org.thingsboard.server.extensions.api.plugins.ws.msg.PluginWebsocketMsg;
import org.thingsboard.server.extensions.api.plugins.ws.msg.TextPluginWebSocketMsg;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.telemetry.SessionEvent;
import org.thingsboard.server.service.telemetry.TelemetryWebSocketMsgEndpoint;
import org.thingsboard.server.service.telemetry.TelemetryWebSocketService;
import org.thingsboard.server.service.telemetry.TelemetryWebSocketSessionRef;
@ -43,7 +40,7 @@ import java.util.concurrent.ConcurrentMap;
@Service
@Slf4j
public class TbWebSocketHandler extends TextWebSocketHandler implements PluginWebSocketMsgEndpoint, TelemetryWebSocketMsgEndpoint {
public class TbWebSocketHandler extends TextWebSocketHandler implements TelemetryWebSocketMsgEndpoint {
private static final ConcurrentMap<String, SessionMetaData> internalSessionMap = new ConcurrentHashMap<>();
private static final ConcurrentMap<String, String> externalSessionMap = new ConcurrentHashMap<>();
@ -183,43 +180,4 @@ public class TbWebSocketHandler extends TextWebSocketHandler implements PluginWe
}
}
//TODO: remove
@Override
public void send(PluginWebsocketMsg<?> wsMsg) throws IOException {
PluginWebsocketSessionRef sessionRef = wsMsg.getSessionRef();
String externalId = sessionRef.getSessionId();
log.debug("[{}] Processing {}", externalId, wsMsg);
String internalId = externalSessionMap.get(externalId);
if (internalId != null) {
SessionMetaData sessionMd = internalSessionMap.get(internalId);
if (sessionMd != null) {
if (wsMsg instanceof TextPluginWebSocketMsg) {
String payload = ((TextPluginWebSocketMsg) wsMsg).getPayload();
sessionMd.session.sendMessage(new TextMessage(payload));
}
} else {
log.warn("[{}][{}] Failed to find session by internal id", externalId, internalId);
}
} else {
log.warn("[{}] Failed to find session by external id", externalId);
}
}
//TODO: remove
@Override
public void close(PluginWebsocketSessionRef sessionRef) throws IOException {
String externalId = sessionRef.getSessionId();
log.debug("[{}] Processing close request", externalId);
String internalId = externalSessionMap.get(externalId);
if (internalId != null) {
SessionMetaData sessionMd = internalSessionMap.get(internalId);
if (sessionMd != null) {
sessionMd.session.close(CloseStatus.NORMAL);
} else {
log.warn("[{}][{}] Failed to find session by internal id", externalId, internalId);
}
} else {
log.warn("[{}] Failed to find session by external id", externalId);
}
}
}

7
application/src/main/java/org/thingsboard/server/install/ThingsboardInstallService.java

@ -23,9 +23,10 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import org.thingsboard.server.service.component.ComponentDiscoveryService;
import org.thingsboard.server.service.install.*;
import java.nio.file.Paths;
import org.thingsboard.server.service.install.DataUpdateService;
import org.thingsboard.server.service.install.DatabaseSchemaService;
import org.thingsboard.server.service.install.DatabaseUpgradeService;
import org.thingsboard.server.service.install.SystemDataLoaderService;
@Service
@Profile("install")

1
application/src/main/java/org/thingsboard/server/service/cluster/discovery/DummyDiscoveryService.java

@ -20,7 +20,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;
import org.thingsboard.server.service.environment.EnvironmentLogService;
import javax.annotation.PostConstruct;
import java.util.Collections;

1
application/src/main/java/org/thingsboard/server/service/cluster/discovery/ServerInstance.java

@ -15,7 +15,6 @@
*/
package org.thingsboard.server.service.cluster.discovery;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;

2
application/src/main/java/org/thingsboard/server/service/cluster/routing/ClusterRoutingService.java

@ -16,9 +16,7 @@
package org.thingsboard.server.service.cluster.routing;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.service.cluster.discovery.ServerInstance;
import java.util.Optional;
import java.util.UUID;

1
application/src/main/java/org/thingsboard/server/service/cluster/routing/ConsistentClusterRoutingService.java

@ -23,7 +23,6 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.service.cluster.discovery.DiscoveryService;
import org.thingsboard.server.service.cluster.discovery.DiscoveryServiceListener;

2
application/src/main/java/org/thingsboard/server/service/cluster/rpc/ClusterGrpcService.java

@ -26,9 +26,7 @@ import org.thingsboard.server.actors.rpc.RpcBroadcastMsg;
import org.thingsboard.server.actors.rpc.RpcSessionCreateRequestMsg;
import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.gen.cluster.ClusterAPIProtos;
import org.thingsboard.server.gen.cluster.ClusterRpcServiceGrpc;
import org.thingsboard.server.service.cluster.discovery.ServerInstance;
import org.thingsboard.server.service.cluster.discovery.ServerInstanceService;

74
application/src/main/java/org/thingsboard/server/service/component/AnnotationComponentDiscoveryService.java

@ -15,11 +15,9 @@
*/
package org.thingsboard.server.service.component;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.base.Charsets;
import com.google.common.io.Resources;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@ -28,17 +26,24 @@ import org.springframework.context.annotation.ClassPathScanningCandidateComponen
import org.springframework.core.env.Environment;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.stereotype.Service;
import org.thingsboard.rule.engine.api.*;
import org.thingsboard.rule.engine.api.NodeConfiguration;
import org.thingsboard.rule.engine.api.NodeDefinition;
import org.thingsboard.rule.engine.api.RuleNode;
import org.thingsboard.server.common.data.plugin.ComponentDescriptor;
import org.thingsboard.server.common.data.plugin.ComponentType;
import org.thingsboard.server.dao.component.ComponentDescriptorService;
import org.thingsboard.server.extensions.api.component.*;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.*;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
@Service
@Slf4j
@ -112,7 +117,6 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
try {
scannedComponent.setType(type);
Class<?> clazz = Class.forName(clazzName);
String descriptorResourceName;
switch (type) {
case ENRICHMENT:
case FILTER:
@ -128,34 +132,6 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
configurationDescriptor.set("nodeDefinition", node);
scannedComponent.setConfigurationDescriptor(configurationDescriptor);
break;
case OLD_ACTION:
Action oldActionAnnotation = clazz.getAnnotation(Action.class);
scannedComponent.setName(oldActionAnnotation.name());
scannedComponent.setScope(oldActionAnnotation.scope());
descriptorResourceName = oldActionAnnotation.descriptor();
scannedComponent.setConfigurationDescriptor(mapper.readTree(
Resources.toString(Resources.getResource(descriptorResourceName), Charsets.UTF_8)));
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.OLD_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(Class::getName).collect(Collectors.joining(",")));
scannedComponent.setConfigurationDescriptor(mapper.readTree(
Resources.toString(Resources.getResource(descriptorResourceName), Charsets.UTF_8)));
break;
default:
throw new RuntimeException(type + " is not supported yet!");
}
@ -212,13 +188,7 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
@Override
public void discoverComponents() {
registerRuleNodeComponents();
registerComponents(ComponentType.OLD_ACTION, Action.class);
registerComponents(ComponentType.PLUGIN, Plugin.class);
log.info("Found following definitions: {}", components.values());
}
@ -244,22 +214,4 @@ public class AnnotationComponentDiscoveryService implements ComponentDiscoverySe
public Optional<ComponentDescriptor> getComponent(String clazz) {
return Optional.ofNullable(components.get(clazz));
}
@Override
public List<ComponentDescriptor> getPluginActions(String pluginClazz) {
Optional<ComponentDescriptor> pluginOpt = getComponent(pluginClazz);
if (pluginOpt.isPresent()) {
ComponentDescriptor plugin = pluginOpt.get();
if (ComponentType.PLUGIN != plugin.getType()) {
throw new IllegalArgumentException(pluginClazz + " is not a plugin!");
}
List<ComponentDescriptor> result = new ArrayList<>();
for (String action : plugin.getActions().split(",")) {
getComponent(action).ifPresent(result::add);
}
return result;
} else {
throw new IllegalArgumentException(pluginClazz + " is not a component!");
}
}
}

2
application/src/main/java/org/thingsboard/server/service/component/ComponentDiscoveryService.java

@ -35,6 +35,4 @@ public interface ComponentDiscoveryService {
Optional<ComponentDescriptor> getComponent(String clazz);
List<ComponentDescriptor> getPluginActions(String pluginClazz);
}

1
application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseSchemaService.java

@ -17,7 +17,6 @@ package org.thingsboard.server.service.install;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import org.thingsboard.server.dao.cassandra.CassandraInstallCluster;

13
application/src/main/java/org/thingsboard/server/service/install/CassandraDatabaseUpgradeService.java

@ -18,7 +18,6 @@ package org.thingsboard.server.service.install;
import com.datastax.driver.core.KeyspaceMetadata;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import org.thingsboard.server.dao.cassandra.CassandraCluster;
@ -33,7 +32,17 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import static org.thingsboard.server.service.install.DatabaseHelper.*;
import static org.thingsboard.server.service.install.DatabaseHelper.ADDITIONAL_INFO;
import static org.thingsboard.server.service.install.DatabaseHelper.ASSET;
import static org.thingsboard.server.service.install.DatabaseHelper.ASSIGNED_CUSTOMERS;
import static org.thingsboard.server.service.install.DatabaseHelper.CONFIGURATION;
import static org.thingsboard.server.service.install.DatabaseHelper.CUSTOMER_ID;
import static org.thingsboard.server.service.install.DatabaseHelper.DASHBOARD;
import static org.thingsboard.server.service.install.DatabaseHelper.DEVICE;
import static org.thingsboard.server.service.install.DatabaseHelper.ID;
import static org.thingsboard.server.service.install.DatabaseHelper.SEARCH_TEXT;
import static org.thingsboard.server.service.install.DatabaseHelper.TENANT_ID;
import static org.thingsboard.server.service.install.DatabaseHelper.TITLE;
@Service
@NoSqlDao

6
application/src/main/java/org/thingsboard/server/service/install/DatabaseHelper.java

@ -30,7 +30,11 @@ import org.thingsboard.server.dao.dashboard.DashboardService;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
* Created by igor on 2/27/18.

22
application/src/main/java/org/thingsboard/server/service/install/DefaultSystemDataLoaderService.java

@ -15,46 +15,34 @@
*/
package org.thingsboard.server.service.install;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.*;
import org.thingsboard.server.common.data.AdminSettings;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.User;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.plugin.ComponentLifecycleState;
import org.thingsboard.server.common.data.plugin.PluginMetaData;
import org.thingsboard.server.common.data.rule.RuleMetaData;
import org.thingsboard.server.common.data.security.Authority;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.UserCredentials;
import org.thingsboard.server.common.data.widget.WidgetType;
import org.thingsboard.server.common.data.widget.WidgetsBundle;
import org.thingsboard.server.dao.customer.CustomerService;
import org.thingsboard.server.dao.dashboard.DashboardService;
import org.thingsboard.server.dao.device.DeviceCredentialsService;
import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.plugin.PluginService;
import org.thingsboard.server.dao.rule.RuleService;
import org.thingsboard.server.dao.settings.AdminSettingsService;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.dao.user.UserService;
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;
@Service
@Profile("install")
@Slf4j

1
application/src/main/java/org/thingsboard/server/service/install/InstallScripts.java

@ -16,7 +16,6 @@
package org.thingsboard.server.service.install;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

1
application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseSchemaService.java

@ -28,7 +28,6 @@ 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")

10
application/src/main/java/org/thingsboard/server/service/install/SqlDatabaseUpgradeService.java

@ -22,7 +22,6 @@ import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import org.thingsboard.server.dao.dashboard.DashboardService;
import org.thingsboard.server.dao.util.SqlDao;
import org.thingsboard.server.service.install.cql.CassandraDbHelper;
import org.thingsboard.server.service.install.sql.SqlDbHelper;
import java.nio.charset.Charset;
@ -30,11 +29,16 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import static org.thingsboard.server.service.install.DatabaseHelper.*;
import static org.thingsboard.server.service.install.DatabaseHelper.ASSIGNED_CUSTOMERS;
import static org.thingsboard.server.service.install.DatabaseHelper.CONFIGURATION;
import static org.thingsboard.server.service.install.DatabaseHelper.CUSTOMER_ID;
import static org.thingsboard.server.service.install.DatabaseHelper.DASHBOARD;
import static org.thingsboard.server.service.install.DatabaseHelper.ID;
import static org.thingsboard.server.service.install.DatabaseHelper.SEARCH_TEXT;
import static org.thingsboard.server.service.install.DatabaseHelper.TENANT_ID;
import static org.thingsboard.server.service.install.DatabaseHelper.TITLE;
@Service
@Profile("install")

17
application/src/main/java/org/thingsboard/server/service/install/cql/CassandraDbHelper.java

@ -15,7 +15,16 @@
*/
package org.thingsboard.server.service.install.cql;
import com.datastax.driver.core.*;
import com.datastax.driver.core.BoundStatement;
import com.datastax.driver.core.DataType;
import com.datastax.driver.core.KeyspaceMetadata;
import com.datastax.driver.core.PreparedStatement;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Row;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.SimpleStatement;
import com.datastax.driver.core.Statement;
import com.datastax.driver.core.TableMetadata;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVPrinter;
@ -25,7 +34,11 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import static org.thingsboard.server.service.install.DatabaseHelper.CSV_DUMP_FORMAT;

7
application/src/main/java/org/thingsboard/server/service/install/sql/SqlDbHelper.java

@ -23,7 +23,12 @@ import org.apache.commons.csv.CSVRecord;
import java.nio.file.Files;
import java.nio.file.Path;
import java.sql.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

21
application/src/main/java/org/thingsboard/server/service/rpc/DefaultDeviceRpcService.java

@ -15,47 +15,30 @@
*/
package org.thingsboard.server.service.rpc;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.async.DeferredResult;
import org.thingsboard.rule.engine.api.RpcError;
import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg;
import org.thingsboard.server.actors.service.ActorService;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.id.UUIDBased;
import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.cluster.SendToClusterMsg;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.core.ToServerRpcResponseMsg;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
import org.thingsboard.server.controller.BaseController;
import org.thingsboard.server.dao.audit.AuditLogService;
import org.thingsboard.server.extensions.api.device.ToDeviceActorNotificationMsg;
import org.thingsboard.server.extensions.api.plugins.msg.FromDeviceRpcResponse;
import org.thingsboard.server.extensions.api.plugins.msg.RpcError;
import org.thingsboard.server.gen.cluster.ClusterAPIProtos;
import org.thingsboard.server.service.cluster.routing.ClusterRoutingService;
import org.thingsboard.server.service.cluster.rpc.ClusterRpcService;
import org.thingsboard.server.service.security.model.SecurityUser;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.IOException;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**

1
application/src/main/java/org/thingsboard/server/service/rpc/DeviceRpcService.java

@ -19,7 +19,6 @@ import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
import org.thingsboard.server.extensions.api.plugins.msg.FromDeviceRpcResponse;
import java.util.function.Consumer;

3
extensions-api/src/main/java/org/thingsboard/server/extensions/api/plugins/msg/FromDeviceRpcResponse.java → application/src/main/java/org/thingsboard/server/service/rpc/FromDeviceRpcResponse.java

@ -13,11 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.extensions.api.plugins.msg;
package org.thingsboard.server.service.rpc;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import org.thingsboard.rule.engine.api.RpcError;
import java.util.Optional;
import java.util.UUID;

2
application/src/main/java/org/thingsboard/server/service/rpc/ToDeviceRpcRequestActorMsg.java

@ -18,12 +18,12 @@ package org.thingsboard.server.service.rpc;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.MsgType;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
import org.thingsboard.server.extensions.api.device.ToDeviceActorNotificationMsg;
import java.util.Optional;

2
application/src/main/java/org/thingsboard/server/service/rpc/ToServerRpcResponseActorMsg.java

@ -18,12 +18,12 @@ package org.thingsboard.server.service.rpc;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import org.thingsboard.rule.engine.api.msg.ToDeviceActorNotificationMsg;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.msg.MsgType;
import org.thingsboard.server.common.msg.cluster.ServerAddress;
import org.thingsboard.server.common.msg.core.ToServerRpcResponseMsg;
import org.thingsboard.server.extensions.api.device.ToDeviceActorNotificationMsg;
import java.util.Optional;

6
application/src/main/java/org/thingsboard/server/service/security/AccessValidator.java

@ -24,12 +24,11 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.async.DeferredResult;
import org.thingsboard.server.actors.plugin.ValidationResult;
import org.thingsboard.server.common.data.BaseData;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.asset.Asset;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.AssetId;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
@ -48,9 +47,8 @@ import org.thingsboard.server.dao.device.DeviceService;
import org.thingsboard.server.dao.rule.RuleChainService;
import org.thingsboard.server.dao.tenant.TenantService;
import org.thingsboard.server.dao.user.UserService;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.extensions.api.exception.ToErrorResponseEntity;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.telemetry.exception.ToErrorResponseEntity;
import javax.annotation.Nullable;
import javax.annotation.PostConstruct;

10
application/src/main/java/org/thingsboard/server/service/security/ValidationCallback.java

@ -16,12 +16,10 @@
package org.thingsboard.server.service.security;
import com.google.common.util.concurrent.FutureCallback;
import org.thingsboard.server.actors.plugin.ValidationResult;
import org.thingsboard.server.actors.plugin.ValidationResultCode;
import org.thingsboard.server.extensions.api.exception.AccessDeniedException;
import org.thingsboard.server.extensions.api.exception.EntityNotFoundException;
import org.thingsboard.server.extensions.api.exception.InternalErrorException;
import org.thingsboard.server.extensions.api.exception.UnauthorizedException;
import org.thingsboard.server.service.telemetry.exception.AccessDeniedException;
import org.thingsboard.server.service.telemetry.exception.EntityNotFoundException;
import org.thingsboard.server.service.telemetry.exception.InternalErrorException;
import org.thingsboard.server.service.telemetry.exception.UnauthorizedException;
/**
* Created by ashvayka on 31.03.18.

2
application/src/main/java/org/thingsboard/server/actors/plugin/ValidationResult.java → application/src/main/java/org/thingsboard/server/service/security/ValidationResult.java

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.actors.plugin;
package org.thingsboard.server.service.security;
import lombok.AllArgsConstructor;
import lombok.Data;

5
application/src/main/java/org/thingsboard/server/actors/plugin/ValidationResultCode.java → application/src/main/java/org/thingsboard/server/service/security/ValidationResultCode.java

@ -13,8 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.actors.plugin;
package org.thingsboard.server.service.security;
/**
* Created by ashvayka on 17.05.18.
*/
public enum ValidationResultCode {
OK,
UNAUTHORIZED,

8
application/src/main/java/org/thingsboard/server/service/security/auth/jwt/JwtAuthenticationProvider.java

@ -15,24 +15,16 @@
*/
package org.thingsboard.server.service.security.auth.jwt;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.stereotype.Component;
import org.thingsboard.server.config.JwtSettings;
import org.thingsboard.server.service.security.auth.JwtAuthenticationToken;
import org.thingsboard.server.service.security.model.SecurityUser;
import org.thingsboard.server.service.security.model.token.JwtTokenFactory;
import org.thingsboard.server.service.security.model.token.RawAccessJwtToken;
import java.util.List;
import java.util.stream.Collectors;
@Component
@SuppressWarnings("unchecked")
public class JwtAuthenticationProvider implements AuthenticationProvider {

1
application/src/main/java/org/thingsboard/server/service/security/auth/jwt/JwtTokenAuthenticationProcessingFilter.java

@ -23,7 +23,6 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.thingsboard.server.config.ThingsboardSecurityConfiguration;
import org.thingsboard.server.service.security.auth.JwtAuthenticationToken;
import org.thingsboard.server.service.security.auth.jwt.extractor.TokenExtractor;
import org.thingsboard.server.service.security.model.token.RawAccessJwtToken;

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save