panlei
2019-08-23 0905eb936d66cf8543da4f96d129cbf854263028
add model download so
4个文件已添加
3个文件已修改
326 ■■■■■ 已修改文件
config/so.yaml 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
controllers/sdk.go 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
extend/config/config.go 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
router/router.go 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
service/SdkDownLoad.go 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
util/zip.go 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
util/zip_test.go 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
config/so.yaml
New file
@@ -0,0 +1,3 @@
sopath:
  ip: 192.168.1.182
  port: 8008
controllers/sdk.go
@@ -2,9 +2,13 @@
import (
    "basic.com/dbapi.git"
    uuid "github.com/satori/go.uuid"
    "webserver/extend/code"
    "webserver/extend/config"
    "webserver/extend/logger"
    "webserver/extend/util"
    "github.com/gin-gonic/gin"
    "webserver/service"
)
type SdkController struct {
@@ -138,4 +142,44 @@
    } else {
        util.ResponseFormat(c,code.ComError,sdks)
    }
}
func (sc SdkController) SdkDownLoad(c *gin.Context) {
    path,exist := c.GetQuery("path")
    if !exist {
        util.ResponseFormat(c,code.ComError,"下载的算法参数有误")
    }
    logger.Info(path)
    flag := c.Query("needUpdateMiddle")
    // 下载算法(有时候也需要把中间件一起下载下来)
    if flag == "true" {
        // 下载并更新中间件,带上MD5校验
        flag1,err := service.DownSo("http://"+config.SoPath.Ip+":"+config.SoPath.Port+"/"+"middleware.so")
        logger.Debug("中间件路径:","http://"+config.SoPath.Ip+":"+config.SoPath.Port+"/"+"middleware.so")
        if err != nil {
            logger.Info(err)
        }
        if !flag1 {
            util.ResponseFormat(c,code.ComError,"请重新下载算法")
        }
    }
    // 下载算法,校验,并写入到目标目录下
    flag2,err2 := service.DownSo(path)
    if err2 != nil {
        logger.Info(err2)
    }
    if !flag2 {
        util.ResponseFormat(c,code.ComError,"请重新下载算法")
    }
    // 将算法和so名称存到规则私有的注册表
    var soApi dbapi.SoApi
    param := make(map[string]interface{})
    param["id"] = uuid.NewV4().String()
    sdkId := uuid.NewV4().String()
    param["sdkId"] = sdkId
    param["soName"] = service.GetFileNameFromUrl(path,true)
    flag3,_ := soApi.Add(param)
    if flag3 {
        util.ResponseFormat(c,code.Success,"下载算法成功!")
    }
}
extend/config/config.go
@@ -1,9 +1,8 @@
package config
import (
    "log"
    "github.com/spf13/viper"
    "log"
)
type server struct {
@@ -54,11 +53,17 @@
    Dbtablepersons index `mapstructure:"dbtablepersons"`
    Personaction   index `mapstructure:"personaction"`
}
type index struct {
    IndexName string `mapstructure:"index"`
    IndexType string `mapstructure:"type"`
}
type sopath struct {
    Ip string `mapstructure:"ip"`
    Port string `mapstructure:"port"`
}
var SoPath = &sopath{}
var EsInfo = &esinfo{}
@@ -89,4 +94,5 @@
    viper.UnmarshalKey("database", DBconf)
    viper.UnmarshalKey("weedfs", WeedFs)
    viper.UnmarshalKey("compare", CompServerInfo)
    viper.UnmarshalKey("sopath",SoPath)
}
router/router.go
@@ -188,6 +188,7 @@
        sdkApi.GET("/findAllSdk", sdkController.FindAllSdk)
        sdkApi.GET("/findByTaskId", sdkController.FindByTaskId)
        sdkApi.GET("/getById", sdkController.GetById)
        sdkApi.GET("/sdkDownload",sdkController.SdkDownLoad)
    }
    //算法参数
service/SdkDownLoad.go
New file
@@ -0,0 +1,112 @@
package service
import (
    "bytes"
    "crypto/md5"
    "encoding/hex"
    "fmt"
    "io"
    "io/ioutil"
    "net/http"
    "os"
    "strings"
    "webserver/extend/logger"
    "webserver/util"
)
// 从服务器上下载文件到临时目录,校验之后如果完整将其拷贝到目标目录下
func DownSo(url string)(bool,error) {
    resp, err := http.Get(url)
    if err != nil {
        logger.Error("获取文件失败")
        return false,err
    }
    // 从resp中读出zip文件解压缩,解出face.so,face.txt,然后把解压出的so用MD5编码出一个temp.txt文件,与解压出的so.txt文件比对,
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        logger.Error("读取resp.body失败")
        return false,err
    }
    CopyFile(body, "/opt/temp/temp.zip")
    util.DeCompress("/opt/temp/temp.zip", "/opt/temp")
    fileName := GetFileNameFromUrl(url,false)
    md5str,err1 := File2md5("/opt/temp/"+fileName+".so")
    if err1 != nil {
        logger.Error(err1)
        return false,err1
    }
    md5str_origin,err2 := ioutil.ReadFile("/opt/temp/"+fileName+".txt")
    if err2 != nil {
        logger.Error("读取解压后的md5文件失败")
        return false,err2
    }
    flag := CompareMd5([]byte(md5str),md5str_origin)
    if flag {
        logger.Info("两次MD5编码一致!")
    } else {
        logger.Debug("两次MD5编码不一致,请重新下载")
        return false,nil
    }
    // 从url中截取soName
    soName := GetFileNameFromUrl(url,true)
    f, err := os.Create("/opt/workspace/ruleprocess/algorithm/" + soName)
    if err != nil {
        logger.Error("在项目目录下创建so文件失败")
        return false,err
    }
    data,_ := ioutil.ReadFile("/opt/temp/"+soName)
    _,err4 := f.Write(data)
    if err4 != nil {
        logger.Error("复制文件出错")
        return false,err4
    }
    return true,nil
}
func CopyFile(byte []byte, dst string) (w int64, err error) {
    dstFile, err := os.Create(dst)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    defer dstFile.Close()
    return io.Copy(dstFile, bytes.NewReader(byte))
}
// 指定目录的文件生成相应的MD5码文件
func File2md5 (filename string) (string, error) {
    // 文件生成MD5加密加密文件
    file, err := os.Open(filename)
    if err != nil {
        fmt.Println("os Open error")
        return "", err
    }
    md5 := md5.New()
    _, err = io.Copy(md5, file)
    if err != nil {
        fmt.Println("io copy error")
        return "", err
    }
    md5Str := hex.EncodeToString(md5.Sum(nil))
    return md5Str,nil
}
// 从url中截取出文件名,参数是是否带后缀
func GetFileNameFromUrl(url string,withSuffix bool)string {
    fileName := strings.Split(url,"/")[len(strings.Split(url,"/"))-1]
    if withSuffix {
        return fileName
    } else {
        withoutSuffix := strings.Split(fileName,".")[0]
        return withoutSuffix
    }
}
// 比较两个MD5编码是否一致
func CompareMd5(value1 []byte,value2 []byte) bool{
    num := bytes.Compare(value1,value2)
    if num == 0 {
        return true
    } else {
        return false
    }
}
util/zip.go
New file
@@ -0,0 +1,118 @@
package util
import (
    "archive/zip"
    "io"
    "os"
    "strings"
)
//压缩文件
//files 文件数组,可以是不同dir下的文件或者文件夹
//dest 压缩文件存放地址
func Compress2Zip(files []*os.File, dest string) error {
    d, _ := os.Create(dest)
    defer d.Close()
    w := zip.NewWriter(d)
    defer w.Close()
    for _, file := range files {
        err := compress(file, "", w)
        if err != nil {
            return err
        }
    }
    return nil
}
func compress(file *os.File, prefix string, zw *zip.Writer) error {
    info, err := file.Stat()
    if err != nil {
        return err
    }
    if info.IsDir() {
        prefix = prefix + "/" + info.Name()
        fileInfos, err := file.Readdir(-1)
        if err != nil {
            return err
        }
        for _, fi := range fileInfos {
            f, err := os.Open(file.Name() + "/" + fi.Name())
            if err != nil {
                return err
            }
            err = compress(f, prefix, zw)
            if err != nil {
                return err
            }
        }
    } else {
        header, err := zip.FileInfoHeader(info)
        header.Name = prefix + "/" + header.Name
        if err != nil {
            return err
        }
        writer, err := zw.CreateHeader(header)
        if err != nil {
            return err
        }
        _, err = io.Copy(writer, file)
        file.Close()
        if err != nil {
            return err
        }
    }
    return nil
}
//解压
func DeCompress(zipFile, dest string) error {
    reader, err := zip.OpenReader(zipFile)
    if err != nil {
        return err
    }
    defer reader.Close()
    for _, file := range reader.File {
        rc, err := file.Open()
        if err != nil {
            return err
        }
        defer rc.Close()
        filename := dest + file.Name
        err = os.MkdirAll(getDir(filename), 0755)
        if err != nil {
            return err
        }
        w, err := os.Create(filename)
        if err != nil {
            return err
        }
        defer w.Close()
        _, err = io.Copy(w, rc)
        if err != nil {
            return err
        }
        w.Close()
        rc.Close()
    }
    return nil
}
func getDir(path string) string {
    return subString(path, 0, strings.LastIndex(path, "/"))
}
func subString(str string, start, end int) string {
    rs := []rune(str)
    length := len(rs)
    if start < 0 || start > length {
        panic("start is wrong")
    }
    if end < start || end > length {
        panic("end is wrong")
    }
    return string(rs[start:end])
}
util/zip_test.go
New file
@@ -0,0 +1,36 @@
package util
import (
    "os"
    "testing"
)
func TestCompress(t *testing.T) {
    f1, err := os.Open("D://test/130.png")
    if err != nil {
        t.Fatal(err)
    }
    defer f1.Close()
    f2, err := os.Open("D://test/file.exe")
    if err != nil {
        t.Fatal(err)
    }
    defer f2.Close()
    f3, err := os.Open("D://test/face.txt")
    if err != nil {
        t.Fatal(err)
    }
    defer f3.Close()
    var files = []*os.File{f1, f2, f3}
    dest := "D://test/test.zip"
    err = Compress(files, dest)
    if err != nil {
        t.Fatal(err)
    }
}
func TestDeCompress(t *testing.T) {
    err := DeCompress("D://test/test.zip", "D://test")
    if err != nil {
        t.Fatal(err)
    }
}