package service
|
|
import (
|
"bytes"
|
"crypto/md5"
|
"encoding/hex"
|
"encoding/json"
|
"fmt"
|
"io"
|
"io/ioutil"
|
"net/http"
|
"os"
|
"path/filepath"
|
"strings"
|
"webserver/extend/config"
|
|
reqUtil "webserver/extend/util"
|
|
"webserver/util"
|
|
"basic.com/dbapi.git"
|
"basic.com/valib/logger.git"
|
)
|
|
func DownSdk(id string) map[string]interface{} {
|
// 下载算法
|
if ok, err := DownSo(id); !ok {
|
logger.Error("下载算法失败", err)
|
return nil
|
}
|
|
return FindLocalSdkSoById(id)
|
}
|
|
// 从服务器上下载文件到临时目录,校验之后如果完整将其拷贝到目标目录下
|
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
|
}
|
}
|
|
func GetSdkList(sdkName string) []SdkInsOrUpgrade {
|
var api dbapi.SdkApi
|
localSdks := api.FindAll(sdkName) //本地已安装所有算法
|
localSdkM := make(map[string]SdkInsOrUpgrade)
|
for _,ls :=range localSdks {
|
siou := SdkInsOrUpgrade{
|
Installed: true,
|
}
|
siou.Sdk = Sdk{
|
Id: ls.Id,
|
IpcId: ls.IpcId,
|
SdkType: ls.SdkType,
|
SdkName: ls.SdkName,
|
Icon: ls.Icon,
|
Url: ls.Url,
|
CreateTime: ls.CreateTime,
|
CreateBy: ls.CreateBy,
|
UpdateTime: ls.UpdateTime,
|
Enable: ls.Enable,
|
DelFlag: int(ls.DelFlag),
|
IconBlob: ls.IconBlob,
|
Version: ls.Version,
|
}
|
localSdkM[siou.Id] = siou
|
}
|
|
//远端可用的算法
|
remoteSdks := findAllMySdk()
|
logger.Debug("remoteSdks:", remoteSdks)
|
|
for sdkId,sdk := range remoteSdks {
|
if v,ok := localSdkM[sdkId];ok { //本地已安装
|
ls := v
|
if shouldVersionBeUpgrade(ls.Version, sdk.Version) { //判断版本号是否需要升级
|
ls.Installed = true
|
ls.IsUpgrade = true //需要升级
|
ls.RemoteVersion = sdk.Version //远端的版本号
|
}
|
localSdkM[sdkId] = ls
|
} else { //本地未安装,需要安装
|
bIns := SdkInsOrUpgrade{
|
RemoteVersion: sdk.Version,
|
IsUpgrade: false,
|
Installed: false,
|
}
|
bIns.Sdk = sdk
|
localSdkM[sdkId] = bIns
|
}
|
}
|
|
sdks := make([]SdkInsOrUpgrade, 0)
|
for _,v := range localSdkM {
|
sdks = append(sdks, v)
|
}
|
return sdks
|
}
|
|
func queryDatabase(sdkName string) ([]map[string]interface{}, map[string]bool) {
|
var api dbapi.SdkApi
|
ids := make(map[string]bool)
|
sdks := []map[string]interface{}{}
|
|
// 查询已经安装的算法
|
data := api.FindAll(sdkName)
|
for _, sdk := range data {
|
ids[sdk.Id] = true
|
sdks = append(sdks, map[string]interface{}{
|
"id": sdk.Id,
|
"ipc_id": sdk.IpcId,
|
"sdk_type": sdk.SdkType,
|
"sdk_name": sdk.SdkName,
|
"icon": sdk.Icon,
|
"enable": sdk.Enable,
|
"installed": true,
|
})
|
}
|
|
return sdks, ids
|
}
|
|
|
type shopSdks struct {
|
Sdks []Sdk `json:"sdks"`
|
}
|
|
func findAllMySdk() map[string]Sdk {
|
token := "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjQ3NDUwMjU5MjMsInVzZXIiOiJ7XCJpZFwiOlwiZTZjY2QzNmQtNGYxNi00NmZjLTg4ZDUtMDczNjU4NjZkMjA1XCIsXCJwZXJtaXNzaW9uc1wiOltcInByb2R1Y3RNYW5nZTpwdWJsaXNoXCIsXCJjb2RlTWFuZ2U6dmlld1wiLFwiZGV2aWNlTWFuYWdlOmFkZFwiLFwiYWRtaW5NYW5hZ2VcIixcIm9yZGVyTWFuZ2VcIixcImRldmljZU1hbmFnZTp2aWV3XCIsXCJwcm9kdWN0TWFuZ2U6YWRkXCIsXCJhZG1pbk1hbmFnZTp2aWV3XCIsXCJjb2RlTWFuZ2U6YWRkXCIsXCJwcm9kdWN0TWFuZ2U6b2ZmU2FsZVwiLFwib3JkZXJNYW5nZTpjYW5jZWxcIixcInByb2R1Y3RDZW50ZXI6ZG93bmxvYWRcIixcInByb2R1Y3RDZW50ZXI6YnV5XCIsXCJwcm9kdWN0TWFuZ2U6dmlld1wiLFwiYXBpXCIsXCJob21lXCIsXCJvcmRlck1hbmdlOnBheVwiLFwiYWRtaW5NYW5hZ2U6YWRkXCIsXCJvcmRlck1hbmdlOmRvd25sb2FkXCIsXCJwcm9kdWN0Q2VudGVyXCIsXCJkZXZpY2VNYW5hZ2U6dW5iaW5kXCIsXCJvcmRlck1hbmdlOnZpZXdcIixcImFkbWluTWFuYWdlOmVkaXRcIixcImRldmljZU1hbmFnZVwiLFwidmlwTWFuYWdlOmFkZFwiLFwidmlwTWFuYWdlOnZpZXdcIixcInByb2R1Y3RDZW50ZXI6dmlld1wiLFwidmlwTWFuYWdlOmVkaXRcIixcInZpcE1hbmFnZVwiLFwicHJvZHVjdE1hbmdlOmVkaXRcIixcImNvZGVNYW5nZVwiLFwicHJvZHVjdE1hbmdlXCJdLFwidXNlcm5hbWVcIjpcImJhc2ljXCJ9In0.vwjAFkWuEyadRLvIOGK8LFE3MjpY3SQ7j6AlTXnQDG8"
|
url := "http://"+config.ShopConf.Url+"/data/api-s/sdk/findAllMySdk"
|
fmt.Println("token:", token, "url:", url)
|
paramBody := map[string]interface{} {
|
"serverId": config.Server.AnalyServerId,
|
"machineCode": "",
|
}
|
header := map[string]string {
|
"Authorization": token,
|
}
|
respBody, err := reqUtil.DoPostRequest(url, reqUtil.CONTENT_TYPE_JSON, paramBody, nil, header)
|
if err != nil {
|
logger.Debug("DoPostRequest err:", err)
|
return nil
|
}
|
var res dbapi.Result
|
if err = json.Unmarshal(respBody, &res); err != nil {
|
logger.Debug("unmarshal err:", err)
|
return nil
|
}
|
bytes, _ := json.Marshal(res.Data)
|
var ss shopSdks
|
if err := json.Unmarshal(bytes, &ss);err != nil {
|
logger.Debug("unmarshal err:", err)
|
return nil
|
}
|
m := make(map[string]Sdk)
|
for _,s := range ss.Sdks {
|
m[s.Id] = s
|
}
|
return m
|
}
|
|
func GetLocalSdks() []map[string]interface{} {
|
var algos = []map[string]interface{}{}
|
|
AlgorithmFiles := "/opt/vasystem/bin/algorithm/*.json"
|
|
files, err := filepath.Glob(AlgorithmFiles)
|
if err != nil {
|
fmt.Println("Cannot access algorithm json files: No such file or directory")
|
return algos
|
}
|
|
for _, filename := range files {
|
algo := make(map[string]interface{})
|
f, err := ioutil.ReadFile(filename)
|
if err != nil {
|
return algos
|
}
|
|
if err := json.Unmarshal(f, &algo); err != nil {
|
return algos
|
}
|
|
algos = append(algos, map[string]interface{}{
|
"id": algo["sdkId"],
|
"ipc_id": algo["ipcId"],
|
"sdk_type": algo["sdkType"],
|
"sdk_name": algo["sdkName"],
|
"icon": algo["icon"],
|
"args": algo["sdkArgs"],
|
})
|
}
|
|
return algos
|
}
|
|
func FindLocalSdkSoById(id string) map[string]interface{} {
|
localAlgos := GetLocalSdks()
|
for _, sdk := range localAlgos {
|
if sdk["id"].(string) == id {
|
return sdk
|
}
|
}
|
|
return nil
|
}
|