go-common/app/admin/ep/melloi/service/file.go

298 lines
8.6 KiB
Go
Raw Normal View History

2019-04-22 10:49:16 +00:00
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
}