New file |
| | |
| | | sopath:
|
| | | ip: 192.168.1.182
|
| | | port: 8008 |
| | |
| | | |
| | | 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 { |
| | |
| | | } 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,"下载算法成功!") |
| | | } |
| | | } |
| | |
| | | package config |
| | | |
| | | import ( |
| | | "log" |
| | | |
| | | "github.com/spf13/viper" |
| | | "log" |
| | | ) |
| | | |
| | | type server struct { |
| | |
| | | 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{} |
| | | |
| | |
| | | viper.UnmarshalKey("database", DBconf) |
| | | viper.UnmarshalKey("weedfs", WeedFs) |
| | | viper.UnmarshalKey("compare", CompServerInfo) |
| | | viper.UnmarshalKey("sopath",SoPath) |
| | | } |
| | |
| | | sdkApi.GET("/findAllSdk", sdkController.FindAllSdk) |
| | | sdkApi.GET("/findByTaskId", sdkController.FindByTaskId) |
| | | sdkApi.GET("/getById", sdkController.GetById) |
| | | sdkApi.GET("/sdkDownload",sdkController.SdkDownLoad) |
| | | } |
| | | |
| | | //算法参数 |
New file |
| | |
| | | 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 |
| | | } |
| | | } |
New file |
| | |
| | | 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]) |
| | | } |
| | | |
New file |
| | |
| | | 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) |
| | | } |
| | | } |