thingsboard-aplcache

RPC Rule Action and descriptor

9/14/2017 2:01:51 AM

Details

diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/ServerSideRpcCallAction.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/ServerSideRpcCallAction.java
new file mode 100644
index 0000000..679c87b
--- /dev/null
+++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/ServerSideRpcCallAction.java
@@ -0,0 +1,88 @@
+package org.thingsboard.server.extensions.core.action.rpc;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.runtime.parser.ParseException;
+import org.springframework.util.StringUtils;
+import org.thingsboard.server.common.msg.device.ToDeviceActorMsg;
+import org.thingsboard.server.common.msg.session.ToDeviceMsg;
+import org.thingsboard.server.extensions.api.component.Action;
+import org.thingsboard.server.extensions.api.plugins.PluginAction;
+import org.thingsboard.server.extensions.api.plugins.msg.PluginToRuleMsg;
+import org.thingsboard.server.extensions.api.plugins.msg.ResponsePluginToRuleMsg;
+import org.thingsboard.server.extensions.api.plugins.msg.RuleToPluginMsg;
+import org.thingsboard.server.extensions.api.rules.RuleContext;
+import org.thingsboard.server.extensions.api.rules.RuleProcessingMetaData;
+import org.thingsboard.server.extensions.api.rules.SimpleRuleLifecycleComponent;
+import org.thingsboard.server.extensions.core.utils.VelocityUtils;
+
+import java.util.Optional;
+
+/**
+ * Created by ashvayka on 14.09.17.
+ */
+@Action(name = "Server Side RPC Call Action", descriptor = "ServerSideRpcCallActionDescriptor.json", configuration = ServerSideRpcCallActionConfiguration.class)
+@Slf4j
+public class ServerSideRpcCallAction extends SimpleRuleLifecycleComponent implements PluginAction<ServerSideRpcCallActionConfiguration> {
+
+    private ServerSideRpcCallActionConfiguration configuration;
+    private Optional<Template> deviceIdTemplate;
+    private Optional<Template> deviceRelationTemplate;
+    private Optional<Template> rpcCallMethodTemplate;
+    private Optional<Template> rpcCallBodyTemplate;
+
+    @Override
+    public void init(ServerSideRpcCallActionConfiguration configuration) {
+        this.configuration = configuration;
+        try {
+            deviceIdTemplate = toTemplate(configuration.getDeviceIdTemplate(), "Device Id Template");
+            deviceRelationTemplate = toTemplate(configuration.getDeviceRelationTemplate(), "Device Relation Template");
+            rpcCallMethodTemplate = toTemplate(configuration.getRpcCallMethodTemplate(), "RPC Call Method Template");
+            rpcCallBodyTemplate = toTemplate(configuration.getRpcCallBodyTemplate(), "RPC Call Body Template");
+        } catch (ParseException e) {
+            log.error("Failed to create templates based on provided configuration!", e);
+            throw new RuntimeException("Failed to create templates based on provided configuration!", e);
+        }
+    }
+
+    @Override
+    public Optional<RuleToPluginMsg<?>> convert(RuleContext ctx, ToDeviceActorMsg toDeviceActorMsg, RuleProcessingMetaData metadata) {
+        String sendFlag = configuration.getSendFlag();
+        if (StringUtils.isEmpty(sendFlag) || (Boolean) metadata.get(sendFlag).orElse(Boolean.FALSE)) {
+            VelocityContext context = VelocityUtils.createContext(metadata);
+
+            ServerSideRpcCallActionMsg.ServerSideRpcCallActionMsgBuilder builder = ServerSideRpcCallActionMsg.builder();
+
+            deviceIdTemplate.ifPresent(t -> builder.deviceId(VelocityUtils.merge(t, context)));
+            deviceRelationTemplate.ifPresent(t -> builder.deviceRelation(VelocityUtils.merge(t, context)));
+            rpcCallMethodTemplate.ifPresent(t -> builder.rpcCallMethod(VelocityUtils.merge(t, context)));
+            rpcCallBodyTemplate.ifPresent(t -> builder.rpcCallBody(VelocityUtils.merge(t, context)));
+            return Optional.of(new ServerSideRpcCallRuleToPluginActionMsg(toDeviceActorMsg.getTenantId(), toDeviceActorMsg.getCustomerId(), toDeviceActorMsg.getDeviceId(),
+                    builder.build()));
+        } else {
+            return Optional.empty();
+        }
+    }
+
+    private Optional<Template> toTemplate(String source, String name) throws ParseException {
+        if (!StringUtils.isEmpty(source)) {
+            return Optional.of(VelocityUtils.create(source, name));
+        } else {
+            return Optional.empty();
+        }
+    }
+
+    @Override
+    public Optional<ToDeviceMsg> convert(PluginToRuleMsg<?> response) {
+        if (response instanceof ResponsePluginToRuleMsg) {
+            return Optional.of(((ResponsePluginToRuleMsg) response).getPayload());
+        }
+        return Optional.empty();
+    }
+
+    @Override
+    public boolean isOneWayAction() {
+        return true;
+    }
+}
diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/ServerSideRpcCallActionConfiguration.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/ServerSideRpcCallActionConfiguration.java
new file mode 100644
index 0000000..30040ed
--- /dev/null
+++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/ServerSideRpcCallActionConfiguration.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright © 2016-2017 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.extensions.core.action.rpc;
+
+import lombok.Data;
+
+/**
+ * @author Andrew Shvayka
+ */
+@Data
+public class ServerSideRpcCallActionConfiguration {
+
+    private String sendFlag;
+
+    private String deviceIdTemplate;
+    private String deviceRelationTemplate;
+    private String rpcCallMethodTemplate;
+    private String rpcCallBodyTemplate;
+}
diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/ServerSideRpcCallActionMsg.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/ServerSideRpcCallActionMsg.java
new file mode 100644
index 0000000..6dcf217
--- /dev/null
+++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/ServerSideRpcCallActionMsg.java
@@ -0,0 +1,20 @@
+package org.thingsboard.server.extensions.core.action.rpc;
+
+import lombok.Builder;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * Created by ashvayka on 14.09.17.
+ */
+@Data
+@Builder
+public class ServerSideRpcCallActionMsg implements Serializable {
+
+    private String deviceId;
+    private String deviceRelation;
+    private String rpcCallMethod;
+    private String rpcCallBody;
+
+}
diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/ServerSideRpcCallRuleToPluginActionMsg.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/ServerSideRpcCallRuleToPluginActionMsg.java
new file mode 100644
index 0000000..0f1e916
--- /dev/null
+++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/action/rpc/ServerSideRpcCallRuleToPluginActionMsg.java
@@ -0,0 +1,17 @@
+package org.thingsboard.server.extensions.core.action.rpc;
+
+import org.thingsboard.server.common.data.id.CustomerId;
+import org.thingsboard.server.common.data.id.DeviceId;
+import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.extensions.api.plugins.msg.AbstractRuleToPluginMsg;
+
+/**
+ * Created by ashvayka on 14.09.17.
+ */
+public class ServerSideRpcCallRuleToPluginActionMsg extends AbstractRuleToPluginMsg<ServerSideRpcCallActionMsg> {
+
+    public ServerSideRpcCallRuleToPluginActionMsg(TenantId tenantId, CustomerId customerId, DeviceId deviceId,
+                                         ServerSideRpcCallActionMsg payload) {
+        super(tenantId, customerId, deviceId, payload);
+    }
+}
diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/handlers/RpcRuleMsgHandler.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/handlers/RpcRuleMsgHandler.java
new file mode 100644
index 0000000..f4e03ea
--- /dev/null
+++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/handlers/RpcRuleMsgHandler.java
@@ -0,0 +1,31 @@
+package org.thingsboard.server.extensions.core.plugin.rpc.handlers;
+
+import org.thingsboard.server.common.data.id.RuleId;
+import org.thingsboard.server.common.data.id.TenantId;
+import org.thingsboard.server.extensions.api.plugins.PluginContext;
+import org.thingsboard.server.extensions.api.plugins.handlers.RuleMsgHandler;
+import org.thingsboard.server.extensions.api.plugins.msg.RuleToPluginMsg;
+import org.thingsboard.server.extensions.api.plugins.msg.ToDeviceRpcRequest;
+import org.thingsboard.server.extensions.api.rules.RuleException;
+import org.thingsboard.server.extensions.core.action.rpc.ServerSideRpcCallActionMsg;
+
+/**
+ * Created by ashvayka on 14.09.17.
+ */
+public class RpcRuleMsgHandler implements RuleMsgHandler {
+
+    @Override
+    public void process(PluginContext ctx, TenantId tenantId, RuleId ruleId, RuleToPluginMsg<?> msg) throws RuleException {
+        if (msg instanceof ServerSideRpcCallActionMsg) {
+            handle(ctx, tenantId, ruleId, (ServerSideRpcCallActionMsg) msg);
+        } else {
+            throw new RuntimeException("Not supported msg: " + msg + "!");
+        }
+    }
+
+    private void handle(PluginContext ctx, TenantId tenantId, RuleId ruleId, ServerSideRpcCallActionMsg msg) {
+//        TODO: implement
+//        ToDeviceRpcRequest request = new ToDeviceRpcRequest();
+//        ctx.sendRpcRequest(request);
+    }
+}
diff --git a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/RpcPlugin.java b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/RpcPlugin.java
index 81b8cbe..b24e4a3 100644
--- a/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/RpcPlugin.java
+++ b/extensions-core/src/main/java/org/thingsboard/server/extensions/core/plugin/rpc/RpcPlugin.java
@@ -1,12 +1,12 @@
 /**
  * Copyright © 2016-2017 The Thingsboard Authors
- *
+ * <p>
  * 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
- *
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
  * 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.
@@ -19,15 +19,18 @@ import lombok.extern.slf4j.Slf4j;
 import org.thingsboard.server.extensions.api.component.Plugin;
 import org.thingsboard.server.extensions.api.plugins.AbstractPlugin;
 import org.thingsboard.server.extensions.api.plugins.PluginContext;
+import org.thingsboard.server.extensions.api.plugins.handlers.DefaultRuleMsgHandler;
 import org.thingsboard.server.extensions.api.plugins.handlers.RestMsgHandler;
+import org.thingsboard.server.extensions.api.plugins.handlers.RuleMsgHandler;
 import org.thingsboard.server.extensions.api.plugins.msg.FromDeviceRpcResponse;
 import org.thingsboard.server.extensions.api.plugins.msg.TimeoutMsg;
+import org.thingsboard.server.extensions.core.action.rpc.ServerSideRpcCallAction;
 import org.thingsboard.server.extensions.core.plugin.rpc.handlers.RpcRestMsgHandler;
 
 /**
  * @author Andrew Shvayka
  */
-@Plugin(name = "RPC Plugin", actions = {}, descriptor = "RpcPluginDescriptor.json", configuration = RpcPluginConfiguration.class)
+@Plugin(name = "RPC Plugin", actions = {ServerSideRpcCallAction.class}, descriptor = "RpcPluginDescriptor.json", configuration = RpcPluginConfiguration.class)
 @Slf4j
 public class RpcPlugin extends AbstractPlugin<RpcPluginConfiguration> {
 
@@ -61,6 +64,11 @@ public class RpcPlugin extends AbstractPlugin<RpcPluginConfiguration> {
     }
 
     @Override
+    protected RuleMsgHandler getRuleMsgHandler() {
+        return new DefaultRuleMsgHandler();
+    }
+
+    @Override
     public void resume(PluginContext ctx) {
 
     }
diff --git a/extensions-core/src/main/resources/ServerSideRpcCallActionDescriptor.json b/extensions-core/src/main/resources/ServerSideRpcCallActionDescriptor.json
new file mode 100644
index 0000000..e69c38e
--- /dev/null
+++ b/extensions-core/src/main/resources/ServerSideRpcCallActionDescriptor.json
@@ -0,0 +1,45 @@
+{
+  "schema": {
+    "title": "Send Mail Action Configuration",
+    "type": "object",
+    "properties": {
+      "sendFlag": {
+        "title": "Send flag",
+        "type": "string"
+      },
+      "deviceIdTemplate": {
+        "title": "Device ID template",
+        "type": "string"
+      },
+      "deviceRelationTemplate": {
+        "title": "Device Relation template",
+        "type": "string"
+      },
+      "rpcCallMethodTemplate": {
+        "title": "RPC Call template",
+        "type": "string"
+      },
+      "rpcCallBodyTemplate": {
+        "title": "RPC Call Body template",
+        "type": "string"
+      }
+    },
+    "required": [
+      "deviceIdTemplate",
+      "deviceRelationTemplate",
+      "rpcCallMethodTemplate",
+      "rpcCallBodyTemplate"
+    ]
+  },
+  "form": [
+    "sendFlag",
+    "deviceIdTemplate",
+    "deviceRelationTemplate",
+    "rpcCallMethodTemplate",
+    {
+      "key": "rpcCallBodyTemplate",
+      "type": "textarea",
+      "rows": 5
+    }
+  ]
+}
\ No newline at end of file