Răsfoiți Sursa

增加http业务组件

xiwa 3 ani în urmă
părinte
comite
a0e23dea2b
25 a modificat fișierele cu 450 adăugiri și 270 ștergeri
  1. BIN
      .DS_Store
  2. 1 1
      common/src/main/java/cc/iotkit/common/ComponentClassLoader.java
  3. BIN
      manager/.DS_Store
  4. 58 0
      manager/src/main/java/cc/iotkit/manager/config/ResponseResultHandler.java
  5. 10 32
      manager/src/main/java/cc/iotkit/manager/controller/DeviceController.java
  6. 18 12
      manager/src/main/java/cc/iotkit/manager/controller/ProtocolController.java
  7. 0 44
      manager/src/main/java/cc/iotkit/manager/controller/aligenie/AligenieDeviceController.java
  8. 4 73
      manager/src/main/java/cc/iotkit/manager/controller/api/DeviceController.java
  9. 6 7
      manager/src/main/java/cc/iotkit/manager/model/query/DeviceQuery.java
  10. 5 4
      pom.xml
  11. BIN
      protocol-gateway/.DS_Store
  12. 5 0
      protocol-gateway/component-server/pom.xml
  13. 60 37
      protocol-gateway/component-server/src/main/java/cc/iotkit/comps/ApiTool.java
  14. 3 3
      protocol-gateway/component-server/src/main/java/cc/iotkit/comps/BizComponentManager.java
  15. 48 0
      protocol-gateway/component-server/src/main/java/cc/iotkit/comps/ComponentManager.java
  16. 2 1
      protocol-gateway/component-server/src/main/java/cc/iotkit/comps/DeviceComponentManager.java
  17. 3 3
      protocol-gateway/component-server/src/main/java/cc/iotkit/comps/DeviceMessageHandler.java
  18. BIN
      protocol-gateway/emqx-component/src/main/java/cc/iotkit/comp/emqx/EmqxDeviceComponent.java
  19. 69 0
      protocol-gateway/http-biz-component/dependency-reduced-pom.xml
  20. 38 6
      protocol-gateway/http-biz-component/pom.xml
  21. 80 43
      protocol-gateway/http-biz-component/src/main/java/cc/iotkit/comp/biz/HttpBizComponent.java
  22. 36 0
      protocol-gateway/http-biz-component/src/main/java/cc/iotkit/comp/biz/HttpConfig.java
  23. 2 2
      protocol-gateway/http-biz-component/src/main/resources/component.spi
  24. 2 2
      protocol-gateway/mqtt-component/dependency-reduced-pom.xml
  25. 0 0
      protocol-gateway/mqtt-component/src/main/java/cc/iotkit/comp/mqtt/MqttDeviceComponent.java

BIN
.DS_Store


+ 1 - 1
common/src/main/java/cc/iotkit/common/ComponentClassLoader.java

@@ -41,7 +41,7 @@ public final class JsonUtil {
 
     public static Object toObject(ScriptObjectMirror mirror) {
         if (mirror.isEmpty()) {
-            return null;
+            return new Object();
         }
         if (mirror.isArray()) {
             List<Object> list = new ArrayList<>();

BIN
manager/.DS_Store


+ 58 - 0
manager/src/main/java/cc/iotkit/manager/config/ResponseResultHandler.java

@@ -0,0 +1,58 @@
+package cc.iotkit.manager.config;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.core.MethodParameter;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+@ControllerAdvice
+public class ResponseResultHandler implements ResponseBodyAdvice<Object> {
+    @Override
+    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
+        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
+        String wrapResponse = request.getHeader("wrap-response");
+        return "json".equals(wrapResponse);
+    }
+
+    @Override
+    public Object beforeBodyWrite(Object body, MethodParameter returnType,
+                                  MediaType selectedContentType,
+                                  Class<? extends HttpMessageConverter<?>> selectedConverterType,
+                                  ServerHttpRequest request, ServerHttpResponse response) {
+        if (body instanceof GlobalExceptionHandler.RequestResult) {
+            GlobalExceptionHandler.RequestResult requestResult = (GlobalExceptionHandler.RequestResult) body;
+            return new ApiResponse(Integer.parseInt(requestResult.getCode()), requestResult.getMessage(),
+                    "", System.currentTimeMillis());
+        } else if (body instanceof Map) {
+            Map map = (Map) body;
+            //spring mvc内部异常
+            if (map.containsKey("timestamp") && map.containsKey("status") && map.containsKey("error")) {
+                return new ApiResponse((Integer) map.get("status"), (String) map.get("error"),
+                        "", System.currentTimeMillis());
+            }
+        }
+
+        return new ApiResponse(200, "", body, System.currentTimeMillis());
+    }
+
+    @Data
+    @NoArgsConstructor
+    @AllArgsConstructor
+    public static class ApiResponse {
+        private int status;
+        private String message;
+        private Object data;
+        private long timestamp;
+    }
+}

+ 10 - 32
manager/src/main/java/cc/iotkit/manager/controller/DeviceController.java

@@ -10,6 +10,7 @@ import cc.iotkit.manager.model.query.DeviceQuery;
 import cc.iotkit.manager.service.DataOwnerService;
 import cc.iotkit.manager.service.DeviceService;
 import cc.iotkit.manager.utils.AuthUtil;
+import cc.iotkit.model.InvokeResult;
 import cc.iotkit.model.Paging;
 import cc.iotkit.model.device.DeviceInfo;
 import cc.iotkit.model.device.message.DeviceProperty;
@@ -55,44 +56,21 @@ public class DeviceController {
     private DeviceBehaviourService behaviourService;
 
     @PostMapping(Constants.API.DEVICE_INVOKE_SERVICE)
-    public String invokeService(@PathVariable("deviceId") String deviceId,
-                                @PathVariable("service") String service,
-                                @RequestBody Map<String, Object> args) {
+    public InvokeResult invokeService(@PathVariable("deviceId") String deviceId,
+                                      @PathVariable("service") String service,
+                                      @RequestBody Map<String, Object> args) {
         if (StringUtils.isBlank(deviceId) || StringUtils.isBlank(service)) {
             throw new RuntimeException("deviceId/service is blank.");
         }
         dataOwnerService.checkWriteRole();
-        return deviceService.invokeService(deviceId, service, args);
+        return new InvokeResult(deviceService.invokeService(deviceId, service, args));
     }
 
     @PostMapping(Constants.API.DEVICE_SET_PROPERTIES)
-    public String setProperty(@PathVariable("deviceId") String deviceId,
-                              @RequestBody Map<String, Object> args) {
+    public InvokeResult setProperty(@PathVariable("deviceId") String deviceId,
+                                    @RequestBody Map<String, Object> args) {
         dataOwnerService.checkWriteRole();
-        return deviceService.setProperty(deviceId, args);
-    }
-
-    @PostMapping("/list")
-    public Paging<DeviceInfo> getDevices(int page,
-                                         int size,
-                                         String pk,
-                                         Boolean online,
-                                         String dn) {
-        Criteria condition = new Criteria();
-        if (!AuthUtil.isAdmin()) {
-            condition.and("uid").is(AuthUtil.getUserId());
-        }
-        if (StringUtils.isNotBlank(pk)) {
-            condition.and("productKey").is(pk);
-        }
-        if (StringUtils.isNotBlank(dn)) {
-            condition.and("deviceName").regex(".*" + dn + ".*");
-        }
-        if (online != null) {
-            condition.and("state.online").is(online);
-        }
-
-        return deviceDao.find(condition, size, page);
+        return new InvokeResult(deviceService.setProperty(deviceId, args));
     }
 
     @PostMapping("/list/{size}/{page}")
@@ -121,8 +99,8 @@ public class DeviceController {
             condition.and("deviceName").regex(".*" + dn + ".*");
         }
         String state = query.getState();
-        if (state != null) {
-            condition.and("state.online").is(state);
+        if (StringUtils.isNotBlank(state)) {
+            condition.and("state.online").is(state.equals("online"));
         }
 
         return deviceDao.find(condition, size, page);

+ 18 - 12
manager/src/main/java/cc/iotkit/manager/controller/ProtocolController.java

@@ -3,7 +3,7 @@ package cc.iotkit.manager.controller;
 import cc.iotkit.common.exception.BizException;
 import cc.iotkit.common.utils.JsonUtil;
 import cc.iotkit.common.utils.ReflectUtil;
-import cc.iotkit.comps.DeviceComponentManager;
+import cc.iotkit.comps.ComponentManager;
 import cc.iotkit.comps.config.ComponentConfig;
 import cc.iotkit.dao.ProtocolComponentRepository;
 import cc.iotkit.dao.ProtocolConverterRepository;
@@ -50,7 +50,7 @@ public class ProtocolController {
     private UserInfoRepository userInfoRepository;
 
     @Autowired
-    private DeviceComponentManager deviceComponentManager;
+    private ComponentManager componentManager;
 
     @PostMapping("/uploadJar")
     public String uploadJar(@RequestParam("file") MultipartFile file, String id) {
@@ -112,8 +112,9 @@ public class ProtocolController {
 
         ProtocolComponent oldComponent = getAndCheckComponent(id);
         component = ReflectUtil.copyNoNulls(component, oldComponent);
+
         try {
-            deviceComponentManager.deRegister(id);
+            componentManager.deRegister(id);
             protocolComponentRepository.save(component);
         } catch (Throwable e) {
             throw new BizException("add protocol component error", e);
@@ -144,7 +145,7 @@ public class ProtocolController {
             script = JsonUtil.parse(script, String.class);
             FileUtils.writeStringToFile(file, script, "UTF-8", false);
 
-            deviceComponentManager.deRegister(id);
+            componentManager.deRegister(id);
         } catch (Throwable e) {
             throw new BizException("save protocol component script error", e);
         }
@@ -164,7 +165,7 @@ public class ProtocolController {
     public void deleteComponent(@PathVariable("id") String id) {
         ProtocolComponent component = getAndCheckComponent(id);
         try {
-            deviceComponentManager.deRegister(id);
+            componentManager.deRegister(id);
 
             Path path = Paths.get(String.format("%s/%s", componentConfig.getComponentDir(), id))
                     .toAbsolutePath().normalize();
@@ -190,8 +191,10 @@ public class ProtocolController {
             @PathVariable("page") int page) {
         Page<ProtocolComponent> components = protocolComponentRepository.findAll(
                 PageRequest.of(page - 1, size, Sort.by(Sort.Order.desc("createAt"))));
-        components.getContent().forEach(c -> c.setState(deviceComponentManager.isRunning(c.getId()) ?
-                ProtocolComponent.STATE_RUNNING : ProtocolComponent.STATE_STOPPED));
+        components.getContent().forEach(c -> c.setState(
+                componentManager.isRunning(c.getId()) ?
+                        ProtocolComponent.STATE_RUNNING : ProtocolComponent.STATE_STOPPED
+        ));
         return new Paging<>(components.getTotalElements(), components.getContent());
     }
 
@@ -294,14 +297,17 @@ public class ProtocolController {
     public void changeComponentState(@PathVariable("id") String id,
                                      @PathVariable("state") String state) {
         ProtocolComponent component = getAndCheckComponent(id);
-        String converterId = component.getConverter();
-        getAndCheckConverter(converterId);
+        if(ProtocolComponent.TYPE_DEVICE.equals(component.getType())){
+            String converterId = component.getConverter();
+            getAndCheckConverter(converterId);
+        }
+
         if (ProtocolComponent.STATE_RUNNING.equals(state)) {
-            deviceComponentManager.register(component);
-            deviceComponentManager.start(component.getId());
+            componentManager.register(component);
+            componentManager.start(component.getId());
             component.setState(ProtocolComponent.STATE_RUNNING);
         } else {
-            deviceComponentManager.deRegister(id);
+            componentManager.deRegister(id);
             component.setState(ProtocolComponent.STATE_STOPPED);
         }
         protocolComponentRepository.save(component);

+ 0 - 44
manager/src/main/java/cc/iotkit/manager/controller/aligenie/AligenieDeviceController.java

@@ -2,23 +2,17 @@ package cc.iotkit.manager.controller.aligenie;
 
 import cc.iotkit.common.Constants;
 import cc.iotkit.common.exception.BizException;
-import cc.iotkit.common.exception.OfflineException;
-import cc.iotkit.common.utils.JsonUtil;
 import cc.iotkit.common.utils.UniqueIdUtil;
 import cc.iotkit.dao.*;
 import cc.iotkit.manager.service.DataOwnerService;
 import cc.iotkit.manager.service.DeviceService;
-import cc.iotkit.manager.utils.AuthUtil;
-import cc.iotkit.model.InvokeResult;
 import cc.iotkit.model.UserInfo;
 import cc.iotkit.model.aligenie.AligenieDevice;
 import cc.iotkit.model.aligenie.AligenieProduct;
 import cc.iotkit.model.device.DeviceInfo;
 import cc.iotkit.model.device.message.ThingModelMessage;
-import io.swagger.annotations.ApiOperation;
 import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.pulsar.client.api.Producer;
 import org.apache.pulsar.client.api.PulsarClient;
 import org.apache.pulsar.client.api.PulsarClientException;
@@ -131,44 +125,6 @@ public class AligenieDeviceController {
                 .build());
     }
 
-    @ApiOperation("设备服务调用")
-    @PostMapping("/invoke/{deviceId}/{service}")
-    public InvokeResult invokeService(@PathVariable("deviceId") String deviceId,
-                                      @PathVariable("service") String service,
-                                      String args) {
-        InvokeResult result = new InvokeResult("", InvokeResult.FAILED_UNKNOWN);
-        AligenieDevice device = aligenieDeviceRepository.findByUidAndDeviceId(AuthUtil.getUserId(), deviceId);
-
-        if (device == null) {
-            result.setCode(InvokeResult.FAILED_NO_AUTH);
-            return result;
-        }
-
-        if (StringUtils.isBlank(deviceId) || StringUtils.isBlank(service)) {
-            log.error("deviceId/service is blank");
-            result.setCode(InvokeResult.FAILED_PARAM_ERROR);
-            return result;
-        }
-
-        try {
-            String requestId;
-            if ("set".equals(service)) {
-                requestId = deviceService.setProperty(deviceId,
-                        JsonUtil.parse(args, Map.class), false);
-            } else {
-                requestId = deviceService.invokeService(deviceId,
-                        service, JsonUtil.parse(args, Map.class), false);
-            }
-            result.setRequestId(requestId);
-            result.setCode(InvokeResult.SUCCESS);
-        } catch (OfflineException e) {
-            log.error("sendMsg failed", e);
-            result.setCode(InvokeResult.FAILED_OFFLINE);
-            return result;
-        }
-        return result;
-    }
-
     @Data
     public static class Device {
         private String deviceId;

+ 4 - 73
manager/src/main/java/cc/iotkit/manager/controller/api/DeviceController.java

@@ -1,7 +1,5 @@
 package cc.iotkit.manager.controller.api;
 
-import cc.iotkit.common.exception.OfflineException;
-import cc.iotkit.common.utils.JsonUtil;
 import cc.iotkit.dao.AppDesignRepository;
 import cc.iotkit.dao.DeviceRepository;
 import cc.iotkit.dao.SpaceDeviceRepository;
@@ -10,7 +8,6 @@ import cc.iotkit.manager.model.vo.AppPageNode;
 import cc.iotkit.manager.service.AppDesignService;
 import cc.iotkit.manager.service.DeviceService;
 import cc.iotkit.manager.utils.AuthUtil;
-import cc.iotkit.model.InvokeResult;
 import cc.iotkit.model.device.DeviceInfo;
 import cc.iotkit.model.space.SpaceDevice;
 import io.swagger.annotations.ApiImplicitParam;
@@ -20,10 +17,12 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.domain.Example;
-import org.springframework.web.bind.annotation.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
 
 import java.util.List;
-import java.util.Map;
 import java.util.stream.Collectors;
 
 @Slf4j
@@ -72,74 +71,6 @@ public class DeviceController {
                 .collect(Collectors.toList());
     }
 
-    @ApiOperation("设备服务调用")
-    @ApiImplicitParams({
-            @ApiImplicitParam(value = "设备ID", name = "deviceId", required = true, dataType = "String"),
-            @ApiImplicitParam(value = "服务名", name = "service", required = true, dataType = "String"),
-            @ApiImplicitParam(value = "参数", name = "args", required = true, dataType = "String"),
-    })
-    @PostMapping("/{deviceId}/service/{service}")
-    public InvokeResult invokeService(@PathVariable("deviceId") String deviceId,
-                                      @PathVariable("service") String service,
-                                      String args) {
-        InvokeResult result = new InvokeResult("", InvokeResult.FAILED_UNKNOWN);
-        SpaceDevice device = checkOwner(deviceId);
-
-        if (device == null) {
-            result.setCode(InvokeResult.FAILED_NO_AUTH);
-            return result;
-        }
-
-        if (StringUtils.isBlank(deviceId) || StringUtils.isBlank(service)) {
-            log.error("deviceId/service is blank");
-            result.setCode(InvokeResult.FAILED_PARAM_ERROR);
-            return result;
-        }
-
-        try {
-            String requestId;
-            if ("property/set".equals(service)) {
-                requestId = deviceService.setProperty(deviceId,
-                        JsonUtil.parse(args, Map.class));
-            } else {
-                requestId = deviceService.invokeService(deviceId, service,
-                        JsonUtil.parse(args, Map.class));
-            }
-            result.setRequestId(requestId);
-            result.setCode(InvokeResult.SUCCESS);
-        } catch (OfflineException e) {
-            log.error("sendMsg failed", e);
-            result.setCode(InvokeResult.FAILED_OFFLINE);
-            return result;
-        }
-
-        return result;
-    }
-
-    @ApiOperation("设备属性调用")
-    @ApiImplicitParams({
-            @ApiImplicitParam(value = "设备ID", name = "deviceId", required = true, dataType = "String"),
-            @ApiImplicitParam(value = "参数", name = "args", required = true, dataType = "String"),
-    })
-    @PostMapping("/{deviceId}/service/property/set")
-    public InvokeResult setProperty(@PathVariable("deviceId") String deviceId,
-                                    String args) {
-        checkOwner(deviceId);
-        if (StringUtils.isBlank(deviceId) || StringUtils.isBlank(args)) {
-            throw new RuntimeException("deviceId/args is blank.");
-        }
-        return invokeService(deviceId, "property/set", args);
-    }
-
-    /**
-     * 检查设备是否属于该用户
-     */
-    private SpaceDevice checkOwner(String deviceId) {
-        return spaceDeviceRepository.findOne(Example.of(SpaceDevice.builder()
-                .uid(AuthUtil.getUserId()).deviceId(deviceId).build()))
-                .orElse(null);
-    }
-
     @GetMapping("/detailPage/{deviceId}")
     public List<AppPageNode> deviceDetailPage(@PathVariable("deviceId") String deviceId) {
         DeviceInfo device = deviceRepository.findById(deviceId).orElseThrow(() -> new RuntimeException("device not found"));

+ 6 - 7
manager/src/main/java/cc/iotkit/manager/model/query/DeviceQuery.java

@@ -9,13 +9,12 @@ import lombok.NoArgsConstructor;
 @AllArgsConstructor
 public class InvokeResult {
 
-    public static final String SUCCESS = "success";
-    public static final String FAILED_UNKNOWN = "unknown";
-    public static final String FAILED_OFFLINE = "offline";
-    public static final String FAILED_PARAM_ERROR = "param_error";
-    public static final String FAILED_NO_AUTH = "no_auth";
-
     private String requestId;
 
-    private String code;
+    private long time;
+
+    public InvokeResult(String requestId) {
+        this.requestId = requestId;
+        this.time = System.currentTimeMillis();
+    }
 }

+ 5 - 4
pom.xml

@@ -27,6 +27,7 @@
     <properties>
         <java.version>1.8</java.version>
         <keycloak-spring.version>17.0.0</keycloak-spring.version>
+        <vertx.version>4.2.2</vertx.version>
     </properties>
 
     <dependencyManagement>
@@ -175,25 +176,25 @@
             <dependency>
                 <groupId>io.vertx</groupId>
                 <artifactId>vertx-core</artifactId>
-                <version>4.2.6</version>
+                <version>${vertx.version}</version>
             </dependency>
 
             <dependency>
                 <groupId>io.vertx</groupId>
                 <artifactId>vertx-mqtt</artifactId>
-                <version>4.2.6</version>
+                <version>${vertx.version}</version>
             </dependency>
 
             <dependency>
                 <groupId>io.vertx</groupId>
                 <artifactId>vertx-web-proxy</artifactId>
-                <version>4.2.6</version>
+                <version>${vertx.version}</version>
             </dependency>
 
             <dependency>
                 <groupId>io.vertx</groupId>
                 <artifactId>vertx-web-client</artifactId>
-                <version>4.2.6</version>
+                <version>${vertx.version}</version>
             </dependency>
 
             <dependency>

BIN
protocol-gateway/.DS_Store


+ 5 - 0
protocol-gateway/component-server/pom.xml

@@ -42,6 +42,11 @@
             <artifactId>slf4j-api</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>io.vertx</groupId>
+            <artifactId>vertx-web-client</artifactId>
+        </dependency>
+
         <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>

+ 60 - 37
protocol-gateway/http-biz-component/src/main/java/cc/iotkit/comp/biz/ApiTool.java → protocol-gateway/component-server/src/main/java/cc/iotkit/comps/ApiTool.java

@@ -1,14 +1,16 @@
-package cc.iotkit.comp.biz;
+package cc.iotkit.comps;
 
 import cc.iotkit.common.Constants;
 import io.vertx.core.Vertx;
 import io.vertx.core.buffer.Buffer;
+import io.vertx.core.http.HttpMethod;
 import io.vertx.ext.web.client.HttpRequest;
 import io.vertx.ext.web.client.WebClient;
 import io.vertx.ext.web.client.WebClientOptions;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 
 import java.nio.file.Paths;
 import java.util.HashMap;
@@ -20,6 +22,7 @@ import java.util.concurrent.atomic.AtomicReference;
 /**
  * 平台API调用工具类
  */
+@Slf4j
 public class ApiTool {
 
     private static final Vertx vertx;
@@ -48,17 +51,19 @@ public class ApiTool {
         ApiTool.timeout = timeout;
     }
 
+    private static String getPath(String path) {
+        return Paths.get(Constants.API.DEVICE_BASE, path).toString();
+    }
+
     /**
      * 获取用户的设备列表
      */
     public static ApiResponse getDevices(String token) {
         HttpRequest<Buffer> request = client
-                .post(port, host, Paths.get(Constants.API.DEVICE_BASE, Constants.API.DEVICE_LIST
-                        .replace("size", "1000")
-                        .replace("page", "1")).toString())
-                .timeout(timeout)
-                .putHeader("authorization", "Bearer " + token);
-        return sendJson(request, new HashMap<>());
+                .post(port, host, getPath(Constants.API.DEVICE_LIST
+                        .replace("{size}", "1000")
+                        .replace("{page}", "1")));
+        return send(token, HttpMethod.POST, request, new HashMap<>());
     }
 
     /**
@@ -66,11 +71,9 @@ public class ApiTool {
      */
     public static ApiResponse getDeviceDetail(String token, String deviceId) {
         HttpRequest<Buffer> request = client
-                .post(port, host, Paths.get(Constants.API.DEVICE_BASE, Constants.API.DEVICE_DETAIL
-                        .replace("deviceId", deviceId)).toString())
-                .timeout(timeout)
-                .putHeader("authorization", "Bearer " + token);
-        return sendJson(request, new HashMap<>());
+                .get(port, host, getPath(Constants.API.DEVICE_DETAIL
+                        .replace("{deviceId}", deviceId)));
+        return send(token, HttpMethod.GET, request, new HashMap<>());
     }
 
     /**
@@ -78,11 +81,9 @@ public class ApiTool {
      */
     public static ApiResponse setProperties(String token, String deviceId, Map<String, Object> properties) {
         HttpRequest<Buffer> request = client
-                .post(port, host, Paths.get(Constants.API.DEVICE_BASE, Constants.API.DEVICE_SET_PROPERTIES
-                        .replace("deviceId", deviceId)).toString())
-                .timeout(timeout)
-                .putHeader("authorization", "Bearer " + token);
-        return sendJson(request, properties);
+                .post(port, host, getPath(Constants.API.DEVICE_SET_PROPERTIES
+                        .replace("{deviceId}", deviceId)));
+        return send(token, HttpMethod.POST, request, properties);
     }
 
     /**
@@ -90,48 +91,70 @@ public class ApiTool {
      */
     public static ApiResponse invokeService(String token, String deviceId, String service, Map<String, Object> params) {
         HttpRequest<Buffer> request = client
-                .post(port, host, Paths.get(Constants.API.DEVICE_BASE, Constants.API.DEVICE_INVOKE_SERVICE
-                        .replace("deviceId", deviceId)
-                        .replace("service", service)).toString())
+                .post(port, host, getPath(Constants.API.DEVICE_INVOKE_SERVICE
+                        .replace("{deviceId}", deviceId)
+                        .replace("{service}", service)));
+        return send(token, HttpMethod.POST, request, params);
+    }
+
+    private static ApiResponse send(String token, HttpMethod method, HttpRequest<Buffer> request, Map<String, Object> params) {
+        request = request
                 .timeout(timeout)
+                .putHeader("wrap-response", "json")
                 .putHeader("authorization", "Bearer " + token);
-        return sendJson(request, params);
-    }
 
-    private static ApiResponse sendJson(HttpRequest<Buffer> request, Map<String, Object> params) {
-        AtomicReference<ApiResponse> apiResponse = new AtomicReference<>(new ApiResponse(500, "", null));
+        AtomicReference<ApiResponse> apiResponse = new AtomicReference<>(
+                new ApiResponse(500, "", null, System.currentTimeMillis()));
         try {
             //转为同步模式便于提供给js调用
             CountDownLatch wait = new CountDownLatch(1);
-            request.sendJson(params)
-                    .onSuccess((response) -> {
-                        System.out.println(response.bodyAsString());
-                        apiResponse.set(response.bodyAsJson(ApiResponse.class));
-                        wait.countDown();
-                    })
-                    .onFailure((err) -> {
-                        err.printStackTrace();
-                        wait.countDown();
-                    });
+
+            if (method == HttpMethod.POST) {
+                request.sendJson(params)
+                        .onSuccess((response) -> {
+                            System.out.println(response.bodyAsString());
+                            apiResponse.set(response.bodyAsJson(ApiResponse.class));
+                            wait.countDown();
+                        })
+                        .onFailure((err) -> {
+                            err.printStackTrace();
+                            wait.countDown();
+                        });
+            } else if (method == HttpMethod.GET) {
+                request.send()
+                        .onSuccess((response) -> {
+                            apiResponse.set(response.bodyAsJson(ApiResponse.class));
+                            wait.countDown();
+                        })
+                        .onFailure((err) -> {
+                            err.printStackTrace();
+                            wait.countDown();
+                        });
+            }
             if (wait.await(timeout, TimeUnit.MILLISECONDS)) {
                 return apiResponse.get();
             } else {
-                apiResponse.get().setCode(500);
+                apiResponse.get().setStatus(500);
                 apiResponse.get().setMessage("request timeout");
             }
         } catch (Throwable e) {
-            apiResponse.get().setCode(500);
+            apiResponse.get().setStatus(500);
             apiResponse.get().setMessage(e.getMessage());
         }
         return apiResponse.get();
     }
 
+    public static void log(String msg) {
+        log.info(msg);
+    }
+
     @Data
     @NoArgsConstructor
     @AllArgsConstructor
     public static class ApiResponse {
-        private int code;
+        private int status;
         private String message;
         private Object data;
+        private long timestamp;
     }
 }

+ 3 - 3
protocol-gateway/component-server/src/main/java/cc/iotkit/comps/BizComponentManager.java

@@ -61,16 +61,16 @@ public class BizComponentManager {
         } catch (Throwable e) {
             throw new BizException("get component instance error");
         }
-        componentInstance.create(new CompConfig(300, component.getConfig()));
-
         try {
             String componentScript = FileUtils.readFileToString(path.
                     resolve(ProtocolComponent.SCRIPT_FILE_NAME).toFile(), "UTF-8");
             componentInstance.setScript(componentScript);
-            register(id, componentInstance);
         } catch (IOException e) {
             throw new BizException("get component script error", e);
         }
+        componentInstance.create(new CompConfig(300, component.getConfig()));
+
+        register(id, componentInstance);
     }
 
     public void register(String id, IComponent component) {

+ 48 - 0
protocol-gateway/component-server/src/main/java/cc/iotkit/comps/ComponentManager.java

@@ -0,0 +1,48 @@
+package cc.iotkit.comps;
+
+
+import cc.iotkit.model.protocol.ProtocolComponent;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+public class ComponentManager {
+
+    @Autowired
+    private BizComponentManager bizComponentManager;
+
+    @Autowired
+    private DeviceComponentManager deviceComponentManager;
+
+
+    public void register(ProtocolComponent component) {
+        String type = component.getType();
+        if (ProtocolComponent.TYPE_BIZ.equals(type)) {
+            bizComponentManager.register(component);
+        } else if (ProtocolComponent.TYPE_DEVICE.equals(type)) {
+            deviceComponentManager.register(component);
+        }
+    }
+
+    public void deRegister(String id) {
+        bizComponentManager.deRegister(id);
+        deviceComponentManager.deRegister(id);
+    }
+
+    public void start(String id) {
+        bizComponentManager.start(id);
+        deviceComponentManager.start(id);
+    }
+
+    public void stop(String id) {
+        bizComponentManager.stop(id);
+        deviceComponentManager.stop(id);
+    }
+
+    public boolean isRunning(String id) {
+        return bizComponentManager.isRunning(id) || deviceComponentManager.isRunning(id);
+    }
+
+}

+ 2 - 1
protocol-gateway/component-server/src/main/java/cc/iotkit/comps/DeviceComponentManager.java

@@ -50,7 +50,8 @@ public class DeviceComponentManager {
     @PostConstruct
     public void init() {
         try {
-            List<ProtocolComponent> componentList = componentRepository.findByState(ProtocolComponent.STATE_RUNNING);
+            List<ProtocolComponent> componentList = componentRepository.findByStateAndType(
+                    ProtocolComponent.STATE_RUNNING, ProtocolComponent.TYPE_DEVICE);
             for (ProtocolComponent component : componentList) {
                 register(component);
                 start(component.getId());

+ 3 - 3
protocol-gateway/component-server/src/main/java/cc/iotkit/comps/DeviceMessageHandler.java

@@ -43,19 +43,19 @@
     <dependency>
       <groupId>io.vertx</groupId>
       <artifactId>vertx-core</artifactId>
-      <version>4.2.6</version>
+      <version>4.2.2</version>
       <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>io.vertx</groupId>
       <artifactId>vertx-web-proxy</artifactId>
-      <version>4.2.6</version>
+      <version>4.2.2</version>
       <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>io.vertx</groupId>
       <artifactId>vertx-mqtt</artifactId>
-      <version>4.2.6</version>
+      <version>4.2.2</version>
       <scope>provided</scope>
     </dependency>
     <dependency>

BIN
protocol-gateway/emqx-component/src/main/java/cc/iotkit/comp/emqx/EmqxDeviceComponent.java


+ 69 - 0
protocol-gateway/http-biz-component/dependency-reduced-pom.xml

@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <parent>
+    <artifactId>protocol-gateway</artifactId>
+    <groupId>cc.iotkit</groupId>
+    <version>0.1.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>http-biz-component</artifactId>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-shade-plugin</artifactId>
+        <version>3.2.4</version>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>shade</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <artifactSet>
+            <includes>
+              <include>io.vertx:vertx-web-proxy</include>
+              <include>io.vertx:vertx-web</include>
+              <include>io.vertx:vertx-bridge-common</include>
+              <include>io.vertx:vertx-http-proxy</include>
+              <include>io.vertx:vertx-core</include>
+              <include>io.netty:netty-codec-http2</include>
+            </includes>
+          </artifactSet>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>8</source>
+          <target>8</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>org.projectlombok</groupId>
+      <artifactId>lombok</artifactId>
+      <version>1.18.22</version>
+      <scope>compile</scope>
+    </dependency>
+    <dependency>
+      <groupId>io.vertx</groupId>
+      <artifactId>vertx-web-proxy</artifactId>
+      <version>4.2.2</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>cc.iotkit</groupId>
+      <artifactId>component</artifactId>
+      <version>0.1.0-SNAPSHOT</version>
+      <scope>compile</scope>
+    </dependency>
+  </dependencies>
+  <properties>
+    <maven.compiler.source>8</maven.compiler.source>
+    <maven.compiler.target>8</maven.compiler.target>
+  </properties>
+</project>

+ 38 - 6
protocol-gateway/http-biz-component/pom.xml

@@ -28,17 +28,49 @@
             <artifactId>vertx-web-proxy</artifactId>
         </dependency>
 
-        <dependency>
-            <groupId>io.vertx</groupId>
-            <artifactId>vertx-web-client</artifactId>
-        </dependency>
-
         <dependency>
             <groupId>cc.iotkit</groupId>
             <artifactId>component</artifactId>
         </dependency>
 
-
     </dependencies>
 
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <version>3.2.4</version>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                    </execution>
+                </executions>
+                <configuration>
+                    <artifactSet>
+                        <includes>
+                            <include>io.vertx:vertx-web-proxy</include>
+                            <include>io.vertx:vertx-web</include>
+                            <include>io.vertx:vertx-bridge-common</include>
+                            <include>io.vertx:vertx-http-proxy</include>
+                            <include>io.vertx:vertx-core</include>
+                            <include>io.netty:netty-codec-http2</include>
+                        </includes>
+                    </artifactSet>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>8</source>
+                    <target>8</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
 </project>

+ 80 - 43
protocol-gateway/http-biz-component/src/main/java/cc/iotkit/comp/biz/HttpBizComponent.java

@@ -6,6 +6,7 @@ import cc.iotkit.comp.IComponent;
 import io.vertx.core.MultiMap;
 import io.vertx.core.Vertx;
 import io.vertx.core.http.HttpServer;
+import io.vertx.core.http.HttpServerRequest;
 import io.vertx.core.http.HttpServerResponse;
 import io.vertx.core.json.JsonObject;
 import io.vertx.ext.web.Router;
@@ -14,16 +15,21 @@ import jdk.nashorn.api.scripting.NashornScriptEngine;
 import jdk.nashorn.api.scripting.ScriptObjectMirror;
 import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.FileUtils;
 
 import javax.script.ScriptEngineManager;
 import javax.script.ScriptException;
+import java.io.File;
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-@Slf4j
+import static java.nio.charset.StandardCharsets.UTF_8;
+
 @Data
+@Slf4j
 public class HttpBizComponent implements IComponent {
 
     private final Vertx vertx = Vertx.vertx();
@@ -32,7 +38,9 @@ public class HttpBizComponent implements IComponent {
 
     private Object scriptObj;
 
-    private HttpConfig config;
+    private CompConfig config;
+
+    private HttpConfig httpConfig;
 
     private String script;
 
@@ -40,7 +48,7 @@ public class HttpBizComponent implements IComponent {
 
     @Override
     public void create(CompConfig config) {
-        this.config = JsonUtil.parse(config.getOther(), HttpConfig.class);
+        this.httpConfig = JsonUtil.parse(config.getOther(), HttpConfig.class);
         try {
             scriptObj = engine.eval(String.format("new (function () {\n%s})()", script));
         } catch (ScriptException e) {
@@ -54,53 +62,75 @@ public class HttpBizComponent implements IComponent {
         Router backendRouter = Router.router(vertx);
         backendRouter.route().handler(BodyHandler.create())
                 .handler(rc -> {
-                    Map<String, Object> httpHeader = getData(rc.request().headers());
-                    log.info("request header:{}", JsonUtil.toJsonString(httpHeader));
-                    Map<String, List<Object>> httpParams = getListData(rc.request().params());
-                    log.info("request params:{}", JsonUtil.toJsonString(httpParams));
-
-                    String contentType = rc.request().headers().get("Content-Type");
-                    JsonObject responseHeader = new JsonObject();
-                    if ("application/json".equals(contentType)) {
-                        String bodyStr = rc.toString();
-                        Map body = JsonUtil.parse(bodyStr, Map.class);
-                        log.info("request body:{}", bodyStr);
-
-                        String response = "unknown error";
-                        String name = "onReceive";
-                        if (((ScriptObjectMirror) scriptObj).get(name) != null) {
-                            try {
-                                Object result = engine.invokeMethod(scriptObj, name, body);
-                                Object resultObj = JsonUtil.toObject((ScriptObjectMirror) result);
-                                if (resultObj instanceof Map) {
-                                    JsonObject data = JsonObject.mapFrom(resultObj);
-                                    responseHeader = data.getJsonObject("header");
-                                    response = data.getString("content");
+                    try {
+                        Map<String, Object> httpHeader = getData(rc.request().headers());
+                        log.info("request header:{}", JsonUtil.toJsonString(httpHeader));
+                        Map<String, List<Object>> httpParams = getListData(rc.request().params());
+                        log.info("request params:{}", JsonUtil.toJsonString(httpParams));
+
+                        HttpServerRequest httpRequest = rc.request();
+                        String contentType = httpRequest.headers().get("Content-Type");
+                        JsonObject responseHeader = new JsonObject();
+                        if ("application/json".equals(contentType)) {
+                            String bodyStr = rc.getBody().toString();
+                            Map body = JsonUtil.parse(bodyStr, Map.class);
+                            log.info("request body:{}", bodyStr);
+
+                            String response = "unknown error";
+                            String name = "onReceive";
+                            if (((ScriptObjectMirror) scriptObj).get(name) != null) {
+                                try {
+                                    Object result = engine.invokeMethod(scriptObj,
+                                            name,
+                                            httpRequest.method().name(),
+                                            httpRequest.path(),
+                                            httpHeader,
+                                            httpParams,
+                                            body);
+                                    Object resultObj = JsonUtil.toObject((ScriptObjectMirror) result);
+                                    if (resultObj instanceof Map) {
+                                        JsonObject data = JsonObject.mapFrom(resultObj);
+                                        responseHeader = data.getJsonObject("header");
+                                        response = data.getString("content");
+                                        response = response == null ? "" : response;
+                                    }
+                                } catch (Throwable e) {
+                                    log.error("invokeMethod onReceive error", e);
+                                    response = e.getMessage();
                                 }
-                            } catch (Throwable e) {
-                                log.error("invokeMethod onReceive error", e);
-                                response = e.getMessage();
+                            } else {
+                                log.error("required [onReceive] method");
                             }
+
+                            HttpServerResponse httpServerResponse = rc.response();
+                            //设置响应头
+                            responseHeader.getMap().forEach((key, value) -> {
+                                //大写转换
+                                key = key.replaceAll("([A-Z])", "-$1").toLowerCase();
+                                httpServerResponse.putHeader(key, value.toString());
+                            });
+
+                            log.info("response,header:{},content:{}", responseHeader, response);
+                            //设置响应内容
+                            httpServerResponse
+                                    .end(response);
                         } else {
-                            log.error("required [onReceive] method");
+                            rc.response().end("");
                         }
-
-                        HttpServerResponse httpServerResponse = rc.response();
-                        //设置响应头
-                        responseHeader.getMap().forEach((key, value) -> {
-                            //大写转换
-                            key = key.replaceAll("([A-Z])", "-$1").toLowerCase();
-                            httpServerResponse.putHeader(key, value.toString());
-                        });
-
-                        log.info("response,header:{},content:{}", responseHeader, response);
-                        //设置响应内容
-                        httpServerResponse
-                                .end(response);
+                    } catch (Throwable e) {
+                        log.error("handle request error", e);
+                        rc.response().end("server error:" + e.getMessage());
                     }
                 });
 
-        backendServer.requestHandler(backendRouter).listen(config.getPort());
+        backendServer.requestHandler(backendRouter)
+                .listen(httpConfig.getPort(), (http) -> {
+                    if (http.succeeded()) {
+                        log.info("http server create succeed,port:{}", httpConfig.getPort());
+                    } else {
+                        log.error("http server create failed", http.cause());
+                    }
+                });
     }
 
     @Override
@@ -131,4 +161,11 @@ public class HttpBizComponent implements IComponent {
         return data;
     }
 
+    public static void main(String[] args) throws IOException {
+        HttpBizComponent component = new HttpBizComponent();
+        component.setScript(FileUtils.readFileToString(new File("/Users/sjg/home/gitee/open-source/iotkit-parent/protocol-gateway/http-biz-component/src/main/resources/component.js"), UTF_8));
+        component.create(new CompConfig(1000, "{\"port\":9081}"));
+        component.start();
+    }
+
 }

+ 36 - 0
protocol-gateway/http-biz-component/src/main/java/cc/iotkit/comp/biz/HttpConfig.java

@@ -0,0 +1,36 @@
+//引用api工具类
+var apiTool = Java.type("cc.iotkit.comp.biz.ApiTool");
+//api配置
+apiTool.config("http://localhost",8086,3000);
+
+this.onReceive=function(method,path,header,params,body){
+  //method:post、get、delete...
+  //path:请求路径
+  //header:http请求头数据,结构:{xx:xx,yy:yy}
+  //params:请求参数,结构:{xx:[...],yy:[...]}
+  //body:请求体,当提交的数据为json格式时使用,结构:{xx:xx,yy:yy}
+  apiTool.log("onReceive method:"+method);
+  apiTool.log("onReceive path:"+path);
+  apiTool.log("onReceive header:"+header);
+  apiTool.log("onReceive params:"+params);
+  apiTool.log("onReceive body:"+body);
+  var duHeader=body.header;
+  var namespace=duHeader.namespace;
+  var requestName=duHeader.name;
+  var messageId=duHeader.messageId;
+  var duPayload=duHeader.payload;
+  var token=duHeader.accessToken;
+
+  //设备发现
+  if(namespace=="DuerOS.ConnectedHome.Discovery" && requestName=="DiscoverAppliancesRequest"){
+
+  }
+
+  return {
+    url:"xx",//不指定直接作为响应返回
+    header:{
+      contentType:"xx"
+    },
+    content:"xx"
+  }
+}

+ 2 - 2
protocol-gateway/http-biz-component/src/main/resources/component.spi

@@ -11,8 +11,8 @@ public class Application {
     public static void main(String[] args) throws IOException {
 
         if (args.length == 0) {
-//            Mqtt.broker = "tcp://127.0.0.1:1883";
-            Mqtt.broker = "tcp://120.76.96.206:1883";
+            Mqtt.broker = "tcp://127.0.0.1:1883";
+//            Mqtt.broker = "tcp://120.76.96.206:1883";
         } else {
             Mqtt.broker = args[0];
         }

+ 2 - 2
protocol-gateway/mqtt-component/dependency-reduced-pom.xml

@@ -43,13 +43,13 @@
     <dependency>
       <groupId>io.vertx</groupId>
       <artifactId>vertx-core</artifactId>
-      <version>4.2.6</version>
+      <version>4.2.2</version>
       <scope>provided</scope>
     </dependency>
     <dependency>
       <groupId>io.vertx</groupId>
       <artifactId>vertx-mqtt</artifactId>
-      <version>4.2.6</version>
+      <version>4.2.2</version>
       <scope>provided</scope>
     </dependency>
     <dependency>

+ 0 - 0
protocol-gateway/mqtt-component/src/main/java/cc/iotkit/comp/mqtt/MqttDeviceComponent.java