298 lines
8.6 KiB
Go
298 lines
8.6 KiB
Go
package service
|
|
|
|
import (
|
|
"bufio"
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"os"
|
|
"os/exec"
|
|
"path"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"go-common/app/admin/ep/melloi/conf"
|
|
"go-common/app/admin/ep/melloi/model"
|
|
"go-common/library/ecode"
|
|
"go-common/library/log"
|
|
bm "go-common/library/net/http/blademaster"
|
|
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// Upload upload file
|
|
func (s *Service) Upload(c context.Context, uploadParam *model.UploadParam, formFile multipart.File, header *multipart.FileHeader) (id int, scriptPath string, err error) {
|
|
|
|
var destFile *os.File
|
|
|
|
//创建脚本保存路径
|
|
if uploadParam.ScriptPath == "" {
|
|
if scriptPath, err = s.uniqueFolderPath(uploadParam.Path); err != nil {
|
|
return
|
|
}
|
|
} else {
|
|
scriptPath = uploadParam.ScriptPath
|
|
}
|
|
|
|
//创建保存文件
|
|
if destFile, err = os.Create(scriptPath + header.Filename); err != nil {
|
|
log.Error("Create failed,error(%v)", err)
|
|
return
|
|
}
|
|
defer destFile.Close()
|
|
|
|
// 读取表单文件,写入保存文件
|
|
if _, err = io.Copy(destFile, formFile); err != nil {
|
|
log.Error("write file error (%v)", err)
|
|
return
|
|
}
|
|
|
|
// jmx文件
|
|
if strings.Contains(header.Filename, ".jmx") {
|
|
treePath := model.TreePath{Department: uploadParam.Department, Project: uploadParam.Project, App: uploadParam.APP}
|
|
script := model.Script{
|
|
ProjectName: uploadParam.TestName,
|
|
//TestName: uploadParam.TestName,
|
|
SavePath: destFile.Name(),
|
|
UpdateBy: uploadParam.UserName,
|
|
TreePath: treePath,
|
|
Upload: true,
|
|
Active: 1,
|
|
ResJtl: scriptPath + "jtl",
|
|
JmeterLog: scriptPath + "jmg",
|
|
ScriptPath: scriptPath,
|
|
ArgumentString: "[{\"\":\"\"}]",
|
|
TestType: 1,
|
|
Domain: uploadParam.Domains,
|
|
Fusing: uploadParam.Fusing,
|
|
UseBusinessStop: uploadParam.UseBusinessStop,
|
|
BusinessStopPercent: uploadParam.BusinessStopPercent,
|
|
}
|
|
if id, _, _, err = s.dao.AddScript(&script); err != nil {
|
|
log.Error("s.dao.AddScript err :(%v)", err)
|
|
return
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// UploadAndGetProtoInfo upload and get proto info
|
|
func (s *Service) UploadAndGetProtoInfo(c context.Context, uploadParam *model.UploadParam, formFile multipart.File, header *multipart.FileHeader) (res map[string]interface{}, err error) {
|
|
// 获取上传路径, Path 为root_path ,ScriptPath 为 root_path + import路径
|
|
_, scriptPath, err := s.Upload(c, uploadParam, formFile, header)
|
|
if err != nil {
|
|
log.Error("Write file failed, error(%v)", err)
|
|
return
|
|
}
|
|
|
|
// 解析proto文件
|
|
path, fileName := filepath.Split(path.Join(scriptPath, header.Filename))
|
|
if res, err = s.ProtoParsing(path, fileName); err != nil {
|
|
log.Error("parser grpc error(%v)", err)
|
|
return
|
|
}
|
|
|
|
// 生成import文件路径
|
|
if err = s.CreateGRPCImportDir(res, uploadParam.Path); err != nil {
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// CreateGRPCImportDir create grpc import path
|
|
func (s *Service) CreateGRPCImportDir(res map[string]interface{}, rootPath string) (err error) {
|
|
if ipts, ok := res["import"]; ok {
|
|
for _, ipt := range ipts.([]string) {
|
|
iptPath, _ := filepath.Split(ipt)
|
|
protoPath := &model.ProtoPathModel{RootPath: rootPath, ExtraPath: iptPath}
|
|
if err = s.CreateProtoImportDir(protoPath); err != nil {
|
|
log.Error("create proto import dir error(%v)", err)
|
|
return
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// CompileProtoFile compile proto file get jar path
|
|
func (s *Service) CompileProtoFile(protoPath, filename string) (jarPath string, err error) {
|
|
return s.createGrpcJar(protoPath, filename)
|
|
}
|
|
|
|
//protocFile protoc file
|
|
func (s *Service) protocFile(scriptPath, protoPath string) (err error) {
|
|
|
|
var (
|
|
protoCMD string
|
|
protoJava string
|
|
protoFileList []string
|
|
line string
|
|
protoFiles = fmt.Sprintf("cd %s && find . -name '*.proto' | awk -F '\\.\\/' '{print $2}'", scriptPath)
|
|
stdout io.ReadCloser
|
|
)
|
|
// 获取scriptPath 目录下所有 proto文件
|
|
cmd := exec.Command("/bin/bash", "-c", protoFiles)
|
|
if stdout, err = cmd.StdoutPipe(); err != nil {
|
|
log.Error("run protoFiles (%s) error(%v)", protoFiles, err)
|
|
return
|
|
}
|
|
|
|
cmd.Start()
|
|
|
|
reader := bufio.NewReader(stdout)
|
|
for {
|
|
if line, err = reader.ReadString('\n'); err != nil || io.EOF == err {
|
|
break
|
|
}
|
|
if line != "" {
|
|
protoFileList = append(protoFileList, line)
|
|
}
|
|
}
|
|
|
|
// 编译所有proto文件
|
|
for _, line := range protoFileList {
|
|
protoCMD = fmt.Sprintf("protoc -I %s --java_out=%s %s", scriptPath, protoPath, path.Join(scriptPath, line))
|
|
protoJava = fmt.Sprintf("protoc --plugin=protoc-gen-grpc-java=%s --grpc-java_out=%s -I %s %s",
|
|
s.c.Grpc.ProtoJavaPluginPath, protoPath, scriptPath, path.Join(scriptPath, line))
|
|
|
|
if err = exec.Command("/bin/bash", "-c", protoCMD).Run(); err != nil {
|
|
log.Error("protoc --proto_path (%s) error (%v)", protoCMD, err)
|
|
return ecode.MelloiProtocError
|
|
}
|
|
// 编译所有proto文件
|
|
for _, line := range protoFileList {
|
|
protoCMD = fmt.Sprintf("protoc -I %s --java_out=%s %s", scriptPath, protoPath, path.Join(scriptPath, line))
|
|
protoJava = fmt.Sprintf("protoc --plugin=protoc-gen-grpc-java=%s --grpc-java_out=%s -I %s %s",
|
|
s.c.Grpc.ProtoJavaPluginPath, protoPath, scriptPath, path.Join(scriptPath, line))
|
|
|
|
if err = exec.Command("/bin/bash", "-c", protoCMD).Run(); err != nil {
|
|
log.Error("protoc --proto_path (%s) error (%v)", protoCMD, err)
|
|
return ecode.MelloiProtocError
|
|
}
|
|
|
|
if err = exec.Command("/bin/bash", "-c", protoJava).Run(); err != nil {
|
|
log.Error("protoc java (%s) error (%v)", protoCMD, err)
|
|
return ecode.MelloiProtocError
|
|
}
|
|
}
|
|
if err = exec.Command("/bin/bash", "-c", protoJava).Run(); err != nil {
|
|
log.Error("protoc java (%s) error (%v)", protoCMD, err)
|
|
return ecode.MelloiProtocError
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
//createGrpcJar crate grpc jar
|
|
func (s *Service) createGrpcJar(scriptPath, filename string) (jarPath string, err error) {
|
|
protoPath := path.Join(scriptPath, "proto")
|
|
if err = os.MkdirAll(protoPath, pathPerm); err != nil {
|
|
log.Error("create proto path err ... (%v)", err)
|
|
return
|
|
}
|
|
|
|
var (
|
|
cmdJava = fmt.Sprintf(" cd %s && find . -name '*.java' |grep -v '^\\./\\.' > sources.txt ", protoPath)
|
|
cmdJavac = fmt.Sprintf("cd %s && javac -Djava.ext.dirs=%s -encoding utf-8 @sources.txt ", protoPath, s.c.Jmeter.JmeterExtLibPath)
|
|
jarFilename = strings.Replace(filename, ".proto", "", -1) + ".jar"
|
|
cmdJar = fmt.Sprintf("cd %s && jar -cvf %s .", protoPath, jarFilename)
|
|
)
|
|
|
|
if err = s.protocFile(scriptPath, protoPath); err != nil {
|
|
log.Error("protoc error (%v)", err)
|
|
return
|
|
}
|
|
|
|
// 编译java文件
|
|
if err = exec.Command("/bin/bash", "-c", cmdJava).Run(); err != nil {
|
|
log.Error("find *.java (%s) error(%+v)", cmdJava, errors.WithStack(err))
|
|
return
|
|
}
|
|
if err = exec.Command("/bin/bash", "-c", cmdJavac).Run(); err != nil {
|
|
log.Error("javac protoc javac (%s) error(%v)", cmdJavac, err)
|
|
err = ecode.MelloiJavacCompileError
|
|
return
|
|
}
|
|
// 生成jar文件
|
|
if err = exec.Command("/bin/bash", "-c", cmdJar).Run(); err != nil {
|
|
log.Error("protoc jar (%s) error(%v)", cmdJar, err)
|
|
err = ecode.MelloiJarError
|
|
return
|
|
}
|
|
jarPath = path.Join(protoPath, jarFilename)
|
|
return
|
|
}
|
|
|
|
//DownloadFile Download File
|
|
func (s *Service) DownloadFile(c *bm.Context, filePath string, w http.ResponseWriter) (err error) {
|
|
var (
|
|
Fi *os.File
|
|
info os.FileInfo
|
|
)
|
|
if info, err = os.Stat(filePath); err != nil {
|
|
return
|
|
}
|
|
//如果文件太大,就禁止下载
|
|
if info.Size() > conf.Conf.Melloi.MaxDowloadSize {
|
|
err = ecode.MelloiBeyondFileSize
|
|
return
|
|
}
|
|
if Fi, err = os.Open(filePath); err != nil {
|
|
log.Error("open file err :(%v)", err)
|
|
return
|
|
}
|
|
defer Fi.Close()
|
|
w.Header().Set("Content-Disposition", "attachment; filename="+Fi.Name())
|
|
if _, err = io.Copy(w, io.Reader(Fi)); err != nil {
|
|
log.Error("copy file err :(%v)", err)
|
|
err = ecode.MelloiCopyFileErr
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
//ReadFile read file
|
|
func (s *Service) ReadFile(c *bm.Context, file, limit string) (data string, err error) {
|
|
var (
|
|
info os.FileInfo
|
|
buff []byte
|
|
cmd *exec.Cmd
|
|
)
|
|
log.Info("开始读取文件--------- : (%s)", file)
|
|
if info, err = os.Stat(file); err != nil {
|
|
return
|
|
}
|
|
if info.Size() > conf.Conf.Melloi.MaxFileSize {
|
|
cmd = exec.Command("/bin/bash", "-c", "tail -1500 "+file)
|
|
} else {
|
|
cmd = exec.Command("/bin/bash", "-c", "cat "+file)
|
|
}
|
|
buff, err = cmd.Output()
|
|
if err != nil {
|
|
return
|
|
}
|
|
data = string(buff)
|
|
return
|
|
}
|
|
|
|
//IsFileExists is file exists
|
|
func (s *Service) IsFileExists(c *bm.Context, fileName string) (bool, error) {
|
|
return exists(fileName)
|
|
}
|
|
|
|
// exists exists
|
|
func exists(path string) (bool, error) {
|
|
_, err := os.Stat(path)
|
|
if err == nil {
|
|
return true, nil
|
|
}
|
|
if os.IsNotExist(err) {
|
|
return false, nil
|
|
}
|
|
return false, err
|
|
}
|