Browse Source

feat:修改OTA升级

荭琪枫 2 years ago
parent
commit
f92bdd9235

+ 38 - 0
iot-common/iot-common-dao/iot-common-model/src/main/java/cc/iotkit/model/ota/OtaPackage.java

@@ -6,6 +6,8 @@ import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.util.Map;
+
 /**
  * @Author: 石恒
  * @Date: 2023/6/10 14:35
@@ -19,27 +21,63 @@ public class OtaPackage implements Id<Long> {
 
     private Long id;
 
+    /**
+     * 文件包大小
+     */
     private Long size;
 
+    /**
+     * 签名
+     */
     private String sign;
 
+    /**
+     * 是否差分升级
+     */
     private Boolean isDiff;
 
+    /**
+     * 文件MD5后的值
+     */
     private String md5;
 
+    /**
+     * 包名
+     */
     private String name;
 
+    /**
+     * 描述
+     */
     private String desc;
 
+    /**
+     * 版本
+     */
     private String version;
 
+    /**
+     * 升级包地址
+     */
     private String url;
 
+    /**
+     * 签名方式
+     */
     private String signMethod;
 
+    /**
+     * 模块
+     */
     private String module;
 
+    /**
+     * 扩展数据
+     */
     private String extData;
 
+    /**
+     * 创建时间
+     */
     private Long createAt;
 }

+ 2 - 0
iot-common/iot-common-dao/iot-common-model/src/main/java/cc/iotkit/model/product/Product.java

@@ -26,6 +26,8 @@ public class Product extends TenantModel implements Id<Long>, Serializable {
 
     private String productKey;
 
+    private String productSecret ;
+
     private String name;
 
     private String category;

+ 9 - 11
iot-module/iot-manager/src/main/java/cc/iotkit/manager/controller/OtaController.java

@@ -5,10 +5,10 @@ import cc.iotkit.common.api.Paging;
 import cc.iotkit.common.api.Request;
 import cc.iotkit.manager.dto.bo.ota.DeviceOtaInfoBo;
 import cc.iotkit.manager.dto.bo.ota.DeviceUpgradeBo;
-import cc.iotkit.manager.dto.vo.ota.DeviceOtaInfoVO;
+import cc.iotkit.manager.dto.bo.ota.OtaPackageBo;
+import cc.iotkit.manager.dto.vo.ota.DeviceOtaInfoVo;
+import cc.iotkit.manager.dto.vo.ota.OtaPackageUploadVo;
 import cc.iotkit.manager.service.OtaService;
-import cc.iotkit.model.alert.AlertConfig;
-import cc.iotkit.model.ota.DeviceOta;
 import cc.iotkit.model.ota.OtaPackage;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -23,7 +23,6 @@ import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
-import java.io.InputStream;
 
 /**
  * @Author: 石恒
@@ -41,25 +40,24 @@ public class OtaController {
 
     @ApiOperation("升级包上传")
     @PostMapping("/package/upload")
-    public String packageUpload(MultipartFile file) throws Exception {
+    public OtaPackageUploadVo packageUpload(MultipartFile file) throws Exception {
         if (!file.isEmpty()) {
             String fileName = file.getOriginalFilename();
             String suffix = StringUtils.isEmpty(fileName) ? "" : fileName.substring(fileName.lastIndexOf("."));
-            InputStream ins = file.getInputStream();
-            return otaService.uploadFile(ins, suffix);
+            return otaService.uploadFile(file, suffix);
         }
-        return "";
+        return null;
     }
 
     @ApiOperation("新增升级包")
     @PostMapping("/package/add")
-    public OtaPackage addChannelTemplate(@RequestBody @Valid Request<OtaPackage> request) throws Exception {
+    public OtaPackage packageAdd(@RequestBody @Valid Request<OtaPackageBo> request) throws Exception {
         return otaService.addOtaPackage(request.getData());
     }
 
     @ApiOperation("删除升级包")
     @PostMapping("/package/delById")
-    public Boolean delChannelConfigById(@RequestBody @Valid Request<Long> request) {
+    public Boolean delPackageById(@RequestBody @Valid Request<Long> request) {
         return otaService.delOtaPackageById(request.getData());
     }
 
@@ -77,7 +75,7 @@ public class OtaController {
 
     @ApiOperation("设备升级结果查询")
     @PostMapping("/result")
-    public Paging<DeviceOtaInfoVO> otaResult(@RequestBody PageRequest<DeviceOtaInfoBo> request) {
+    public Paging<DeviceOtaInfoVo> otaResult(@RequestBody PageRequest<DeviceOtaInfoBo> request) {
         return otaService.otaResult(request);
     }
 

+ 74 - 0
iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/bo/ota/OtaPackageBo.java

@@ -0,0 +1,74 @@
+package cc.iotkit.manager.dto.bo.ota;
+
+import cc.iotkit.common.api.BaseDto;
+import io.github.linpeilie.annotations.AutoMapper;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * @Author: 石恒
+ * @Date: 2023/6/27 22:09
+ * @Description:
+ */
+@ApiModel(value = "OtaPackageBo")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = OtaPackageBo.class, reverseConvertGenerate = false)
+public class OtaPackageBo extends BaseDto {
+
+    /**
+     * 文件包大小
+     */
+    private Long size;
+
+    /**
+     * 签名
+     */
+    private String sign;
+
+    /**
+     * 是否差分升级
+     */
+    private Boolean isDiff;
+
+    /**
+     * 文件MD5后的值
+     */
+    private String md5;
+
+    /**
+     * 包名
+     */
+    private String name;
+
+    /**
+     * 描述
+     */
+    private String desc;
+
+    /**
+     * 版本
+     */
+    private String version;
+
+    /**
+     * 升级包地址
+     */
+    private String url;
+
+    /**
+     * 签名方式
+     */
+    private String signMethod;
+
+    /**
+     * 模块
+     */
+    private String module;
+
+    /**
+     * 扩展数据
+     */
+
+}

+ 3 - 4
iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/ota/DeviceOtaInfoVO.java → iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/ota/DeviceOtaInfoVo.java

@@ -1,6 +1,5 @@
 package cc.iotkit.manager.dto.vo.ota;
 
-import cc.iotkit.model.device.DeviceInfo;
 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
 import io.github.linpeilie.annotations.AutoMapper;
 import io.swagger.annotations.ApiModel;
@@ -15,9 +14,9 @@ import java.io.Serializable;
  */
 @Data
 @ExcelIgnoreUnannotated
-@ApiModel(value = "DeviceOtaInfoVO")
-@AutoMapper(target = DeviceOtaInfoVO.class)
-public class DeviceOtaInfoVO implements Serializable {
+@ApiModel(value = "DeviceOtaInfoVo")
+@AutoMapper(target = DeviceOtaInfoVo.class)
+public class DeviceOtaInfoVo implements Serializable {
     private Long id;
 
     private Integer step;

+ 25 - 0
iot-module/iot-manager/src/main/java/cc/iotkit/manager/dto/vo/ota/OtaPackageUploadVo.java

@@ -0,0 +1,25 @@
+package cc.iotkit.manager.dto.vo.ota;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import io.github.linpeilie.annotations.AutoMapper;
+import io.swagger.annotations.ApiModel;
+import lombok.Builder;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @Author: 石恒
+ * @Date: 2023/6/27 22:35
+ * @Description:
+ */
+@Data
+@Builder
+@ExcelIgnoreUnannotated
+@ApiModel(value = "OtaPackageUploadVo")
+@AutoMapper(target = OtaPackageUploadVo.class)
+public class OtaPackageUploadVo implements Serializable {
+    private String url;
+    private Long size;
+    private String md5;
+}

+ 60 - 23
iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/OtaService.java

@@ -2,41 +2,38 @@ package cc.iotkit.manager.service;
 
 import cc.iotkit.common.api.PageRequest;
 import cc.iotkit.common.api.Paging;
-import cc.iotkit.common.api.Request;
-import cc.iotkit.comps.ApiTool;
 import cc.iotkit.data.manager.IDeviceOtaInfoData;
 import cc.iotkit.data.manager.IOtaDeviceData;
 import cc.iotkit.data.manager.IOtaPackageData;
-import cc.iotkit.data.service.DeviceOtaInfoDataImpl;
 import cc.iotkit.manager.dto.bo.ota.DeviceOtaInfoBo;
-import cc.iotkit.manager.dto.vo.channel.ChannelTemplateVo;
-import cc.iotkit.manager.dto.vo.ota.DeviceOtaInfoVO;
-import cc.iotkit.model.alert.AlertConfig;
-import cc.iotkit.model.notify.ChannelTemplate;
+import cc.iotkit.manager.dto.bo.ota.OtaPackageBo;
+import cc.iotkit.manager.dto.vo.ota.DeviceOtaInfoVo;
+import cc.iotkit.manager.dto.vo.ota.OtaPackageUploadVo;
 import cc.iotkit.model.ota.DeviceOtaInfo;
 import cc.iotkit.model.ota.OtaPackage;
 import cc.iotkit.oss.service.OssTemplate;
-import com.google.gson.JsonObject;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.io.FileUtils;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
-import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.multipart.MultipartFile;
 
-import java.io.InputStream;
+import java.io.*;
+import java.security.MessageDigest;
 import java.util.List;
 import java.util.UUID;
 
 /**
  * @Author: 石恒
  * @Date: 2023/5/19 20:49
- * @Description:
- * oss:
- *   region: tb3321.oss-cn-shanghai.aliyuncs.com
- *   endpoint: oss-cn-shanghai.aliyuncs.com
- *   accessKey: LTAI5tAq5Db5eHt5DTYmXLF4
- *   secretKey: bPbHQbeXPSRtyNxxCsw5uRVGJTxNHK
- *   buckName: tb3321
+ * @Description: oss:
+ * region: tb3321.oss-cn-shanghai.aliyuncs.com
+ * endpoint: oss-cn-shanghai.aliyuncs.com
+ * accessKey: LTAI5tAq5Db5eHt5DTYmXLF4
+ * secretKey: bPbHQbeXPSRtyNxxCsw5uRVGJTxNHK
+ * buckName: tb3321
  */
 @Slf4j
 @Service
@@ -55,14 +52,54 @@ public class OtaService {
     @Value("${oss.buckName}")
     private String buckName;
 
-    public String uploadFile(InputStream inputStream, String suffix) throws Exception {
+    public OtaPackageUploadVo uploadFile(MultipartFile file, String suffix) throws Exception {
+        InputStream inputStream = file.getInputStream();
+        long size = file.getSize();
         String objectName = UUID.randomUUID().toString().replaceAll("-", "") + suffix;
         ossTemplate.putObject(buckName, objectName, inputStream);
-        return "https://" + region + "/" + objectName;
+        String url = "https://" + region + "/" + objectName;
+        String md5 = md5OfFile(file);
+        return OtaPackageUploadVo.builder()
+                .url(url)
+                .size(size)
+                .md5(md5)
+                .build();
     }
 
-    public OtaPackage addOtaPackage(OtaPackage otaPackage) {
-        return iOtaPackageData.save(otaPackage);
+    public static String md5OfFile(MultipartFile multipartFile) throws Exception {
+        File file = null;
+        if (multipartFile.isEmpty()) {
+            return "";
+        }
+        try {
+            //本质上还是在项目根路径创建文件
+            file = new File(multipartFile.getOriginalFilename());
+            //将MultipartFile的byte[]写入到file中
+            FileUtils.writeByteArrayToFile(file, multipartFile.getBytes());
+            byte[] bytes = DigestUtils.md5(multipartFile.getInputStream());
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        MessageDigest md = MessageDigest.getInstance("MD5");
+        FileInputStream fs = new FileInputStream(file);
+        BufferedInputStream bs = new BufferedInputStream(fs);
+        byte[] buffer = new byte[1024];
+        int bytesRead;
+
+        while ((bytesRead = bs.read(buffer, 0, buffer.length)) != -1) {
+            md.update(buffer, 0, bytesRead);
+        }
+        byte[] digest = md.digest();
+
+        StringBuilder sb = new StringBuilder();
+        for (byte bite : digest) {
+            sb.append(String.format("%02x", bite & 0xff));
+        }
+        return sb.toString();
+    }
+
+    public OtaPackage addOtaPackage(OtaPackageBo otaPackage) {
+        return iOtaPackageData.save(otaPackage.to(OtaPackage.class));
     }
 
     public Boolean delOtaPackageById(Long id) {
@@ -84,8 +121,8 @@ public class OtaService {
         });
     }
 
-    public Paging<DeviceOtaInfoVO> otaResult(PageRequest<DeviceOtaInfoBo> request) {
-        return deviceOtaInfoData.findAll(request.to(DeviceOtaInfo.class)).to(DeviceOtaInfoVO.class);
+    public Paging<DeviceOtaInfoVo> otaResult(PageRequest<DeviceOtaInfoBo> request) {
+        return deviceOtaInfoData.findAll(request.to(DeviceOtaInfo.class)).to(DeviceOtaInfoVo.class);
     }
 
 }

+ 7 - 1
iot-module/iot-manager/src/main/java/cc/iotkit/manager/service/impl/ProductServiceImpl.java

@@ -26,9 +26,12 @@ import cc.iotkit.model.product.Product;
 import cc.iotkit.model.product.ProductModel;
 import cc.iotkit.model.product.ThingModel;
 import cc.iotkit.temporal.IDbStructureData;
+import cn.hutool.core.lang.UUID;
+import cn.hutool.crypto.digest.MD5;
 import com.aliyun.oss.OSS;
 import com.aliyun.oss.OSSClientBuilder;
 import com.aliyun.oss.model.PutObjectResult;
+import com.amazonaws.util.Md5Utils;
 import com.github.yitter.idgen.YitIdHelper;
 import lombok.RequiredArgsConstructor;
 import lombok.SneakyThrows;
@@ -77,10 +80,13 @@ public class ProductServiceImpl implements IProductService {
     @Override
     public ProductVo addEntity(ProductBo data) {
         Product product = data.to(Product.class);
-
         if (product.getCreateAt() == null) {
             product.setCreateAt(System.currentTimeMillis());
         }
+
+        String secret = UUID.randomUUID().toString(true);
+        product.setProductSecret(secret);
+
         productData.save(product);
         return MapstructUtils.convert(product, ProductVo.class);
     }