diff --git a/common/src/main/java/cc/iotkit/common/Constants.java b/common/src/main/java/cc/iotkit/common/Constants.java index 1882fdf5..695eed54 100755 --- a/common/src/main/java/cc/iotkit/common/Constants.java +++ b/common/src/main/java/cc/iotkit/common/Constants.java @@ -88,7 +88,21 @@ public interface Constants { ThirdPlatform(String desc) { this.desc = desc; } + } + /** + * 三方平台openUid名称 + */ + enum ThirdOpenUid{ + duerosOpenUid("小度OpenUid"), + aligenieOpenUid("天猫精灵OpenUid"), + miiotOpenUid("小爱OpenUid"); + + public String desc; + + ThirdOpenUid(String desc) { + this.desc = desc; + } } interface API_DEVICE { @@ -161,6 +175,11 @@ public interface Constants { * 获取空间设备信息 */ String GET_DEVICE = "/device/{deviceId}"; + + /** + * 设置第三方平台openUid + */ + String SET_OPEN_UID = "/setOpenUid"; } interface MQTT { diff --git a/manager/src/main/java/cc/iotkit/manager/config/GlobalExceptionHandler.java b/manager/src/main/java/cc/iotkit/manager/config/GlobalExceptionHandler.java index cc56bfed..226a3512 100755 --- a/manager/src/main/java/cc/iotkit/manager/config/GlobalExceptionHandler.java +++ b/manager/src/main/java/cc/iotkit/manager/config/GlobalExceptionHandler.java @@ -2,6 +2,7 @@ package cc.iotkit.manager.config; import cn.dev33.satoken.exception.NotLoginException; import cn.dev33.satoken.exception.NotPermissionException; +import cn.dev33.satoken.exception.NotRoleException; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @@ -25,7 +26,7 @@ public class GlobalExceptionHandler { return new RequestResult("401", "未授权的请求"); } - if (e instanceof NotPermissionException) { + if (e instanceof NotPermissionException || e instanceof NotRoleException) { response.setStatus(403); return new RequestResult("403", "没有权限"); } diff --git a/manager/src/main/java/cc/iotkit/manager/config/SaTokenConfigure.java b/manager/src/main/java/cc/iotkit/manager/config/SaTokenConfigure.java index d056e72f..3a6230c6 100755 --- a/manager/src/main/java/cc/iotkit/manager/config/SaTokenConfigure.java +++ b/manager/src/main/java/cc/iotkit/manager/config/SaTokenConfigure.java @@ -36,6 +36,7 @@ public class SaTokenConfigure implements WebMvcConfigurer { "/space/addDevice/**", "/space/saveDevice", "/space/removeDevice", + "/space/setOpenUid", "/space/device/*", "/device/*/consumer/*", "/device/*/service/property/set", diff --git a/manager/src/main/java/cc/iotkit/manager/controller/DeviceController.java b/manager/src/main/java/cc/iotkit/manager/controller/DeviceController.java index a9a94b0e..e9d76a29 100755 --- a/manager/src/main/java/cc/iotkit/manager/controller/DeviceController.java +++ b/manager/src/main/java/cc/iotkit/manager/controller/DeviceController.java @@ -2,7 +2,6 @@ package cc.iotkit.manager.controller; import cc.iotkit.common.Constants; import cc.iotkit.common.exception.BizException; -import cc.iotkit.common.utils.CodecUtil; import cc.iotkit.common.utils.DeviceUtil; import cc.iotkit.common.utils.UniqueIdUtil; import cc.iotkit.comps.service.DeviceBehaviourService; @@ -31,7 +30,6 @@ import org.springframework.web.context.request.async.DeferredResult; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.UUID; @Slf4j @RestController diff --git a/manager/src/main/java/cc/iotkit/manager/controller/SpaceDeviceController.java b/manager/src/main/java/cc/iotkit/manager/controller/SpaceDeviceController.java index 002bc387..5c8f12b3 100755 --- a/manager/src/main/java/cc/iotkit/manager/controller/SpaceDeviceController.java +++ b/manager/src/main/java/cc/iotkit/manager/controller/SpaceDeviceController.java @@ -102,12 +102,18 @@ public class SpaceDeviceController { .build(); } + /** + * 获取用户所有设备列表 + */ @GetMapping("/{userId}/devices") public List getDevices(@PathVariable("userId") String userId) { List spaceDevices = spaceDeviceRepository.findAll(Example.of(SpaceDevice.builder().uid(userId).build())); return spaceDevices.stream().map((this::parseSpaceDevice)).collect(Collectors.toList()); } + /** + * 搜索未添加过的设备 + */ @GetMapping(Constants.API_SPACE.FIND_DEVICE) List findDevice(String mac) { if (StringUtils.isBlank(mac)) { @@ -155,6 +161,9 @@ public class SpaceDeviceController { return findDeviceVo; } + /** + * 往指定房间中添加设备 + */ @PostMapping(Constants.API_SPACE.ADD_DEVICE) public void addDevice(SpaceDevice device) { String deviceId = device.getDeviceId(); @@ -202,7 +211,7 @@ public class SpaceDeviceController { subUid.add(uid); } - //更新设备标签 + //更新设备标签,标识设备是用的哪个第三方平台 List platforms = optUser.get().getUsePlatforms(); Map tags = deviceInfo.getTag(); for (String platform : platforms) { @@ -213,6 +222,9 @@ public class SpaceDeviceController { deviceRepository.save(deviceInfo); } + /** + * 移除房间中的设备 + */ @DeleteMapping(Constants.API_SPACE.REMOVE_DEVICE) public void removeDevice(String deviceId) { String uid = AuthUtil.getUserId(); @@ -225,7 +237,7 @@ public class SpaceDeviceController { spaceDeviceRepository.deleteById(spaceDevice.getId()); DeviceInfo deviceInfo = deviceRepository.findByDeviceId(deviceId); Optional optUser = userInfoRepository.findById(uid); - if (!optUser.isPresent()) { + if (optUser.isEmpty()) { throw new BizException("user does not exist"); } @@ -240,11 +252,14 @@ public class SpaceDeviceController { deviceRepository.save(deviceInfo); } + /** + * 保存房间设备信息 + */ @PostMapping(Constants.API_SPACE.SAVE_DEVICE) public void saveDevice(SpaceDevice spaceDevice) { dataOwnerService.checkOwner(spaceDevice); Optional optData = spaceDeviceRepository.findById(spaceDevice.getId()); - if (!optData.isPresent()) { + if (optData.isEmpty()) { throw new BizException("space device does not exist"); } SpaceDevice oldData = optData.get(); @@ -253,6 +268,9 @@ public class SpaceDeviceController { spaceDeviceRepository.save(oldData); } + /** + * 获取房间中指定设备信息 + */ @GetMapping(Constants.API_SPACE.GET_DEVICE) public SpaceDeviceVo getSpaceDevice(@PathVariable("deviceId") String deviceId) { String uid = AuthUtil.getUserId(); @@ -262,4 +280,28 @@ public class SpaceDeviceController { spaceDeviceRepository.save(spaceDevice); return parseSpaceDevice(spaceDevice); } + + /** + * 设置设备的第三方平台openUid + * 如:小度接入使用的openUid + */ + @PostMapping(Constants.API_SPACE.SET_OPEN_UID) + public void setOpenUid(String deviceId, String platform, String openUid) { + SpaceDevice spaceDevice = spaceDeviceRepository.findByDeviceId(deviceId); + if (spaceDevice == null) { + throw new BizException("space device does not exist"); + } + + //只能修改自己的设备 + dataOwnerService.checkOwner(spaceDevice); + + //找到设备 + DeviceInfo deviceInfo = deviceRepository.findByDeviceId(deviceId); + Map tags = deviceInfo.getTag(); + String openUidName = platform + "OpenUid"; + //给设备添加对应平台openUid的设备标签 + Constants.ThirdOpenUid thirdOpenUid = Constants.ThirdOpenUid.valueOf(openUidName); + tags.put(openUidName, new DeviceInfo.Tag(openUidName, thirdOpenUid.desc, openUid)); + deviceRepository.save(deviceInfo); + } } diff --git a/protocol-gateway/component-server/src/main/java/cc/iotkit/comps/ApiTool.java b/protocol-gateway/component-server/src/main/java/cc/iotkit/comps/ApiTool.java index 21d693b4..c2300535 100755 --- a/protocol-gateway/component-server/src/main/java/cc/iotkit/comps/ApiTool.java +++ b/protocol-gateway/component-server/src/main/java/cc/iotkit/comps/ApiTool.java @@ -1,10 +1,12 @@ package cc.iotkit.comps; import cc.iotkit.common.Constants; +import io.vertx.core.MultiMap; 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.HttpResponse; import io.vertx.ext.web.client.WebClient; import io.vertx.ext.web.client.WebClientOptions; import lombok.AllArgsConstructor; @@ -90,6 +92,19 @@ public class ApiTool { return send(token, HttpMethod.POST, request, new HashMap<>()); } + /** + * 设置第三方平台的openUid + */ + public ApiResponse setOpenUid(String token, String deviceId, String platform, String openUid) { + HttpRequest request = client + .post(port, host, getSpacePath(Constants.API_SPACE.SET_OPEN_UID)); + Map map = new HashMap<>(); + map.put("deviceId", deviceId); + map.put("platform", platform); + map.put("openUid", openUid); + return send(token, HttpMethod.POST, request, map, false); + } + /** * 获取设备详情 */ @@ -121,7 +136,17 @@ public class ApiTool { return send(token, HttpMethod.POST, request, params); } - private ApiResponse send(String token, HttpMethod method, HttpRequest request, Map params) { + private ApiResponse send(String token, HttpMethod method, + HttpRequest request, + Map params) { + return send(token, method, request, params, true); + } + + private ApiResponse send(String token, HttpMethod method, + HttpRequest request, + Map params, + boolean isJson + ) { request = request .timeout(timeout) .putHeader("wrap-response", "json") @@ -133,29 +158,23 @@ public class ApiTool { //转为同步模式便于提供给js调用 CountDownLatch wait = new CountDownLatch(1); - if (method == HttpMethod.POST) { + if (method == HttpMethod.POST && isJson) { request.sendJson(params) - .onSuccess((response) -> { - log.info("send succeed,response:{}", response.bodyAsString()); - apiResponse.set(response.bodyAsJson(ApiResponse.class)); - wait.countDown(); - }) - .onFailure((err) -> { - log.error("send failed", err); - wait.countDown(); - }); - } else if (method == HttpMethod.GET) { + .onSuccess((response) -> onSendSuccess(apiResponse, wait, response)) + .onFailure((err) -> onSendFail(wait, err)); + } else if (method == HttpMethod.POST) { + //添加表单参数 + MultiMap multiMap = MultiMap.caseInsensitiveMultiMap(); + params.forEach((k, v) -> multiMap.add(k, v.toString())); + request.sendForm(multiMap) + .onSuccess((response) -> onSendSuccess(apiResponse, wait, response)) + .onFailure((err) -> onSendFail(wait, err)); + } else { request.send() - .onSuccess((response) -> { - log.info("send succeed,response:{}", response.bodyAsString()); - apiResponse.set(response.bodyAsJson(ApiResponse.class)); - wait.countDown(); - }) - .onFailure((err) -> { - log.error("send failed", err); - wait.countDown(); - }); + .onSuccess((response) -> onSendSuccess(apiResponse, wait, response)) + .onFailure((err) -> onSendFail(wait, err)); } + if (wait.await(timeout, TimeUnit.MILLISECONDS)) { return apiResponse.get(); } else { @@ -170,6 +189,17 @@ public class ApiTool { return apiResponse.get(); } + private void onSendFail(CountDownLatch wait, Throwable err) { + log.error("send failed", err); + wait.countDown(); + } + + private void onSendSuccess(AtomicReference apiResponse, CountDownLatch wait, HttpResponse response) { + log.info("send succeed,response:{}", response.bodyAsString()); + apiResponse.set(response.bodyAsJson(ApiResponse.class)); + wait.countDown(); + } + public void log(String msg) { log.info(msg); } diff --git a/rule-engine/src/main/java/cc/iotkit/ruleengine/action/ScriptService.java b/rule-engine/src/main/java/cc/iotkit/ruleengine/action/ScriptService.java index a15afb8b..fb2cea27 100755 --- a/rule-engine/src/main/java/cc/iotkit/ruleengine/action/ScriptService.java +++ b/rule-engine/src/main/java/cc/iotkit/ruleengine/action/ScriptService.java @@ -1,6 +1,8 @@ package cc.iotkit.ruleengine.action; import cc.iotkit.common.utils.JsonUtil; +import cc.iotkit.dao.DeviceCache; +import cc.iotkit.model.device.DeviceInfo; import cc.iotkit.model.device.message.ThingModelMessage; import jdk.nashorn.api.scripting.NashornScriptEngine; import jdk.nashorn.api.scripting.ScriptObjectMirror; @@ -21,13 +23,24 @@ public class ScriptService { private ScriptObjectMirror scriptObject; + private DeviceCache deviceCache; + public Map execScript(ThingModelMessage msg) { try { if (scriptObject == null) { scriptObject = (ScriptObjectMirror) engine.eval("new (function(){" + script + "})()"); } + //取设备信息 + DeviceInfo deviceInfo = deviceCache.get(msg.getDeviceId()); + //执行转换脚本 - ScriptObjectMirror result = (ScriptObjectMirror) engine.invokeMethod(scriptObject, "translate", msg); + ScriptObjectMirror result = (ScriptObjectMirror) engine + .invokeMethod(scriptObject, "translate", msg, deviceInfo); + + if (result == null) { + return null; + } + Object objResult = JsonUtil.toObject(result); if (!(objResult instanceof Map)) { return null; diff --git a/rule-engine/src/main/java/cc/iotkit/ruleengine/rule/RuleManager.java b/rule-engine/src/main/java/cc/iotkit/ruleengine/rule/RuleManager.java index e1f38843..c1e05f02 100755 --- a/rule-engine/src/main/java/cc/iotkit/ruleengine/rule/RuleManager.java +++ b/rule-engine/src/main/java/cc/iotkit/ruleengine/rule/RuleManager.java @@ -5,10 +5,7 @@ import cc.iotkit.dao.DeviceCache; import cc.iotkit.dao.RuleInfoRepository; import cc.iotkit.model.rule.RuleAction; import cc.iotkit.model.rule.RuleInfo; -import cc.iotkit.ruleengine.action.Action; -import cc.iotkit.ruleengine.action.DeviceAction; -import cc.iotkit.ruleengine.action.DeviceActionService; -import cc.iotkit.ruleengine.action.HttpAction; +import cc.iotkit.ruleengine.action.*; import cc.iotkit.ruleengine.config.RuleConfiguration; import cc.iotkit.ruleengine.filter.DeviceFilter; import cc.iotkit.ruleengine.filter.Filter; @@ -132,7 +129,11 @@ public class RuleManager { action.setDeviceActionService(deviceActionService); return action; } else if (HttpAction.TYPE.equals(type)) { - return parse(config, HttpAction.class); + HttpAction httpAction = parse(config, HttpAction.class); + for (HttpService service : httpAction.getServices()) { + service.setDeviceCache(deviceCache); + } + return httpAction; } return null; }