diff --git a/iot-module/iot-manager/pom.xml b/iot-module/iot-manager/pom.xml index ab7e443a..3531b9fe 100644 --- a/iot-module/iot-manager/pom.xml +++ b/iot-module/iot-manager/pom.xml @@ -108,6 +108,11 @@ iot-common-satoken + + cc.iotkit + iot-common-excel + + diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/ProtocolController.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/ProtocolController.java index 21ec3b3e..67e0f74c 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/ProtocolController.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/ProtocolController.java @@ -10,6 +10,7 @@ package cc.iotkit.manager.controller; import cc.iotkit.common.api.PageRequest; +import cc.iotkit.common.api.Request; import cc.iotkit.common.enums.ErrCode; import cc.iotkit.common.exception.BizException; import cc.iotkit.common.satoken.utils.AuthUtil; @@ -19,15 +20,24 @@ import cc.iotkit.comps.config.ComponentConfig; import cc.iotkit.data.manager.IProtocolComponentData; import cc.iotkit.data.manager.IProtocolConverterData; import cc.iotkit.data.manager.IUserInfoData; +import cc.iotkit.manager.dto.bo.ChangeStateBo; +import cc.iotkit.manager.dto.bo.protocolcomponent.ProtocolComponentBo; +import cc.iotkit.manager.dto.bo.protocolconverter.ProtocolConverterBo; +import cc.iotkit.manager.dto.vo.protocolcomponent.ProtocolComponentVo; +import cc.iotkit.manager.dto.vo.protocolconverter.ProtocolConverterVo; import cc.iotkit.manager.service.DataOwnerService; import cc.iotkit.common.api.Paging; +import cc.iotkit.manager.service.IProtocolService; import cc.iotkit.model.protocol.ProtocolComponent; import cc.iotkit.model.protocol.ProtocolConverter; import io.swagger.annotations.Api; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StringUtils; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -38,315 +48,108 @@ import java.util.Objects; import java.util.UUID; @Api(tags = {"协议"}) -@Slf4j @RestController @RequestMapping("/protocol") public class ProtocolController { @Autowired - private ComponentConfig componentConfig; - - @Autowired - private IProtocolComponentData protocolComponentData; - - @Autowired - private IProtocolConverterData protocolConverterData; - - @Autowired - private DataOwnerService dataOwnerService; - - @Autowired - private IUserInfoData userInfoData; - - @Autowired - private ComponentManager componentManager; + private IProtocolService protocolService; + @ApiOperation("上传Jar包") @PostMapping("/uploadJar") public String uploadJar( @RequestParam("file") MultipartFile file, @RequestParam("id") String id) { - if (file == null) { - throw new BizException(ErrCode.PARAMS_EXCEPTION); - } - log.info("saving upload jar file:{}", file.getName()); - String fileName = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename())); - try { - if (StringUtils.hasLength(id)) { - getAndCheckComponent(id); - } else { - id = UUID.randomUUID().toString(); - } - Path jarFilePath = componentConfig.getComponentFilePath(id); - Files.createDirectories(jarFilePath); - Path targetLocation = jarFilePath.resolve(fileName); - Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING); - return id; - } catch (IOException ex) { - throw new BizException(ErrCode.UPLOAD_FILE_ERROR, ex); - } + return protocolService.uploadJar(file, id); } + @ApiOperation("添加组件") @PostMapping("/addComponent") - public void addComponent(ProtocolComponent component) { - String id = component.getId(); - //jar包上传后生成的id - if (!StringUtils.hasLength(id)) { - throw new BizException(ErrCode.COMPONENT_ID_BLANK); - } - Path jarPath = componentConfig.getComponentFilePath(id); - if (!jarPath.resolve(component.getJarFile()).toFile().exists()) { - throw new BizException(ErrCode.COMPONENT_JAR_NOT_FOUND); - } - - ProtocolComponent protocolComponent = protocolComponentData.findById(id); - if (protocolComponent != null) { - throw new BizException(ErrCode.COMPONENT_ALREADY); - } - try { - component.setCreateAt(System.currentTimeMillis()); - component.setUid(AuthUtil.getUserId()); - protocolComponentData.save(component); - } catch (Throwable e) { - throw new BizException(ErrCode.ADD_COMPONENT_ERROR, e); - } + public boolean addComponent(ProtocolComponentBo component) { + return protocolService.addComponent(component); } - @PostMapping("/saveComponent") - public void saveComponent(ProtocolComponent component) { - String id = component.getId(); - if (!StringUtils.hasLength(id)) { - throw new BizException(ErrCode.COMPONENT_ID_BLANK); - } - Path jarPath = componentConfig.getComponentFilePath(id); - if (!jarPath.resolve(component.getJarFile()).toFile().exists()) { - throw new BizException(ErrCode.COMPONENT_JAR_NOT_FOUND); - } - - ProtocolComponent oldComponent = getAndCheckComponent(id); - component = ReflectUtil.copyNoNulls(component, oldComponent); - - try { - componentManager.deRegister(id); - protocolComponentData.save(component); - } catch (Throwable e) { - throw new BizException(ErrCode.ADD_COMPONENT_ERROR, e); - } + @ApiOperation("修改组件") + @PostMapping("/editComponent") + public String saveComponent(ProtocolComponentBo component) { + return protocolService.saveComponent(component); } - @GetMapping("/getComponentScript/{id}") - public ProtocolComponent getComponentScript(@PathVariable("id") String id) { - ProtocolComponent component = getAndCheckComponent(id); - - String script = component.getScript(); - // 如果数据库里不存在,则从文件中读取脚本 - if(!StringUtils.hasText(script)){ - try { - File file = getComponentScriptFile(id); - script = FileUtils.readFileToString(file, "UTF-8"); - } catch (Throwable e) { - log.error("read converter script file error", e); - script = ""; - } - component.setScript(script); - } - return component; + @ApiOperation("获取组件详情") + @PostMapping("/getComponentDetail") + public ProtocolComponentVo getComponentScript(@Validated @RequestBody Request req) { + String id = req.getData(); + return protocolService.getProtocolComponent(id); } - @PostMapping("/saveComponentScript/{id}") - public void saveComponentScript( - @PathVariable("id") String id, - @RequestBody ProtocolComponent upReq) { - ProtocolComponent old = getAndCheckComponent(id); - try { - // 保存到文件 - File file = getComponentScriptFile(id); - String script = upReq.getScript(); - FileUtils.writeStringToFile(file, script, "UTF-8", false); - - // 保存到数据库,后续加版本号 - old.setScript(upReq.getScript()); - old.setScriptTyp(upReq.getScriptTyp()); - protocolComponentData.save(old); - - componentManager.deRegister(id); - } catch (Throwable e) { - throw new BizException(ErrCode.SAVE_COMPONENT_SCRIPT_ERROR, e); - } + @ApiOperation("保存组件脚本") + @PostMapping("/saveComponentScript") + public boolean saveComponentScript( + @RequestBody ProtocolComponentBo upReq) { + return protocolService.saveComponentScript(upReq); } - private File getComponentScriptFile(String id) { - Path path = componentConfig.getComponentFilePath(id); - return path.resolve(ProtocolComponent.SCRIPT_FILE_NAME).toFile(); + + @ApiOperation("删除组件") + @PostMapping("/delete") + public boolean deleteComponent(@Validated @RequestBody Request req) { + return protocolService.deleteComponent(req.getData()); } - private ProtocolComponent getAndCheckComponent(@PathVariable("id") String id) { - ProtocolComponent oldComponent = protocolComponentData.findById(id); - if (oldComponent == null) { - throw new BizException(ErrCode.COMPONENT_NOT_FOUND); - } - dataOwnerService.checkOwner(oldComponent); - return oldComponent; - } - - @PostMapping("/deleteComponent/{id}") - public void deleteComponent(@PathVariable("id") String id) { - ProtocolComponent component = getAndCheckComponent(id); - try { - componentManager.deRegister(id); - - Path path = Paths.get(String.format("%s/%s", componentConfig.getComponentDir(), id)) - .toAbsolutePath().normalize(); - File file = path.toFile(); - try { - if (file.isDirectory()) { - FileUtils.deleteDirectory(file); - } else { - FileUtils.delete(file); - } - } catch (NoSuchFileException e) { - log.warn("delete component script error", e); - } - protocolComponentData.deleteById(component.getId()); - } catch (Throwable e) { - throw new BizException(ErrCode.DELETE_COMPONENT_ERROR, e); - } - } - - @PostMapping("/components/{size}/{page}") - public Paging getComponents( - PageRequest query ) { - Paging components = protocolComponentData.findAll(query); - components.getData().forEach(c -> c.setState( - componentManager.isRunning(c.getId()) ? - ProtocolComponent.STATE_RUNNING : ProtocolComponent.STATE_STOPPED - )); - return components; + @ApiOperation("获取组件列表") + @PostMapping("/list") + public Paging getComponents(@Validated @RequestBody + PageRequest query) { + return protocolService.selectPageList(query); } + @ApiOperation("获取转换脚本列表") @PostMapping("/converters/list") - public Paging getConverters(PageRequest query) { - return protocolConverterData.findAll(query); + public Paging getConverters(@Validated @RequestBody PageRequest query) { + return protocolService.selectConvertersPageList(query); } + @ApiOperation("新增转换脚本") @PostMapping("/addConverter") - public void addConverter(ProtocolConverter converter) { - try { - converter.setId(null); - converter.setCreateAt(System.currentTimeMillis()); - converter.setUid(AuthUtil.getUserId()); - protocolConverterData.save(converter); - } catch (Throwable e) { - throw new BizException(ErrCode.ADD_CONVERT_ERROR, e); - } - } - - @PostMapping("/saveConverter") - public void saveConverter(ProtocolConverter converter) { - ProtocolConverter oldConverter = getAndCheckConverter(converter.getId()); - converter = ReflectUtil.copyNoNulls(converter, oldConverter); - try { - protocolConverterData.save(converter); - } catch (Throwable e) { - throw new BizException(ErrCode.ADD_CONVERT_ERROR, e); - } - } - - private ProtocolConverter getAndCheckConverter(String id) { - ProtocolConverter converter = protocolConverterData.findById(id); - if (converter == null) { - throw new BizException(ErrCode.CONVERT_NOT_FOUND); - } - - dataOwnerService.checkOwner(converter); - return converter; - } - - @GetMapping("/getConverterScript/{id}") - public ProtocolConverter getConverterScript(@PathVariable("id") String id) { - ProtocolConverter converter = getAndCheckConverter(id); - String script = converter.getScript(); - // 如果数据库里不存在,则从文件中读取脚本 - if(!StringUtils.hasText(script)){ - try { - Path path = componentConfig.getConverterFilePath(id); - File file = path.resolve(ProtocolConverter.SCRIPT_FILE_NAME).toFile(); - script = FileUtils.readFileToString(file, "UTF-8"); - } catch (Throwable e) { - log.error("read converter script file error", e); - script = ""; - } - converter.setScript(script); - } - return converter; + public boolean addConverter(@Validated @RequestBody ProtocolConverterBo converter) { + return protocolService.addConverter(converter); } - @PostMapping("/saveConverterScript/{id}") - public void saveConverterScript( - @PathVariable("id") String id, - @RequestBody ProtocolConverter converter) { - getAndCheckConverter(id); - try { - // 先存文件 - Path path = componentConfig.getConverterFilePath(id); - File file = path.resolve(ProtocolConverter.SCRIPT_FILE_NAME).toFile(); - String script = converter.getScript(); - FileUtils.writeStringToFile(file, script, "UTF-8", false); - - // 再存数据库 - protocolConverterData.save(converter); - - } catch (Throwable e) { - throw new BizException(ErrCode.SAVE_CONVERT_SCRIPT_ERROR, e); - } + @ApiOperation("修改转换脚本") + @PostMapping("/editConverter") + public boolean editConverter(ProtocolConverterBo req) { + return protocolService.editConverter(req); } - @PostMapping("/deleteConverter/{id}") - public void deleteConverter(@PathVariable("id") String id) { - getAndCheckConverter(id); - try { - Path path = Paths.get(String.format("%s/%s", componentConfig.getConverterDir(), id)) - .toAbsolutePath().normalize(); - File file = path.toFile(); - try { - if (file.isDirectory()) { - FileUtils.deleteDirectory(file); - } else { - FileUtils.delete(file); - } - } catch (NoSuchFileException e) { - log.warn("delete converter script error", e); - } - protocolConverterData.deleteById(id); - } catch (Throwable e) { - throw new BizException(ErrCode.DELETE_CONVERT_ERROR, e); - } + + + @ApiOperation("获取转换脚本详情") + @PostMapping("/getConverterScript/{id}") + public ProtocolConverterVo getConverter(@RequestBody Request req) { + String id = req.getData(); + + return protocolService.getConverter(id); + + } + + @PostMapping("/saveConverterScript") + public boolean saveConverterScript( + @Validated @RequestBody ProtocolConverterBo req) { + + return protocolService.saveConverterScript(req); + } + + @PostMapping("/deleteConverter") + public boolean deleteConverter(@RequestBody @Validated Request req) { + String id = req.getData(); + return protocolService.deleteConverter(id); } @PostMapping("/component/{id}/state/{state}") - public void changeComponentState(@PathVariable("id") String id, - @PathVariable("state") String state) { - ProtocolComponent component = getAndCheckComponent(id); - if (ProtocolComponent.TYPE_DEVICE.equals(component.getType())&&ProtocolComponent.CONVER_TYPE_CUSTOM.equals(component.getConverType())) { - String converterId = component.getConverter(); - getAndCheckConverter(converterId); - } - - if (ProtocolComponent.STATE_RUNNING.equals(state)) { - File scriptFile = getComponentScriptFile(id); - if (!scriptFile.exists()) { - throw new BizException("请先编写组件脚本"); - } - - componentManager.register(component); - componentManager.start(component.getId()); - component.setState(ProtocolComponent.STATE_RUNNING); - } else { - componentManager.deRegister(id); - component.setState(ProtocolComponent.STATE_STOPPED); - } - protocolComponentData.save(component); + public boolean changeComponentState(@RequestBody @Validated ChangeStateBo req) { + return protocolService.changeComponentState(req); } } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/ChangeStateBo.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/ChangeStateBo.java new file mode 100644 index 00000000..f60ae9a0 --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/ChangeStateBo.java @@ -0,0 +1,33 @@ +package cc.iotkit.manager.dto.bo; + +import cc.iotkit.common.api.BaseDto; +import cc.iotkit.model.protocol.ProtocolComponent; +import io.github.linpeilie.annotations.AutoMapper; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Size; + + +@ApiModel(value = "ProtocolComponentBo") +@Data +@EqualsAndHashCode(callSuper = true) +@AutoMapper(target = ProtocolComponent.class, reverseConvertGenerate = false) +public class ChangeStateBo extends BaseDto { + private static final long serialVersionUID = -1L; + + @NotBlank(message = "id不能为空") + @ApiModelProperty(value = "") + private String id; + + + @NotBlank(message = "state不能为空") + @ApiModelProperty(value = "运行状态") + @Size(max = 255, message = "运行状态长度不正确") + private String state; + + +} diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/protocolcomponent/ProtocolComponentBo.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/protocolcomponent/ProtocolComponentBo.java index 79bc9e48..9f62be5d 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/protocolcomponent/ProtocolComponentBo.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/protocolcomponent/ProtocolComponentBo.java @@ -1,22 +1,85 @@ package cc.iotkit.manager.dto.bo.protocolcomponent; - -import cc.iotkit.common.api.PageRequest; import cc.iotkit.model.protocol.ProtocolComponent; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.Size; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Date; +import java.math.BigDecimal; + +import cc.iotkit.common.api.BaseDto; +import cc.iotkit.common.validate.AddGroup; +import cc.iotkit.common.validate.EditGroup; import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; import lombok.EqualsAndHashCode; -/** - * @Author: jay - * @Date: 2023/5/29 10:43 - * @Version: V1.0 - * @Description: 组件查询 - */ + +@ApiModel(value = "ProtocolComponentBo") @Data @EqualsAndHashCode(callSuper = true) @AutoMapper(target = ProtocolComponent.class, reverseConvertGenerate = false) -public class ProtocolComponentBo extends PageRequest { +public class ProtocolComponentBo extends BaseDto { + + @ApiModelProperty(value = "") + private String id; + + private static final long serialVersionUID = -1L; + + @ApiModelProperty(value = "") + @Size(max = 65535, message = "长度不正确") + private String config; + + @ApiModelProperty(value = "转换器类型") + @Size(max = 255, message = "转换器类型长度不正确") + private String converType; + + @ApiModelProperty(value = "转换脚本") + @Size(max = 255, message = "转换脚本长度不正确") + private String converter; + + @ApiModelProperty(value = "创建时间") + private Long createAt; + + @ApiModelProperty(value = "jar包") + @Size(max = 255, message = "jar包长度不正确") + private String jarFile; + + @ApiModelProperty(value = "组件名称") + @Size(max = 255, message = "组件名称长度不正确") + private String name; + + @ApiModelProperty(value = "通讯协议") + @Size(max = 255, message = "通讯协议长度不正确") + private String protocol; + + @ApiModelProperty(value = "脚本内容") + @Size(max = 65535, message = "脚本内容长度不正确") + private String script; + + @ApiModelProperty(value = "通讯脚本语言类型") + @Size(max = 255, message = "通讯脚本语言类型长度不正确") + private String scriptTyp; + + @ApiModelProperty(value = "运行状态") + @Size(max = 255, message = "运行状态长度不正确") + private String state; + + @ApiModelProperty(value = "组件类型") + @Size(max = 255, message = "组件类型长度不正确") + private String type; + + @ApiModelProperty(value = "所属性用户id") + @Size(max = 255, message = "所属性用户id长度不正确") + private String uid; } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/protocolconverter/ProtocolConverterBo.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/protocolconverter/ProtocolConverterBo.java index 8ea247fd..894632d6 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/protocolconverter/ProtocolConverterBo.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/protocolconverter/ProtocolConverterBo.java @@ -1,20 +1,61 @@ package cc.iotkit.manager.dto.bo.protocolconverter; - -import cc.iotkit.common.api.PageRequest; import cc.iotkit.model.protocol.ProtocolConverter; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.Size; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.Date; +import java.math.BigDecimal; + +import cc.iotkit.common.api.BaseDto; +import cc.iotkit.common.validate.AddGroup; +import cc.iotkit.common.validate.EditGroup; + import io.github.linpeilie.annotations.AutoMapper; import lombok.Data; import lombok.EqualsAndHashCode; -/** - * @Author: jay - * @Date: 2023/5/29 10:48 - * @Version: V1.0 - * @Description: 转换脚本查询参数 - */ + +@ApiModel(value = "ProtocolConverterBo") @Data @EqualsAndHashCode(callSuper = true) @AutoMapper(target = ProtocolConverter.class, reverseConvertGenerate = false) -public class ProtocolConverterBo extends PageRequest { +public class ProtocolConverterBo extends BaseDto { + + private static final long serialVersionUID = -1L; + + @ApiModelProperty(value = "id") + private String id; + + @ApiModelProperty(value = "创建时间") + private Long createAt; + + @ApiModelProperty(value = "描述") + @Size(max = 255, message = "描述长度不正确") + private String desc; + + @ApiModelProperty(value = "转换器名称") + @Size(max = 255, message = "转换器名称长度不正确") + private String name; + + @ApiModelProperty(value = "脚本内容") + @Size(max = 65535, message = "脚本内容长度不正确") + private String script; + + @ApiModelProperty(value = "转换脚本类型") + @Size(max = 255, message = "转换脚本类型长度不正确") + private String typ; + + @ApiModelProperty(value = "所属性用户id") + @Size(max = 255, message = "所属性用户id长度不正确") + private String uid; + } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/protocolcomponent/ProtocolComponentVo.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/protocolcomponent/ProtocolComponentVo.java index 6b2a2329..21f55602 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/protocolcomponent/ProtocolComponentVo.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/protocolcomponent/ProtocolComponentVo.java @@ -1,59 +1,80 @@ package cc.iotkit.manager.dto.vo.protocolcomponent; import cc.iotkit.model.protocol.ProtocolComponent; - -import io.github.linpeilie.annotations.AutoMapper; +import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; - +import lombok.ToString; +import java.util.Date; import java.io.Serializable; +import java.math.BigDecimal; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; -/** - * @Author: jay - * @Date: 2023/5/29 10:54 - * @Version: V1.0 - * @Description: 组件Vo - */ + +@ApiModel(value = "ProtocolComponentVo") @Data - +@ExcelIgnoreUnannotated @AutoMapper(target = ProtocolComponent.class) -public class ProtocolComponentVo implements Serializable { - private static final long serialVersionUID = 1L; +public class ProtocolComponentVo implements Serializable { - /** - * 所属性用户id - */ - @ApiModelProperty(value = "用户id") - private String uid; + private static final long serialVersionUID = -1L; - @ApiModelProperty(value = "名称") - private String name; + @ApiModelProperty(value="") + @ExcelProperty(value = "") + private String id; + @ApiModelProperty(value="") + @ExcelProperty(value = "") + private String config; - @ApiModelProperty(value = "协议类型") + @ApiModelProperty(value="转换器类型") + @ExcelProperty(value = "转换器类型") + private String converType; - private String protocol; + @ApiModelProperty(value="转换脚本") + @ExcelProperty(value = "转换脚本") + private String converter; - @ApiModelProperty(value = "jar包") - private String jarFile; + @ApiModelProperty(value="创建时间") + @ExcelProperty(value = "创建时间") + private Long createAt; - @ApiModelProperty(value = "配置") - private String config; + @ApiModelProperty(value="jar包") + @ExcelProperty(value = "jar包") + private String jarFile; - @ApiModelProperty(value = "转换器") - private String converter; + @ApiModelProperty(value="组件名称") + @ExcelProperty(value = "组件名称") + private String name; + + @ApiModelProperty(value="通讯协议") + @ExcelProperty(value = "通讯协议") + private String protocol; + + @ApiModelProperty(value="脚本内容") + @ExcelProperty(value = "脚本内容") + private String script; + + @ApiModelProperty(value="通讯脚本语言类型") + @ExcelProperty(value = "通讯脚本语言类型") + private String scriptTyp; + + @ApiModelProperty(value="运行状态") + @ExcelProperty(value = "运行状态") + private String state; + + @ApiModelProperty(value="组件类型") + @ExcelProperty(value = "组件类型") + private String type; + + @ApiModelProperty(value="所属性用户id") + @ExcelProperty(value = "所属性用户id") + private String uid; - @ApiModelProperty(value = "运行状态") - private String state; - - private Long createAt; - - @ApiModelProperty(value = "脚本类型") - private String scriptTyp; - - @ApiModelProperty(value = "脚本内容") - private String script; } diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/protocolconverter/ProtocolConverterVo.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/protocolconverter/ProtocolConverterVo.java new file mode 100644 index 00000000..92f404f5 --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/protocolconverter/ProtocolConverterVo.java @@ -0,0 +1,57 @@ +package cc.iotkit.manager.dto.vo.protocolconverter; + +import cc.iotkit.model.protocol.ProtocolConverter; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.ToString; + +import java.util.Date; +import java.io.Serializable; +import java.math.BigDecimal; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import io.github.linpeilie.annotations.AutoMapper; + + +@ApiModel(value = "ProtocolConverterVo") +@Data +@ExcelIgnoreUnannotated +@AutoMapper(target = ProtocolConverter.class) + +public class ProtocolConverterVo implements Serializable { + + private static final long serialVersionUID = -1L; + + @ApiModelProperty(value = "") + @ExcelProperty(value = "") + private String id; + + @ApiModelProperty(value = "创建时间") + @ExcelProperty(value = "创建时间") + private Long createAt; + + @ApiModelProperty(value = "描述") + @ExcelProperty(value = "描述") + private String desc; + + @ApiModelProperty(value = "转换器名称") + @ExcelProperty(value = "转换器名称") + private String name; + + @ApiModelProperty(value = "脚本内容") + @ExcelProperty(value = "脚本内容") + private String script; + + @ApiModelProperty(value = "转换脚本类型") + @ExcelProperty(value = "转换脚本类型") + private String typ; + + @ApiModelProperty(value = "所属性用户id") + @ExcelProperty(value = "所属性用户id") + private String uid; + + +} diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IProtocolService.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IProtocolService.java index 3688fc99..f023d4e7 100644 --- a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IProtocolService.java +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/IProtocolService.java @@ -1,6 +1,15 @@ package cc.iotkit.manager.service; +import cc.iotkit.common.api.PageRequest; +import cc.iotkit.common.api.Paging; +import cc.iotkit.manager.dto.bo.ChangeStateBo; +import cc.iotkit.manager.dto.bo.protocolcomponent.ProtocolComponentBo; +import cc.iotkit.manager.dto.bo.protocolconverter.ProtocolConverterBo; +import cc.iotkit.manager.dto.vo.protocolcomponent.ProtocolComponentVo; +import cc.iotkit.manager.dto.vo.protocolconverter.ProtocolConverterVo; import cc.iotkit.model.protocol.ProtocolComponent; +import cc.iotkit.model.protocol.ProtocolConverter; +import org.springframework.web.multipart.MultipartFile; /** * @Author: jay @@ -11,10 +20,34 @@ import cc.iotkit.model.protocol.ProtocolComponent; public interface IProtocolService { // 上传jar包 - String uploadJar(String jarFile, String id); + String uploadJar(MultipartFile file, String id); // 添加组件 - boolean addComponent(ProtocolComponent component); + boolean addComponent(ProtocolComponentBo component); + String saveComponent(ProtocolComponentBo component); + + ProtocolComponentVo getProtocolComponent(String id); + + boolean saveComponentScript(ProtocolComponentBo upReq); + + boolean deleteComponent(String data); + + Paging selectPageList(PageRequest query); + + Paging selectConvertersPageList(PageRequest query); + + boolean addConverter(ProtocolConverterBo converter); + + boolean editConverter(ProtocolConverterBo req); + + ProtocolConverterVo getConverter(String id); + + boolean saveConverterScript(ProtocolConverterBo req); + + boolean deleteConverter(String id); + + boolean changeComponentState(ChangeStateBo req); } + diff --git a/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/ProtocolServiceImpl.java b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/ProtocolServiceImpl.java new file mode 100644 index 00000000..55f4b282 --- /dev/null +++ b/iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/ProtocolServiceImpl.java @@ -0,0 +1,366 @@ +package cc.iotkit.manager.service.impl; + +import cc.iotkit.common.api.PageRequest; +import cc.iotkit.common.api.Paging; +import cc.iotkit.common.enums.ErrCode; +import cc.iotkit.common.exception.BizException; +import cc.iotkit.common.satoken.utils.AuthUtil; +import cc.iotkit.common.utils.MapstructUtils; +import cc.iotkit.common.utils.ReflectUtil; +import cc.iotkit.comps.ComponentManager; +import cc.iotkit.comps.config.ComponentConfig; +import cc.iotkit.data.manager.IProtocolComponentData; +import cc.iotkit.data.manager.IProtocolConverterData; +import cc.iotkit.data.manager.IUserInfoData; +import cc.iotkit.manager.dto.bo.ChangeStateBo; +import cc.iotkit.manager.dto.bo.protocolcomponent.ProtocolComponentBo; +import cc.iotkit.manager.dto.bo.protocolconverter.ProtocolConverterBo; +import cc.iotkit.manager.dto.vo.protocolcomponent.ProtocolComponentVo; +import cc.iotkit.manager.dto.vo.protocolconverter.ProtocolConverterVo; +import cc.iotkit.manager.service.DataOwnerService; +import cc.iotkit.manager.service.IProtocolService; +import cc.iotkit.model.protocol.ProtocolComponent; +import cc.iotkit.model.protocol.ProtocolConverter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FileUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.nio.file.*; +import java.util.Objects; +import java.util.UUID; + +/** + * @Author: jay + * @Date: 2023/5/30 10:48 + * @Version: V1.0 + * @Description: 协议服务 + */ + +@Service +@Slf4j +public class ProtocolServiceImpl implements IProtocolService { + + @Autowired + private ComponentConfig componentConfig; + + @Autowired + private IProtocolComponentData protocolComponentData; + + @Autowired + private IProtocolConverterData protocolConverterData; + + @Autowired + private DataOwnerService dataOwnerService; + + @Autowired + private IUserInfoData userInfoData; + + @Autowired + private ComponentManager componentManager; + @Override + public String uploadJar(MultipartFile file, String id) { + if (file == null) { + throw new BizException(ErrCode.PARAMS_EXCEPTION); + } + log.info("saving upload jar file:{}", file.getName()); + String fileName = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename())); + try { + if (StringUtils.hasLength(id)) { + getAndCheckComponent(id); + } else { + id = UUID.randomUUID().toString(); + } + Path jarFilePath = componentConfig.getComponentFilePath(id); + Files.createDirectories(jarFilePath); + Path targetLocation = jarFilePath.resolve(fileName); + Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING); + return id; + } catch (IOException ex) { + throw new BizException(ErrCode.UPLOAD_FILE_ERROR, ex); + } + } + + @Override + public boolean addComponent(ProtocolComponentBo component) { + String id = component.getId(); + //jar包上传后生成的id + if (!StringUtils.hasLength(id)) { + throw new BizException(ErrCode.COMPONENT_ID_BLANK); + } + Path jarPath = componentConfig.getComponentFilePath(id); + if (!jarPath.resolve(component.getJarFile()).toFile().exists()) { + throw new BizException(ErrCode.COMPONENT_JAR_NOT_FOUND); + } + + ProtocolComponent protocolComponent = protocolComponentData.findById(id); + if (protocolComponent != null) { + throw new BizException(ErrCode.COMPONENT_ALREADY); + } + try { + component.setCreateAt(System.currentTimeMillis()); + component.setUid(AuthUtil.getUserId()); + protocolComponentData.save(component.to(ProtocolComponent.class)); + } catch (Throwable e) { + throw new BizException(ErrCode.ADD_COMPONENT_ERROR, e); + } + return true; + } + + @Override + public String saveComponent(ProtocolComponentBo req) { + ProtocolComponent component = req.to(ProtocolComponent.class); + String id = component.getId(); + if (!StringUtils.hasLength(id)) { + throw new BizException(ErrCode.COMPONENT_ID_BLANK); + } + Path jarPath = componentConfig.getComponentFilePath(id); + if (!jarPath.resolve(component.getJarFile()).toFile().exists()) { + throw new BizException(ErrCode.COMPONENT_JAR_NOT_FOUND); + } + + ProtocolComponent oldComponent = getAndCheckComponent(id); + component = ReflectUtil.copyNoNulls(component, oldComponent); + + try { + componentManager.deRegister(id); + protocolComponentData.save(component); + return component.getId(); + } catch (Throwable e) { + throw new BizException(ErrCode.ADD_COMPONENT_ERROR, e); + } + } + + @Override + public ProtocolComponentVo getProtocolComponent(String id) { + ProtocolComponent component = getAndCheckComponent(id); + + String script = component.getScript(); + // 如果数据库里不存在,则从文件中读取脚本 + if (!StringUtils.hasText(script)) { + try { + File file = getComponentScriptFile(id); + script = FileUtils.readFileToString(file, "UTF-8"); + } catch (Throwable e) { + log.error("read converter script file error", e); + script = ""; + } + component.setScript(script); + } + return MapstructUtils.convert(component, ProtocolComponentVo.class); + } + + @Override + public boolean saveComponentScript(ProtocolComponentBo upReq) { + String id = upReq.getId(); + ProtocolComponent old = getAndCheckComponent(id); + try { + // 保存到文件 + File file = getComponentScriptFile(id); + String script = upReq.getScript(); + FileUtils.writeStringToFile(file, script, "UTF-8", false); + + // 保存到数据库,后续加版本号 + old.setScript(upReq.getScript()); + old.setScriptTyp(upReq.getScriptTyp()); + protocolComponentData.save(old); + + componentManager.deRegister(id); + } catch (Throwable e) { + throw new BizException(ErrCode.SAVE_COMPONENT_SCRIPT_ERROR, e); + } + return true; + } + + @Override + public boolean deleteComponent(String id) { + ProtocolComponent component = getAndCheckComponent(id); + try { + componentManager.deRegister(id); + + Path path = Paths.get(String.format("%s/%s", componentConfig.getComponentDir(), id)) + .toAbsolutePath().normalize(); + File file = path.toFile(); + try { + if (file.isDirectory()) { + FileUtils.deleteDirectory(file); + } else { + FileUtils.delete(file); + } + } catch (NoSuchFileException e) { + log.warn("delete component script error", e); + } + protocolComponentData.deleteById(component.getId()); + } catch (Throwable e) { + throw new BizException(ErrCode.DELETE_COMPONENT_ERROR, e); + } + return true; + } + + @Override + public Paging selectPageList(PageRequest query) { + Paging components = protocolComponentData.findAll(query.to(ProtocolComponent.class)).to(ProtocolComponentVo.class); + components.getData().forEach(c -> c.setState( + componentManager.isRunning(c.getId()) ? + ProtocolComponent.STATE_RUNNING : ProtocolComponent.STATE_STOPPED + )); + return components; + } + + @Override + public Paging selectConvertersPageList(PageRequest query) { + return protocolConverterData.findAll(query.to(ProtocolConverter.class)).to(ProtocolConverterVo.class); + } + + @Override + public boolean addConverter(ProtocolConverterBo req) { + try { + ProtocolConverter converter = req.to(ProtocolConverter.class); + converter.setId(null); + converter.setCreateAt(System.currentTimeMillis()); + converter.setUid(AuthUtil.getUserId()); + protocolConverterData.save(converter); + } catch (Throwable e) { + throw new BizException(ErrCode.ADD_CONVERT_ERROR, e); + } + return false; + } + + @Override + public boolean editConverter(ProtocolConverterBo req) { + ProtocolConverter converter = req.to(ProtocolConverter.class); + ProtocolConverter oldConverter = getAndCheckConverter(converter.getId()); + converter = ReflectUtil.copyNoNulls(converter, oldConverter); + try { + protocolConverterData.save(converter); + } catch (Throwable e) { + throw new BizException(ErrCode.ADD_CONVERT_ERROR, e); + } + return true; + } + + @Override + public ProtocolConverterVo getConverter(String id) { + ProtocolConverter converter = getAndCheckConverter(id); + String script = converter.getScript(); + // 如果数据库里不存在,则从文件中读取脚本 + if (!StringUtils.hasText(script)) { + try { + Path path = componentConfig.getConverterFilePath(id); + File file = path.resolve(ProtocolConverter.SCRIPT_FILE_NAME).toFile(); + script = FileUtils.readFileToString(file, "UTF-8"); + } catch (Throwable e) { + log.error("read converter script file error", e); + script = ""; + } + converter.setScript(script); + } + return MapstructUtils.convert(converter, ProtocolConverterVo.class); + } + + @Override + public boolean saveConverterScript(ProtocolConverterBo req) { + ProtocolConverter converter = req.to(ProtocolConverter.class); + String id = req.getId(); + getAndCheckConverter(id); + try { + // 先存文件 + Path path = componentConfig.getConverterFilePath(id); + File file = path.resolve(ProtocolConverter.SCRIPT_FILE_NAME).toFile(); + String script = converter.getScript(); + FileUtils.writeStringToFile(file, script, "UTF-8", false); + + // 再存数据库 + protocolConverterData.save(converter); + + } catch (Throwable e) { + throw new BizException(ErrCode.SAVE_CONVERT_SCRIPT_ERROR, e); + } + return true; + } + + @Override + public boolean deleteConverter(String id) { + getAndCheckConverter(id); + try { + Path path = Paths.get(String.format("%s/%s", componentConfig.getConverterDir(), id)) + .toAbsolutePath().normalize(); + File file = path.toFile(); + try { + if (file.isDirectory()) { + FileUtils.deleteDirectory(file); + } else { + FileUtils.delete(file); + } + } catch (NoSuchFileException e) { + log.warn("delete converter script error", e); + } + protocolConverterData.deleteById(id); + } catch (Throwable e) { + throw new BizException(ErrCode.DELETE_CONVERT_ERROR, e); + } + return true; + } + + @Override + public boolean changeComponentState(ChangeStateBo req) { + String id = req.getId(); + String state = req.getState(); + ProtocolComponent component = getAndCheckComponent(id); + if (ProtocolComponent.TYPE_DEVICE.equals(component.getType()) && ProtocolComponent.CONVER_TYPE_CUSTOM.equals(component.getConverType())) { + String converterId = component.getConverter(); + getAndCheckConverter(converterId); + } + + if (ProtocolComponent.STATE_RUNNING.equals(state)) { + File scriptFile = getComponentScriptFile(id); + if (!scriptFile.exists()) { + throw new BizException("请先编写组件脚本"); + } + + componentManager.register(component); + componentManager.start(component.getId()); + component.setState(ProtocolComponent.STATE_RUNNING); + } else { + componentManager.deRegister(id); + component.setState(ProtocolComponent.STATE_STOPPED); + } + protocolComponentData.save(component); + return true; + } + + + /******************************/ + private File getComponentScriptFile(String id) { + Path path = componentConfig.getComponentFilePath(id); + return path.resolve(ProtocolComponent.SCRIPT_FILE_NAME).toFile(); + } + + private ProtocolComponent getAndCheckComponent(@PathVariable("id") String id) { + ProtocolComponent oldComponent = protocolComponentData.findById(id); + if (oldComponent == null) { + throw new BizException(ErrCode.COMPONENT_NOT_FOUND); + } + dataOwnerService.checkOwner(oldComponent); + return oldComponent; + } + + private ProtocolConverter getAndCheckConverter(String id) { + ProtocolConverter converter = protocolConverterData.findById(id); + if (converter == null) { + throw new BizException(ErrCode.CONVERT_NOT_FOUND); + } + + dataOwnerService.checkOwner(converter); + return converter; + } + + + + +}