parent
							
								
									1d78596095
								
							
						
					
					
						commit
						939c4403af
					
				|  | @ -19,14 +19,18 @@ minio: | ||||||
|   endpoint: 127.0.0.1:9000 |   endpoint: 127.0.0.1:9000 | ||||||
|   accessKeyId: root |   accessKeyId: root | ||||||
|   secretAccessKey: OIxv7QptYBO3 |   secretAccessKey: OIxv7QptYBO3 | ||||||
|  |   bucket: jky-data | ||||||
| node: | node: | ||||||
|   host: 127.0.0.1 |   host: 127.0.0.1 | ||||||
|   port: 27188 |   port: 27188 | ||||||
|   token: 06d36c6f5705507dae778fdce90d0767 |   token: 06d36c6f5705507dae778fdce90d0767 | ||||||
| functions: | functions: | ||||||
|   - name: task-response |   - name: task-response | ||||||
|     dataTag: 14 |     dataTag: 24 | ||||||
|     mqType: 1 |     mqType: 1 | ||||||
|   - name: task-execute |   - name: task-execute | ||||||
|     dataTag: 16 |     dataTag: 16 | ||||||
|     mqType: 2 |     mqType: 2 | ||||||
|  |   - name: task-execute-log | ||||||
|  |     dataTag: 26 | ||||||
|  |     mqType: 1 | ||||||
							
								
								
									
										29
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										29
									
								
								go.mod
								
								
								
								
							|  | @ -4,8 +4,8 @@ go 1.19 | ||||||
| 
 | 
 | ||||||
| require ( | require ( | ||||||
| 	git.hpds.cc/Component/logging v0.0.0-20230106105738-e378e873921b | 	git.hpds.cc/Component/logging v0.0.0-20230106105738-e378e873921b | ||||||
| 	git.hpds.cc/Component/network v0.0.0-20221012021659-2433c68452d5 | 	git.hpds.cc/Component/network v0.0.0-20230405135741-a4ea724bab76 | ||||||
| 	git.hpds.cc/pavement/hpds_node v0.0.0-20230307094826-753c4fe9c877 | 	git.hpds.cc/pavement/hpds_node v0.0.0-20230405153516-9403c4d01e12 | ||||||
| 	github.com/docker/docker v23.0.1+incompatible | 	github.com/docker/docker v23.0.1+incompatible | ||||||
| 	github.com/docker/go-connections v0.4.0 | 	github.com/docker/go-connections v0.4.0 | ||||||
| 	github.com/emirpasic/gods v1.18.1 | 	github.com/emirpasic/gods v1.18.1 | ||||||
|  | @ -15,7 +15,7 @@ require ( | ||||||
| 	github.com/shirou/gopsutil/v3 v3.23.2 | 	github.com/shirou/gopsutil/v3 v3.23.2 | ||||||
| 	github.com/spf13/cobra v1.6.1 | 	github.com/spf13/cobra v1.6.1 | ||||||
| 	go.uber.org/zap v1.24.0 | 	go.uber.org/zap v1.24.0 | ||||||
| 	golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 | 	golang.org/x/image v0.1.0 | ||||||
| 	gopkg.in/yaml.v3 v3.0.1 | 	gopkg.in/yaml.v3 v3.0.1 | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | @ -30,15 +30,13 @@ require ( | ||||||
| 	github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect | 	github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect | ||||||
| 	github.com/gogo/protobuf v1.3.2 // indirect | 	github.com/gogo/protobuf v1.3.2 // indirect | ||||||
| 	github.com/golang/mock v1.6.0 // indirect | 	github.com/golang/mock v1.6.0 // indirect | ||||||
|  | 	github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect | ||||||
| 	github.com/google/uuid v1.3.0 // indirect | 	github.com/google/uuid v1.3.0 // indirect | ||||||
| 	github.com/inconshreveable/mousetrap v1.0.1 // indirect | 	github.com/inconshreveable/mousetrap v1.0.1 // indirect | ||||||
| 	github.com/json-iterator/go v1.1.12 // indirect | 	github.com/json-iterator/go v1.1.12 // indirect | ||||||
| 	github.com/klauspost/compress v1.15.15 // indirect | 	github.com/klauspost/compress v1.15.15 // indirect | ||||||
| 	github.com/klauspost/cpuid/v2 v2.2.3 // indirect | 	github.com/klauspost/cpuid/v2 v2.2.3 // indirect | ||||||
| 	github.com/lucas-clemente/quic-go v0.29.1 // indirect |  | ||||||
| 	github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect | 	github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect | ||||||
| 	github.com/marten-seemann/qtls-go1-18 v0.1.2 // indirect |  | ||||||
| 	github.com/marten-seemann/qtls-go1-19 v0.1.0 // indirect |  | ||||||
| 	github.com/matoous/go-nanoid/v2 v2.0.0 // indirect | 	github.com/matoous/go-nanoid/v2 v2.0.0 // indirect | ||||||
| 	github.com/minio/md5-simd v1.1.2 // indirect | 	github.com/minio/md5-simd v1.1.2 // indirect | ||||||
| 	github.com/minio/sha256-simd v1.0.0 // indirect | 	github.com/minio/sha256-simd v1.0.0 // indirect | ||||||
|  | @ -46,12 +44,14 @@ require ( | ||||||
| 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||||||
| 	github.com/modern-go/reflect2 v1.0.2 // indirect | 	github.com/modern-go/reflect2 v1.0.2 // indirect | ||||||
| 	github.com/morikuni/aec v1.0.0 // indirect | 	github.com/morikuni/aec v1.0.0 // indirect | ||||||
| 	github.com/nxadm/tail v1.4.8 // indirect | 	github.com/onsi/ginkgo/v2 v2.2.0 // indirect | ||||||
| 	github.com/onsi/ginkgo v1.16.4 // indirect |  | ||||||
| 	github.com/opencontainers/go-digest v1.0.0 // indirect | 	github.com/opencontainers/go-digest v1.0.0 // indirect | ||||||
| 	github.com/opencontainers/image-spec v1.0.2 // indirect | 	github.com/opencontainers/image-spec v1.0.2 // indirect | ||||||
| 	github.com/pkg/errors v0.9.1 // indirect | 	github.com/pkg/errors v0.9.1 // indirect | ||||||
| 	github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect | 	github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect | ||||||
|  | 	github.com/quic-go/qtls-go1-19 v0.2.1 // indirect | ||||||
|  | 	github.com/quic-go/qtls-go1-20 v0.1.1 // indirect | ||||||
|  | 	github.com/quic-go/quic-go v0.33.0 // indirect | ||||||
| 	github.com/rs/xid v1.4.0 // indirect | 	github.com/rs/xid v1.4.0 // indirect | ||||||
| 	github.com/sirupsen/logrus v1.9.0 // indirect | 	github.com/sirupsen/logrus v1.9.0 // indirect | ||||||
| 	github.com/spf13/pflag v1.0.5 // indirect | 	github.com/spf13/pflag v1.0.5 // indirect | ||||||
|  | @ -61,15 +61,20 @@ require ( | ||||||
| 	go.uber.org/atomic v1.7.0 // indirect | 	go.uber.org/atomic v1.7.0 // indirect | ||||||
| 	go.uber.org/multierr v1.6.0 // indirect | 	go.uber.org/multierr v1.6.0 // indirect | ||||||
| 	golang.org/x/crypto v0.6.0 // indirect | 	golang.org/x/crypto v0.6.0 // indirect | ||||||
| 	golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect | 	golang.org/x/exp v0.0.0-20221205204356-47842c84f3db // indirect | ||||||
| 	golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect | 	golang.org/x/mod v0.6.0 // indirect | ||||||
| 	golang.org/x/net v0.7.0 // indirect | 	golang.org/x/net v0.7.0 // indirect | ||||||
| 	golang.org/x/sys v0.5.0 // indirect | 	golang.org/x/sys v0.5.0 // indirect | ||||||
| 	golang.org/x/text v0.7.0 // indirect | 	golang.org/x/text v0.7.0 // indirect | ||||||
| 	golang.org/x/time v0.3.0 // indirect | 	golang.org/x/time v0.3.0 // indirect | ||||||
| 	golang.org/x/tools v0.1.12 // indirect | 	golang.org/x/tools v0.2.0 // indirect | ||||||
| 	gopkg.in/ini.v1 v1.67.0 // indirect | 	gopkg.in/ini.v1 v1.67.0 // indirect | ||||||
| 	gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect | 	gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect | ||||||
| 	gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect |  | ||||||
| 	gotest.tools/v3 v3.4.0 // indirect | 	gotest.tools/v3 v3.4.0 // indirect | ||||||
| ) | ) | ||||||
|  | 
 | ||||||
|  | // | ||||||
|  | //replace ( | ||||||
|  | //	git.hpds.cc/Component/network => ../network | ||||||
|  | //	git.hpds.cc/pavement/hpds_node => ../hpds_node | ||||||
|  | //) | ||||||
|  |  | ||||||
							
								
								
									
										339
									
								
								mq/handler.go
								
								
								
								
							
							
						
						
									
										339
									
								
								mq/handler.go
								
								
								
								
							|  | @ -2,11 +2,14 @@ package mq | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"bufio" | 	"bufio" | ||||||
|  | 	"bytes" | ||||||
| 	"context" | 	"context" | ||||||
| 	"encoding/base64" | 	"encoding/base64" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"git.hpds.cc/Component/network/frame" | ||||||
| 	"git.hpds.cc/pavement/hpds_node" | 	"git.hpds.cc/pavement/hpds_node" | ||||||
|  | 	"github.com/docker/docker/api/types/registry" | ||||||
| 	"github.com/emirpasic/gods/lists/arraylist" | 	"github.com/emirpasic/gods/lists/arraylist" | ||||||
| 	"github.com/fsnotify/fsnotify" | 	"github.com/fsnotify/fsnotify" | ||||||
| 	"github.com/gammazero/workerpool" | 	"github.com/gammazero/workerpool" | ||||||
|  | @ -15,6 +18,7 @@ import ( | ||||||
| 	"github.com/shirou/gopsutil/v3/host" | 	"github.com/shirou/gopsutil/v3/host" | ||||||
| 	"go.uber.org/zap" | 	"go.uber.org/zap" | ||||||
| 	"io" | 	"io" | ||||||
|  | 	"mime/multipart" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"os" | 	"os" | ||||||
| 	"os/exec" | 	"os/exec" | ||||||
|  | @ -36,8 +40,8 @@ var ( | ||||||
| 	TaskList map[string]docker.ContainerStore | 	TaskList map[string]docker.ContainerStore | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TaskExecuteHandler(data []byte) (byte, []byte) { | func TaskExecuteHandler(data []byte) (frame.Tag, []byte) { | ||||||
| 	fmt.Println("接收数据", string(data)) | 	//fmt.Println("接收数据", string(data))
 | ||||||
| 	cmd := new(InstructionReq) | 	cmd := new(InstructionReq) | ||||||
| 	err := json.Unmarshal(data, cmd) | 	err := json.Unmarshal(data, cmd) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  | @ -51,7 +55,7 @@ func TaskExecuteHandler(data []byte) (byte, []byte) { | ||||||
| 		//模型下发
 | 		//模型下发
 | ||||||
| 		waitWorkerStartFinish(config.WorkPool, cmd.Payload.(map[string]interface{}), ModelIssueRepeaterHandler) | 		waitWorkerStartFinish(config.WorkPool, cmd.Payload.(map[string]interface{}), ModelIssueRepeaterHandler) | ||||||
| 	} | 	} | ||||||
| 	return byte(cmd.Command), nil | 	return frame.Tag(cmd.Command), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func waitWorkerStartFinish(wp *workerpool.WorkerPool, payload map[string]interface{}, f func(payload map[string]interface{})) { | func waitWorkerStartFinish(wp *workerpool.WorkerPool, payload map[string]interface{}, f func(payload map[string]interface{})) { | ||||||
|  | @ -174,12 +178,14 @@ func ModelIssueRepeaterHandler(payload map[string]interface{}) { | ||||||
| 
 | 
 | ||||||
| func ModelTaskExecuteHandler(payload map[string]interface{}) { | func ModelTaskExecuteHandler(payload map[string]interface{}) { | ||||||
| 	hi, _ := host.Info() | 	hi, _ := host.Info() | ||||||
|  | 	currTime := time.Now().Unix() | ||||||
|  | 	//config.Logger.With(zap.Any("收到数据", payload))
 | ||||||
| 	if payload["nodeGuid"] == hi.HostID { | 	if payload["nodeGuid"] == hi.HostID { | ||||||
| 		if len(payload["subDataset"].(string)) > 0 { | 		if len(payload["subDataset"].(string)) > 0 { //如果是订阅数据
 | ||||||
| 			sf := hpds_node.NewStreamFunction( | 			sf := hpds_node.NewStreamFunction( | ||||||
| 				payload["subDataset"].(string), | 				payload["subDataset"].(string), | ||||||
| 				hpds_node.WithMqAddr(fmt.Sprintf("%s:%d", config.Cfg.Node.Host, config.Cfg.Node.Port)), | 				hpds_node.WithMqAddr(fmt.Sprintf("%s:%d", config.Cfg.Node.Host, config.Cfg.Node.Port)), | ||||||
| 				hpds_node.WithObserveDataTags(payload["subDataTag"].(byte)), | 				hpds_node.WithObserveDataTags(frame.Tag(payload["subDataTag"].(byte))), | ||||||
| 				hpds_node.WithCredential(config.Cfg.Node.Token), | 				hpds_node.WithCredential(config.Cfg.Node.Token), | ||||||
| 			) | 			) | ||||||
| 			err := sf.Connect() | 			err := sf.Connect() | ||||||
|  | @ -190,7 +196,7 @@ func ModelTaskExecuteHandler(payload map[string]interface{}) { | ||||||
| 				Node:     config.Cfg.Node, | 				Node:     config.Cfg.Node, | ||||||
| 				EndPoint: sf, | 				EndPoint: sf, | ||||||
| 			} | 			} | ||||||
| 			_ = sf.SetHandler(func(data []byte) (byte, []byte) { | 			_ = sf.SetHandler(func(data []byte) (frame.Tag, []byte) { | ||||||
| 
 | 
 | ||||||
| 				//查询docker是否已经开启
 | 				//查询docker是否已经开启
 | ||||||
| 				issue := new(docker.ContainerStore) | 				issue := new(docker.ContainerStore) | ||||||
|  | @ -344,12 +350,331 @@ func ModelTaskExecuteHandler(payload map[string]interface{}) { | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				return payload["subDataTag"].(byte), nil | 				return frame.Tag(payload["subDataTag"].(byte)), nil | ||||||
| 			}) | 			}) | ||||||
| 			MqList = append(MqList, nodeInfo) | 			MqList = append(MqList, nodeInfo) | ||||||
|  | 		} else { | ||||||
|  | 
 | ||||||
|  | 			//查询docker是否已经开启
 | ||||||
|  | 			issue := new(docker.ContainerStore) | ||||||
|  | 			cList := make([]registry.SearchResult, 0) | ||||||
|  | 			var err error | ||||||
|  | 			issueResult, ok := payload["issueResult"] | ||||||
|  | 			if ok { | ||||||
|  | 				if len(issueResult.(string)) > 0 { | ||||||
|  | 					_ = json.Unmarshal([]byte(payload["issueResult"].(string)), issue) | ||||||
|  | 					dCli := docker.NewDockerClient() | ||||||
|  | 					cList, err = dCli.SearchImage(issue.Name) | ||||||
|  | 					if err != nil { | ||||||
|  | 
 | ||||||
|  | 					} | ||||||
|  | 					if len(cList) < 1 { | ||||||
|  | 						//TODO: 启动容器
 | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} else { | ||||||
|  | 				issue.DstPort = "5000" | ||||||
|  | 				issue.HttpUrl = "" | ||||||
|  | 			} | ||||||
|  | 			//如果是数据集任务
 | ||||||
|  | 			if _, ok := payload["single"]; ok { | ||||||
|  | 				f := payload["single"].(map[string]interface{}) | ||||||
|  | 				if len(payload["workflow"].(string)) > 0 { | ||||||
|  | 					//是否设置工作流程
 | ||||||
|  | 					wf := new(Workflow) | ||||||
|  | 					err = json.Unmarshal([]byte(payload["workflow"].(string)), wf) | ||||||
|  | 					if err != nil { | ||||||
|  | 
 | ||||||
|  | 					} | ||||||
|  | 					fn := proto.FileCapture{ | ||||||
|  | 						FileId:      int64(f["fileId"].(float64)), | ||||||
|  | 						FileName:    f["fileName"].(string), | ||||||
|  | 						File:        f["file"].(string), | ||||||
|  | 						DatasetName: payload["datasetName"].(string), | ||||||
|  | 						CaptureTime: int64(f["captureTime"].(float64)), | ||||||
|  | 					} | ||||||
|  | 					ProcessWorkflow(payload, fn, wf) | ||||||
|  | 					//if len(payload["datasetPath"].(string)) > 0 {
 | ||||||
|  | 					//	//数据集处理
 | ||||||
|  | 					//	opt := &minio.Options{
 | ||||||
|  | 					//		Creds:  credentials.NewStaticV4(config.Cfg.Minio.AccessKeyId, config.Cfg.Minio.SecretAccessKey, ""),
 | ||||||
|  | 					//		Secure: false,
 | ||||||
|  | 					//	}
 | ||||||
|  | 					//	cli, _ := minio.New(config.Cfg.Minio.Endpoint, opt)
 | ||||||
|  | 					//	doneCh := make(chan struct{})
 | ||||||
|  | 					//	defer close(doneCh)
 | ||||||
|  | 					//	objectCh := cli.ListObjects(context.Background(), config.Cfg.Minio.Bucket, minio.ListObjectsOptions{
 | ||||||
|  | 					//		Prefix:    payload["datasetPath"].(string),
 | ||||||
|  | 					//		Recursive: true,
 | ||||||
|  | 					//	})
 | ||||||
|  | 					//	for object := range objectCh {
 | ||||||
|  | 					//		file, _ := cli.GetObject(context.Background(), config.Cfg.Minio.Bucket, object.Key, minio.GetObjectOptions{})
 | ||||||
|  | 					//		imgByte, _ := io.ReadAll(file)
 | ||||||
|  | 					//
 | ||||||
|  | 					//		f := proto.FileCapture{
 | ||||||
|  | 					//			FileName:    object.Key,
 | ||||||
|  | 					//			File:        base64.StdEncoding.EncodeToString(imgByte),
 | ||||||
|  | 					//			DatasetName: payload["datasetName"].(string),
 | ||||||
|  | 					//			CaptureTime: object.LastModified.Unix(),
 | ||||||
|  | 					//		}
 | ||||||
|  | 					//		ProcessWorkflow(payload, f, wf)
 | ||||||
|  | 					//	}
 | ||||||
|  | 					//
 | ||||||
|  | 					//}
 | ||||||
|  | 				} else { | ||||||
|  | 					reqUrl := fmt.Sprintf("http://127.0.0.1:%s/%s", issue.DstPort, issue.HttpUrl) | ||||||
|  | 					if len(payload["httpUrl"].(string)) > 0 { | ||||||
|  | 						reqUrl = payload["httpUrl"].(string) | ||||||
|  | 					} | ||||||
|  | 					fc := f["file"].(string) | ||||||
|  | 					dec := base64.NewDecoder(base64.StdEncoding, strings.NewReader(fc)) | ||||||
|  | 
 | ||||||
|  | 					buff := new(bytes.Buffer) | ||||||
|  | 					writer := multipart.NewWriter(buff) | ||||||
|  | 					formFile, _ := writer.CreateFormFile("image", f["fileName"].(string)) | ||||||
|  | 					_, _ = io.Copy(formFile, dec) | ||||||
|  | 					_ = writer.Close() | ||||||
|  | 
 | ||||||
|  | 					response, err := http.Post(reqUrl, writer.FormDataContentType(), buff) | ||||||
|  | 					if err != nil { | ||||||
|  | 						config.Logger.With(zap.String("源文件名", f["fileName"].(string))). | ||||||
|  | 							With(zap.String("临时文件名", path.Join(config.Cfg.TmpPath, payload["subDataset"].(string), f["fileName"].(string)))). | ||||||
|  | 							Error("文件提交", zap.Error(err)) | ||||||
|  | 					} | ||||||
|  | 					defer func() { | ||||||
|  | 						_ = response.Body.Close() | ||||||
|  | 					}() | ||||||
|  | 					body, err := io.ReadAll(response.Body) | ||||||
|  | 					if err != nil { | ||||||
|  | 						config.Logger.With(zap.String("源文件名", f["fileName"].(string))). | ||||||
|  | 							With(zap.String("临时文件名", path.Join(config.Cfg.TmpPath, payload["subDataset"].(string), f["fileName"].(string)))). | ||||||
|  | 							Error("模型识别", zap.Error(err)) | ||||||
|  | 					} | ||||||
|  | 					cli := GetMqClient("task-response", 1) | ||||||
|  | 					pay := make(map[string]interface{}) | ||||||
|  | 					pay["taskId"] = payload["taskId"] | ||||||
|  | 					pay["fileId"] = f["fileId"] | ||||||
|  | 					pay["taskCode"] = payload["taskCode"] | ||||||
|  | 					pay["nodeId"] = payload["nodeId"] | ||||||
|  | 					pay["modelId"] = payload["modelId"] | ||||||
|  | 					pay["startTime"] = currTime | ||||||
|  | 					pay["finishTime"] = time.Now().Unix() | ||||||
|  | 					pay["subDataset"] = payload["subDataset"] | ||||||
|  | 					pay["datasetArr"] = payload["datasetArr"] | ||||||
|  | 					pay["srcPath"] = f["fileName"] | ||||||
|  | 					pay["body"] = string(body) | ||||||
|  | 					ap := cli.EndPoint.(hpds_node.AccessPoint) | ||||||
|  | 					res := new(InstructionReq) | ||||||
|  | 					res.Command = TaskResponse | ||||||
|  | 					res.Payload = pay | ||||||
|  | 					pData, _ := json.Marshal(res) | ||||||
|  | 					_ = GenerateAndSendData(ap, pData) | ||||||
|  | 
 | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			//if len(cList) > 0 {
 | ||||||
|  | 			//if len(payload["workflow"].(string)) > 0 {
 | ||||||
|  | 			//	//是否设置工作流程
 | ||||||
|  | 			//	wf := new(Workflow)
 | ||||||
|  | 			//	err = json.Unmarshal([]byte(payload["workflow"].(string)), wf)
 | ||||||
|  | 			//	if err != nil {
 | ||||||
|  | 			//
 | ||||||
|  | 			//	}
 | ||||||
|  | 			//	if len(payload["datasetPath"].(string)) > 0 {
 | ||||||
|  | 			//		//数据集处理
 | ||||||
|  | 			//		opt := &minio.Options{
 | ||||||
|  | 			//			Creds:  credentials.NewStaticV4(config.Cfg.Minio.AccessKeyId, config.Cfg.Minio.SecretAccessKey, ""),
 | ||||||
|  | 			//			Secure: false,
 | ||||||
|  | 			//		}
 | ||||||
|  | 			//		cli, _ := minio.New(config.Cfg.Minio.Endpoint, opt)
 | ||||||
|  | 			//		doneCh := make(chan struct{})
 | ||||||
|  | 			//		defer close(doneCh)
 | ||||||
|  | 			//		objectCh := cli.ListObjects(context.Background(), config.Cfg.Minio.Bucket, minio.ListObjectsOptions{
 | ||||||
|  | 			//			Prefix:    payload["datasetPath"].(string),
 | ||||||
|  | 			//			Recursive: true,
 | ||||||
|  | 			//		})
 | ||||||
|  | 			//		for object := range objectCh {
 | ||||||
|  | 			//			file, _ := cli.GetObject(context.Background(), config.Cfg.Minio.Bucket, object.Key, minio.GetObjectOptions{})
 | ||||||
|  | 			//			imgByte, _ := io.ReadAll(file)
 | ||||||
|  | 			//
 | ||||||
|  | 			//			f := proto.FileCapture{
 | ||||||
|  | 			//				FileName:    object.Key,
 | ||||||
|  | 			//				File:        base64.StdEncoding.EncodeToString(imgByte),
 | ||||||
|  | 			//				DatasetName: payload["datasetName"].(string),
 | ||||||
|  | 			//				CaptureTime: object.LastModified.Unix(),
 | ||||||
|  | 			//			}
 | ||||||
|  | 			//			ProcessWorkflow(payload, f, wf)
 | ||||||
|  | 			//		}
 | ||||||
|  | 			//
 | ||||||
|  | 			//	}
 | ||||||
|  | 			//} else {
 | ||||||
|  | 			//	if len(payload["datasetPath"].(string)) > 0 {
 | ||||||
|  | 			//		//数据集处理
 | ||||||
|  | 			//		opt := &minio.Options{
 | ||||||
|  | 			//			Creds:  credentials.NewStaticV4(config.Cfg.Minio.AccessKeyId, config.Cfg.Minio.SecretAccessKey, ""),
 | ||||||
|  | 			//			Secure: false,
 | ||||||
|  | 			//		}
 | ||||||
|  | 			//		cli, _ := minio.New(config.Cfg.Minio.Endpoint, opt)
 | ||||||
|  | 			//		doneCh := make(chan struct{})
 | ||||||
|  | 			//		defer close(doneCh)
 | ||||||
|  | 			//		objectCh := cli.ListObjects(context.Background(), config.Cfg.Minio.Bucket, minio.ListObjectsOptions{
 | ||||||
|  | 			//			Prefix:    payload["datasetPath"].(string),
 | ||||||
|  | 			//			Recursive: true,
 | ||||||
|  | 			//		})
 | ||||||
|  | 			//		for object := range objectCh {
 | ||||||
|  | 			//			file, _ := cli.GetObject(context.Background(), config.Cfg.Minio.Bucket, object.Key, minio.GetObjectOptions{})
 | ||||||
|  | 			//			imgByte, _ := io.ReadAll(file)
 | ||||||
|  | 			//
 | ||||||
|  | 			//			f := proto.FileCapture{
 | ||||||
|  | 			//				FileName:    object.Key,
 | ||||||
|  | 			//				File:        base64.StdEncoding.EncodeToString(imgByte),
 | ||||||
|  | 			//				DatasetName: payload["datasetName"].(string),
 | ||||||
|  | 			//				CaptureTime: object.LastModified.Unix(),
 | ||||||
|  | 			//			}
 | ||||||
|  | 			//
 | ||||||
|  | 			//			if len(payload["httpUrl"].(string)) > 0 {
 | ||||||
|  | 			//				dec := base64.NewDecoder(base64.StdEncoding, strings.NewReader(f.File))
 | ||||||
|  | 			//				reqUrl := fmt.Sprintf("http://localhost:%s/%s", issue.DstPort, issue.HttpUrl)
 | ||||||
|  | 			//				response, err := http.Post(reqUrl, "multipart/form-data", dec)
 | ||||||
|  | 			//				if err != nil {
 | ||||||
|  | 			//					config.Logger.With(zap.String("源文件名", f.FileName)).
 | ||||||
|  | 			//						With(zap.String("临时文件名", path.Join(config.Cfg.TmpPath, payload["subDataset"].(string), f.FileName))).
 | ||||||
|  | 			//						Error("文件提交", zap.Error(err))
 | ||||||
|  | 			//				}
 | ||||||
|  | 			//				defer func() {
 | ||||||
|  | 			//					_ = response.Body.Close()
 | ||||||
|  | 			//					config.Logger.With(zap.String("源文件名", f.FileName)).
 | ||||||
|  | 			//						With(zap.String("临时文件名", path.Join(config.Cfg.TmpPath, payload["subDataset"].(string), f.FileName))).
 | ||||||
|  | 			//						Info("模型识别")
 | ||||||
|  | 			//				}()
 | ||||||
|  | 			//				body, err := io.ReadAll(response.Body)
 | ||||||
|  | 			//				if err != nil {
 | ||||||
|  | 			//					config.Logger.With(zap.String("源文件名", f.FileName)).
 | ||||||
|  | 			//						With(zap.String("临时文件名", path.Join(config.Cfg.TmpPath, payload["subDataset"].(string), f.FileName))).
 | ||||||
|  | 			//						Error("模型识别", zap.Error(err))
 | ||||||
|  | 			//				}
 | ||||||
|  | 			//				cli := GetMqClient("task-response", 1)
 | ||||||
|  | 			//				ap := cli.EndPoint.(hpds_node.AccessPoint)
 | ||||||
|  | 			//				res := new(InstructionReq)
 | ||||||
|  | 			//				res.Command = TaskResponse
 | ||||||
|  | 			//				res.Payload = body
 | ||||||
|  | 			//				pData, _ := json.Marshal(res)
 | ||||||
|  | 			//				_ = GenerateAndSendData(ap, pData)
 | ||||||
|  | 			//			}
 | ||||||
|  | 			//		}
 | ||||||
|  | 			//	}
 | ||||||
|  | 			//f := new(proto.FileCapture)
 | ||||||
|  | 			//err := json.Unmarshal(data, f)
 | ||||||
|  | 			//if err != nil {
 | ||||||
|  | 			//
 | ||||||
|  | 			//}
 | ||||||
|  | 			//if len(f.File) > 0 {
 | ||||||
|  | 			//
 | ||||||
|  | 			//	i := strings.Index(f.File, ",")
 | ||||||
|  | 			//	dec := base64.NewDecoder(base64.StdEncoding, strings.NewReader(f.File[i+1:]))
 | ||||||
|  | 			//	if len(payload["httpUrl"].(string)) > 0 {
 | ||||||
|  | 			//		_ = os.MkdirAll(path.Join(config.Cfg.TmpPath, payload["subDataset"].(string)), os.ModePerm)
 | ||||||
|  | 			//		tmpFile, _ := os.Create(path.Join(config.Cfg.TmpPath, payload["subDataset"].(string), f.FileName))
 | ||||||
|  | 			//		_, err = io.Copy(tmpFile, dec)
 | ||||||
|  | 			//
 | ||||||
|  | 			//		reqUrl := fmt.Sprintf("http://localhost:%s/%s", issue.DstPort, issue.HttpUrl)
 | ||||||
|  | 			//		response, err := http.Post(reqUrl, "multipart/form-data", dec)
 | ||||||
|  | 			//		if err != nil {
 | ||||||
|  | 			//			config.Logger.With(zap.String("源文件名", f.FileName)).
 | ||||||
|  | 			//				With(zap.String("临时文件名", path.Join(config.Cfg.TmpPath, payload["subDataset"].(string), f.FileName))).
 | ||||||
|  | 			//				Error("文件提交", zap.Error(err))
 | ||||||
|  | 			//		}
 | ||||||
|  | 			//		defer func() {
 | ||||||
|  | 			//			_ = response.Body.Close()
 | ||||||
|  | 			//			config.Logger.With(zap.String("源文件名", f.FileName)).
 | ||||||
|  | 			//				With(zap.String("临时文件名", path.Join(config.Cfg.TmpPath, payload["subDataset"].(string), f.FileName))).
 | ||||||
|  | 			//				Info("模型识别")
 | ||||||
|  | 			//		}()
 | ||||||
|  | 			//		body, err := io.ReadAll(response.Body)
 | ||||||
|  | 			//		if err != nil {
 | ||||||
|  | 			//			config.Logger.With(zap.String("源文件名", f.FileName)).
 | ||||||
|  | 			//				With(zap.String("临时文件名", path.Join(config.Cfg.TmpPath, payload["subDataset"].(string), f.FileName))).
 | ||||||
|  | 			//				Error("模型识别", zap.Error(err))
 | ||||||
|  | 			//		}
 | ||||||
|  | 			//		cli := GetMqClient("task-response", 1)
 | ||||||
|  | 			//		ap := cli.EndPoint.(hpds_node.AccessPoint)
 | ||||||
|  | 			//		res := new(InstructionReq)
 | ||||||
|  | 			//		res.Command = TaskResponse
 | ||||||
|  | 			//		res.Payload = body
 | ||||||
|  | 			//		pData, _ := json.Marshal(res)
 | ||||||
|  | 			//		_ = GenerateAndSendData(ap, pData)
 | ||||||
|  | 			//	}
 | ||||||
|  | 			//	if len(payload["inPath"].(string)) > 0 {
 | ||||||
|  | 			//		outPath := ""
 | ||||||
|  | 			//		for k, v := range issue.Volumes {
 | ||||||
|  | 			//			if v == payload["outPath"].(string) {
 | ||||||
|  | 			//				outPath = k
 | ||||||
|  | 			//				break
 | ||||||
|  | 			//			}
 | ||||||
|  | 			//		}
 | ||||||
|  | 			//		//创建一个监控对象
 | ||||||
|  | 			//		watch, err := fsnotify.NewWatcher()
 | ||||||
|  | 			//		if err != nil {
 | ||||||
|  | 			//			config.Logger.Error("创建文件监控", zap.Error(err))
 | ||||||
|  | 			//		}
 | ||||||
|  | 			//		defer func(watch *fsnotify.Watcher) {
 | ||||||
|  | 			//			_ = watch.Close()
 | ||||||
|  | 			//		}(watch)
 | ||||||
|  | 			//
 | ||||||
|  | 			//		err = watch.Add(outPath)
 | ||||||
|  | 			//		if err != nil {
 | ||||||
|  | 			//			config.Logger.With(zap.String("监控目录", outPath)).
 | ||||||
|  | 			//				Error("创建文件监控", zap.Error(err))
 | ||||||
|  | 			//		}
 | ||||||
|  | 			//		for k, v := range issue.Volumes {
 | ||||||
|  | 			//			if v == payload["inPath"].(string) {
 | ||||||
|  | 			//				_ = os.MkdirAll(k, os.ModePerm)
 | ||||||
|  | 			//				tmpFile, _ := os.Create(path.Join(k, f.FileName))
 | ||||||
|  | 			//				_, err = io.Copy(tmpFile, dec)
 | ||||||
|  | 			//				break
 | ||||||
|  | 			//			}
 | ||||||
|  | 			//		}
 | ||||||
|  | 			//		list := arraylist.New() // empty
 | ||||||
|  | 			//		t1 := time.NewTicker(1 * time.Second)
 | ||||||
|  | 			//		go func() {
 | ||||||
|  | 			//			for {
 | ||||||
|  | 			//				select {
 | ||||||
|  | 			//				case ev := <-watch.Events:
 | ||||||
|  | 			//					{
 | ||||||
|  | 			//						//判断事件发生的类型,如下5种
 | ||||||
|  | 			//						// Create 创建
 | ||||||
|  | 			//						// Write 写入
 | ||||||
|  | 			//						// Remove 删除
 | ||||||
|  | 			//						// Rename 重命名
 | ||||||
|  | 			//						// Chmod 修改权限
 | ||||||
|  | 			//						if ev.Op&fsnotify.Create == fsnotify.Create {
 | ||||||
|  | 			//							config.Logger.Info("创建文件", zap.String("文件名", ev.Name))
 | ||||||
|  | 			//							list.Add(ev.Name)
 | ||||||
|  | 			//						}
 | ||||||
|  | 			//					}
 | ||||||
|  | 			//				case <-t1.C:
 | ||||||
|  | 			//					{
 | ||||||
|  | 			//						if list.Size() > 0 {
 | ||||||
|  | 			//							returnFileHandleResult(list, payload, issue)
 | ||||||
|  | 			//						}
 | ||||||
|  | 			//					}
 | ||||||
|  | 			//				case err = <-watch.Errors:
 | ||||||
|  | 			//					{
 | ||||||
|  | 			//						config.Logger.With(zap.String("监控目录", outPath)).
 | ||||||
|  | 			//							Error("文件监控", zap.Error(err))
 | ||||||
|  | 			//						return
 | ||||||
|  | 			//					}
 | ||||||
|  | 			//				}
 | ||||||
|  | 			//			}
 | ||||||
|  | 			//		}()
 | ||||||
|  | 			//	}
 | ||||||
|  | 			//}
 | ||||||
| 		} | 		} | ||||||
|  | 		//}
 | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | 
 | ||||||
| func returnFileHandleResult(list *arraylist.List, payload map[string]interface{}, issue *docker.ContainerStore) { | func returnFileHandleResult(list *arraylist.List, payload map[string]interface{}, issue *docker.ContainerStore) { | ||||||
| 	var ( | 	var ( | ||||||
| 		mu      sync.RWMutex | 		mu      sync.RWMutex | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ package mq | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"git.hpds.cc/Component/logging" | 	"git.hpds.cc/Component/logging" | ||||||
|  | 	"git.hpds.cc/Component/network/frame" | ||||||
| 	"go.uber.org/zap" | 	"go.uber.org/zap" | ||||||
| 	"os" | 	"os" | ||||||
| 	"taskExecute/config" | 	"taskExecute/config" | ||||||
|  | @ -40,7 +41,7 @@ func NewMqClient(funcs []config.FuncConfig, node config.HpdsNode, logger *loggin | ||||||
| 			sf := hpds_node.NewStreamFunction( | 			sf := hpds_node.NewStreamFunction( | ||||||
| 				v.Name, | 				v.Name, | ||||||
| 				hpds_node.WithMqAddr(fmt.Sprintf("%s:%d", node.Host, node.Port)), | 				hpds_node.WithMqAddr(fmt.Sprintf("%s:%d", node.Host, node.Port)), | ||||||
| 				hpds_node.WithObserveDataTags(v.DataTag), | 				hpds_node.WithObserveDataTags(frame.Tag(v.DataTag)), | ||||||
| 				hpds_node.WithCredential(node.Token), | 				hpds_node.WithCredential(node.Token), | ||||||
| 			) | 			) | ||||||
| 			err = sf.Connect() | 			err = sf.Connect() | ||||||
|  | @ -72,7 +73,7 @@ func NewMqClient(funcs []config.FuncConfig, node config.HpdsNode, logger *loggin | ||||||
| 				EndPoint: ap, | 				EndPoint: ap, | ||||||
| 			} | 			} | ||||||
| 			must(logger, err) | 			must(logger, err) | ||||||
| 			ap.SetDataTag(v.DataTag) | 			ap.SetDataTag(frame.Tag(v.DataTag)) | ||||||
| 			mqList = append(mqList, nodeInfo) | 			mqList = append(mqList, nodeInfo) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -7,6 +7,7 @@ const ( | ||||||
| 	TaskResponse | 	TaskResponse | ||||||
| 	ModelIssueRepeater | 	ModelIssueRepeater | ||||||
| 	ModelIssueResponse | 	ModelIssueResponse | ||||||
|  | 	TaskExecuteLog | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type InstructionReq struct { | type InstructionReq struct { | ||||||
|  | @ -20,9 +21,18 @@ type TaskResponseBody struct { | ||||||
| 	TaskCode   string `json:"taskCode"` | 	TaskCode   string `json:"taskCode"` | ||||||
| 	NodeId     int64  `json:"nodeId"` | 	NodeId     int64  `json:"nodeId"` | ||||||
| 	ModelId    int64  `json:"modelId"` | 	ModelId    int64  `json:"modelId"` | ||||||
|  | 	FileId     int64  `json:"fileId"` | ||||||
| 	SrcPath    string `json:"srcPath"` | 	SrcPath    string `json:"srcPath"` | ||||||
|  | 	DatasetArr string `json:"datasetArr"` | ||||||
| 	StartTime  int64  `json:"startTime"` | 	StartTime  int64  `json:"startTime"` | ||||||
| 	FinishTime int64  `json:"finishTime"` | 	FinishTime int64  `json:"finishTime"` | ||||||
| 	Msg        string `json:"msg"` | 	Msg        string `json:"msg"` | ||||||
| 	Body       string `json:"body"` | 	Body       string `json:"body"` | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | type TaskExecuteLogStruct struct { | ||||||
|  | 	TaskId   int64       `json:"taskId"` | ||||||
|  | 	TaskCode string      `json:"taskCode"` | ||||||
|  | 	NodeGuid string      `json:"nodeGuid"` | ||||||
|  | 	Payload  interface{} `json:"payload"` | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										128
									
								
								mq/service.go
								
								
								
								
							
							
						
						
									
										128
									
								
								mq/service.go
								
								
								
								
							|  | @ -1,11 +1,16 @@ | ||||||
| package mq | package mq | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"bytes" | ||||||
| 	"encoding/base64" | 	"encoding/base64" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"git.hpds.cc/pavement/hpds_node" | 	"git.hpds.cc/pavement/hpds_node" | ||||||
|  | 	"golang.org/x/image/bmp" | ||||||
|  | 	"golang.org/x/image/tiff" | ||||||
| 	"image" | 	"image" | ||||||
|  | 	"image/jpeg" | ||||||
|  | 	"image/png" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"taskExecute/pkg/utils" | 	"taskExecute/pkg/utils" | ||||||
| 	"taskExecute/proto" | 	"taskExecute/proto" | ||||||
|  | @ -40,8 +45,8 @@ func CreateWorkflowQueue(wf *Workflow) *WorkflowQueue { | ||||||
| func ProcessWorkflow(payload map[string]interface{}, fc proto.FileCapture, wf *Workflow) { | func ProcessWorkflow(payload map[string]interface{}, fc proto.FileCapture, wf *Workflow) { | ||||||
| 	qList := CreateWorkflowQueue(wf) | 	qList := CreateWorkflowQueue(wf) | ||||||
| 	var ( | 	var ( | ||||||
| 		img image.Image | 		img        image.Image | ||||||
| 		//imgBase64  string
 | 		imgList    []image.Image | ||||||
| 		imgType    string = "jpeg" | 		imgType    string = "jpeg" | ||||||
| 		err        error | 		err        error | ||||||
| 		resultData string | 		resultData string | ||||||
|  | @ -50,17 +55,24 @@ func ProcessWorkflow(payload map[string]interface{}, fc proto.FileCapture, wf *W | ||||||
| 	for i := 0; i < len(wf.Nodes); i++ { | 	for i := 0; i < len(wf.Nodes); i++ { | ||||||
| 		nodeId, _ := qList.Pop() | 		nodeId, _ := qList.Pop() | ||||||
| 		node := GetWorkflowNodeById(wf, nodeId) | 		node := GetWorkflowNodeById(wf, nodeId) | ||||||
|  | 		if node == nil { | ||||||
|  | 			continue | ||||||
|  | 		} | ||||||
| 		switch node.Type { | 		switch node.Type { | ||||||
| 		case "start-node": | 		case "start-node": | ||||||
| 			continue | 			fn, _ := base64.StdEncoding.DecodeString(fc.File) | ||||||
|  | 			buff := bytes.NewBuffer(fn) | ||||||
|  | 			img, imgType, _ = image.Decode(buff) | ||||||
| 		case "image-node": | 		case "image-node": | ||||||
| 			//处理图像后
 | 			//处理图像后
 | ||||||
| 			fn, _ := base64.StdEncoding.DecodeString(fc.File) | 			fn := utils.ImageToBuff(img, imgType) | ||||||
| 			if node.Properties.NodeData.Method == "crop" { | 			if node.Properties.NodeData.Method == "zoom" { | ||||||
| 				img, imgType, err = utils.Clip(fn, node.Properties.NodeData.Width, node.Properties.NodeData.Height, node.Properties.NodeData.EqualProportion) | 				img, imgType, err = utils.Clip(fn, node.Properties.NodeData.Width, node.Properties.NodeData.Height, node.Properties.NodeData.EqualProportion) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
| 					goto ReturnPoint | 					goto ReturnPoint | ||||||
| 				} | 				} | ||||||
|  | 			} else if node.Properties.NodeData.Method == "crop" { | ||||||
|  | 				imgList = utils.SplitImage(fn, node.Properties.NodeData.Width, node.Properties.NodeData.Height) | ||||||
| 			} else if node.Properties.NodeData.Method == "gray" { | 			} else if node.Properties.NodeData.Method == "gray" { | ||||||
| 				img, err = utils.Gray(fn) | 				img, err = utils.Gray(fn) | ||||||
| 				if err != nil { | 				if err != nil { | ||||||
|  | @ -75,56 +87,104 @@ func ProcessWorkflow(payload map[string]interface{}, fc proto.FileCapture, wf *W | ||||||
| 				case 270: | 				case 270: | ||||||
| 					img = utils.Rotate270(fn) | 					img = utils.Rotate270(fn) | ||||||
| 				default: | 				default: | ||||||
| 					img = utils.BuffToImage(fn) | 					img, _, _ = image.Decode(fn) | ||||||
| 				} | 				} | ||||||
| 			} else if node.Properties.NodeData.Method == "formatConversion" { | 			} else if node.Properties.NodeData.Method == "formatConversion" { | ||||||
| 				img = utils.BuffToImage(fn) | 				//img = utils.BuffToImage(fn)
 | ||||||
| 				switch node.Properties.NodeData.Format { | 				switch node.Properties.NodeData.Format { | ||||||
| 				case "bmp": | 				case "bmp": | ||||||
| 					imgType = "bmp" | 					imgType = "bmp" | ||||||
|  | 					_ = bmp.Encode(fn, img) | ||||||
| 				case "png": | 				case "png": | ||||||
| 					imgType = "png" | 					imgType = "png" | ||||||
|  | 					_ = png.Encode(fn, img) | ||||||
| 				case "tiff": | 				case "tiff": | ||||||
| 					imgType = "tiff" | 					imgType = "tiff" | ||||||
|  | 					_ = tiff.Encode(fn, img, &tiff.Options{Predictor: false}) | ||||||
| 				default: | 				default: | ||||||
| 					imgType = "jpeg" | 					imgType = "jpeg" | ||||||
|  | 					_ = jpeg.Encode(fn, img, &jpeg.Options{ | ||||||
|  | 						Quality: 100, | ||||||
|  | 					}) | ||||||
| 				} | 				} | ||||||
|  | 
 | ||||||
|  | 				img, _, _ = image.Decode(fn) | ||||||
| 			} | 			} | ||||||
| 		case "fetch-node": | 		case "fetch-node": | ||||||
| 			header := make(map[string]string) | 			header := make(map[string]string) | ||||||
| 			header["ContentType"] = node.Properties.NodeData.ContentType | 			header["ContentType"] = node.Properties.NodeData.ContentType | ||||||
| 			param := make(map[string]string) | 			param := make(map[string]string) | ||||||
| 			isBody := false | 			isBody := false | ||||||
| 			for _, val := range node.Properties.NodeData.DynamicValidateForm.Fields { | 			if len(imgList) > 0 { | ||||||
| 				switch val.Type { | 				result := make([]string, len(imgList)) | ||||||
| 				case "fileName": | 				for idx, subImg := range imgList { | ||||||
| 					param[val.Key] = fc.FileName | 					for _, val := range node.Properties.NodeData.DynamicValidateForm.Fields { | ||||||
| 				case "imgBase64": | 						switch val.Type { | ||||||
| 					param[val.Key] = utils.ImageToBase64(img, imgType) | 						case "fileName": | ||||||
| 				default: | 							param[val.Key] = fc.FileName | ||||||
| 					isBody = true | 						case "imgBase64": | ||||||
|  | 							param[val.Key] = utils.ImageToBase64(subImg, imgType) | ||||||
|  | 						default: | ||||||
|  | 							isBody = true | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 					if !isBody { | ||||||
|  | 						data, e := utils.HttpDo(fmt.Sprintf("%s%s", node.Properties.NodeData.Proto, node.Properties.NodeData.Url), | ||||||
|  | 							strings.ToUpper(node.Properties.NodeData.MethodType), param, header) | ||||||
|  | 						if e != nil { | ||||||
|  | 							err = e | ||||||
|  | 							goto ReturnPoint | ||||||
|  | 						} | ||||||
|  | 						result[idx] = string(data) | ||||||
|  | 						//resultData = string(data)
 | ||||||
|  | 					} else { | ||||||
|  | 						buff := utils.ImageToBuff(subImg, imgType) | ||||||
|  | 						files := make([]utils.UploadFile, 1) | ||||||
|  | 						files[0] = utils.UploadFile{ | ||||||
|  | 							Name:     "image", | ||||||
|  | 							Filepath: "./output.jpg", | ||||||
|  | 							File:     buff, | ||||||
|  | 						} | ||||||
|  | 						data := utils.PostFile(fmt.Sprintf("%s%s", node.Properties.NodeData.Proto, node.Properties.NodeData.Url), | ||||||
|  | 							param, "multipart/form-data", files, header) | ||||||
|  | 						//resultData = data
 | ||||||
|  | 						result[idx] = string(data) | ||||||
|  | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 				resultStr, _ := json.Marshal(result) | ||||||
| 			if !isBody { | 				resultData = string(resultStr) | ||||||
| 				data, err := utils.HttpDo(fmt.Sprintf("%s%s", node.Properties.NodeData.Proto, node.Properties.NodeData.Url), |  | ||||||
| 					strings.ToUpper(node.Properties.NodeData.MethodType), param, header) |  | ||||||
| 				if err != nil { |  | ||||||
| 					goto ReturnPoint |  | ||||||
| 				} |  | ||||||
| 				resultData = string(data) |  | ||||||
| 			} else { | 			} else { | ||||||
| 				buff := utils.ImageToBuff(img, imgType) | 				for _, val := range node.Properties.NodeData.DynamicValidateForm.Fields { | ||||||
| 				files := make([]utils.UploadFile, 1) | 					switch val.Type { | ||||||
| 				files[0] = utils.UploadFile{ | 					case "fileName": | ||||||
| 					Name:     "file", | 						param[val.Key] = fc.FileName | ||||||
| 					Filepath: "./output.jpg", | 					case "imgBase64": | ||||||
| 					File:     buff, | 						param[val.Key] = utils.ImageToBase64(img, imgType) | ||||||
|  | 					default: | ||||||
|  | 						isBody = true | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				if !isBody { | ||||||
|  | 					data, e := utils.HttpDo(fmt.Sprintf("%s%s", node.Properties.NodeData.Proto, node.Properties.NodeData.Url), | ||||||
|  | 						strings.ToUpper(node.Properties.NodeData.MethodType), param, header) | ||||||
|  | 					if e != nil { | ||||||
|  | 						err = e | ||||||
|  | 						goto ReturnPoint | ||||||
|  | 					} | ||||||
|  | 					resultData = string(data) | ||||||
|  | 				} else { | ||||||
|  | 					buff := utils.ImageToBuff(img, imgType) | ||||||
|  | 					files := make([]utils.UploadFile, 1) | ||||||
|  | 					files[0] = utils.UploadFile{ | ||||||
|  | 						Name:     "image", | ||||||
|  | 						Filepath: "./output.jpg", | ||||||
|  | 						File:     buff, | ||||||
|  | 					} | ||||||
|  | 					data := utils.PostFile(fmt.Sprintf("%s%s", node.Properties.NodeData.Proto, node.Properties.NodeData.Url), | ||||||
|  | 						param, "multipart/form-data", files, header) | ||||||
|  | 					resultData = data | ||||||
| 				} | 				} | ||||||
| 				data := utils.PostFile(fmt.Sprintf("%s%s", node.Properties.NodeData.Proto, node.Properties.NodeData.Url), |  | ||||||
| 					param, "multipart/form-data", files, header) |  | ||||||
| 				resultData = data |  | ||||||
| 			} | 			} | ||||||
| 
 |  | ||||||
| 		case "model-node": | 		case "model-node": | ||||||
| 			continue | 			continue | ||||||
| 		case "mq-node": | 		case "mq-node": | ||||||
|  | @ -139,6 +199,8 @@ ReturnPoint: | ||||||
| 	item.TaskCode = payload["taskCode"].(string) | 	item.TaskCode = payload["taskCode"].(string) | ||||||
| 	item.NodeId = int64(payload["nodeId"].(float64)) | 	item.NodeId = int64(payload["nodeId"].(float64)) | ||||||
| 	item.ModelId = int64(payload["modelId"].(float64)) | 	item.ModelId = int64(payload["modelId"].(float64)) | ||||||
|  | 	item.DatasetArr = payload["datasetArr"].(string) | ||||||
|  | 	item.FileId = fc.FileId | ||||||
| 	item.SrcPath = fc.FileName | 	item.SrcPath = fc.FileName | ||||||
| 	item.StartTime = startTime | 	item.StartTime = startTime | ||||||
| 	item.FinishTime = time.Now().Unix() | 	item.FinishTime = time.Now().Unix() | ||||||
|  |  | ||||||
|  | @ -14,13 +14,19 @@ import ( | ||||||
| 
 | 
 | ||||||
| func HttpDo(reqUrl, method string, params map[string]string, header map[string]string) (data []byte, err error) { | func HttpDo(reqUrl, method string, params map[string]string, header map[string]string) (data []byte, err error) { | ||||||
| 	var paramStr string = "" | 	var paramStr string = "" | ||||||
| 	for k, v := range params { | 	if contentType, ok := header["ContentType"]; ok && strings.Contains(contentType, "json") { | ||||||
| 		if len(paramStr) == 0 { | 		bytesData, _ := json.Marshal(params) | ||||||
| 			paramStr = fmt.Sprintf("%s=%s", k, url.QueryEscape(v)) | 		paramStr = string(bytesData) | ||||||
| 		} else { | 	} else { | ||||||
| 			paramStr = fmt.Sprintf("%s&%s=%s", paramStr, k, url.QueryEscape(v)) | 		for k, v := range params { | ||||||
|  | 			if len(paramStr) == 0 { | ||||||
|  | 				paramStr = fmt.Sprintf("%s=%s", k, url.QueryEscape(v)) | ||||||
|  | 			} else { | ||||||
|  | 				paramStr = fmt.Sprintf("%s&%s=%s", paramStr, k, url.QueryEscape(v)) | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
| 	client := &http.Client{} | 	client := &http.Client{} | ||||||
| 	req, err := http.NewRequest(strings.ToUpper(method), reqUrl, strings.NewReader(paramStr)) | 	req, err := http.NewRequest(strings.ToUpper(method), reqUrl, strings.NewReader(paramStr)) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
|  |  | ||||||
|  | @ -3,12 +3,15 @@ package utils | ||||||
| import ( | import ( | ||||||
| 	"bytes" | 	"bytes" | ||||||
| 	"encoding/base64" | 	"encoding/base64" | ||||||
|  | 	"fmt" | ||||||
| 	"golang.org/x/image/bmp" | 	"golang.org/x/image/bmp" | ||||||
| 	"golang.org/x/image/tiff" | 	"golang.org/x/image/tiff" | ||||||
| 	"image" | 	"image" | ||||||
| 	"image/color" | 	"image/color" | ||||||
|  | 	"image/draw" | ||||||
| 	"image/jpeg" | 	"image/jpeg" | ||||||
| 	"image/png" | 	"image/png" | ||||||
|  | 	"math" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func BuffToImage(in []byte) image.Image { | func BuffToImage(in []byte) image.Image { | ||||||
|  | @ -18,10 +21,12 @@ func BuffToImage(in []byte) image.Image { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Clip 图片裁剪
 | // Clip 图片裁剪
 | ||||||
| func Clip(in []byte, wi, hi int, equalProportion bool) (out image.Image, imageType string, err error) { | func Clip(buff *bytes.Buffer, wi, hi int, equalProportion bool) (out image.Image, imageType string, err error) { | ||||||
| 	buff := bytes.NewBuffer(in) | 	//buff := bytes.NewBuffer(in)
 | ||||||
| 	m, imgType, _ := image.Decode(buff) | 	m, imgType, err := image.Decode(buff) | ||||||
| 	rgbImg := m.(*image.YCbCr) | 	if err != nil { | ||||||
|  | 		return nil, "", err | ||||||
|  | 	} | ||||||
| 	if equalProportion { | 	if equalProportion { | ||||||
| 		w := m.Bounds().Max.X | 		w := m.Bounds().Max.X | ||||||
| 		h := m.Bounds().Max.Y | 		h := m.Bounds().Max.Y | ||||||
|  | @ -29,7 +34,35 @@ func Clip(in []byte, wi, hi int, equalProportion bool) (out image.Image, imageTy | ||||||
| 			wi, hi = fixSize(w, h, wi, hi) | 			wi, hi = fixSize(w, h, wi, hi) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	return rgbImg.SubImage(image.Rect(0, 0, wi, hi)), imgType, nil | 	switch imgType { | ||||||
|  | 	case "jpeg", "jpg": | ||||||
|  | 		rgbImg := m.(*image.YCbCr) | ||||||
|  | 		return rgbImg.SubImage(image.Rect(0, 0, wi, hi)), imgType, nil | ||||||
|  | 	case "bmp": | ||||||
|  | 		img := m.(*image.RGBA) | ||||||
|  | 		if equalProportion { | ||||||
|  | 
 | ||||||
|  | 		} | ||||||
|  | 		return img.SubImage(image.Rect(0, 0, wi, hi)).(*image.RGBA), imageType, nil | ||||||
|  | 	case "png": | ||||||
|  | 		switch m.(type) { | ||||||
|  | 		case *image.NRGBA: | ||||||
|  | 			img := m.(*image.NRGBA) | ||||||
|  | 			subImg := img.SubImage(image.Rect(0, 0, wi, hi)).(*image.NRGBA) | ||||||
|  | 
 | ||||||
|  | 			return subImg, imageType, nil | ||||||
|  | 		case *image.RGBA: | ||||||
|  | 			img := m.(*image.RGBA) | ||||||
|  | 			subImg := img.SubImage(image.Rect(0, 0, wi, hi)).(*image.RGBA) | ||||||
|  | 			return subImg, imageType, nil | ||||||
|  | 		} | ||||||
|  | 	case "gif": | ||||||
|  | 		img := m.(*image.Paletted) | ||||||
|  | 		subImg := img.SubImage(image.Rect(0, 0, wi, hi)).(*image.Paletted) | ||||||
|  | 		return subImg, imageType, nil | ||||||
|  | 	} | ||||||
|  | 	return nil, "", fmt.Errorf("未知的图片格式") | ||||||
|  | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func fixSize(img1W, img2H, wi, hi int) (new1W, new2W int) { | func fixSize(img1W, img2H, wi, hi int) (new1W, new2W int) { | ||||||
|  | @ -45,8 +78,8 @@ func fixSize(img1W, img2H, wi, hi int) (new1W, new2W int) { | ||||||
| 	return int(imgWidth * ratio), int(imgHeight * ratio) | 	return int(imgWidth * ratio), int(imgHeight * ratio) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func Gray(in []byte) (out image.Image, err error) { | func Gray(buff *bytes.Buffer) (out image.Image, err error) { | ||||||
| 	m := BuffToImage(in) | 	m, _, _ := image.Decode(buff) | ||||||
| 	bounds := m.Bounds() | 	bounds := m.Bounds() | ||||||
| 	dx := bounds.Dx() | 	dx := bounds.Dx() | ||||||
| 	dy := bounds.Dy() | 	dy := bounds.Dy() | ||||||
|  | @ -64,8 +97,8 @@ func Gray(in []byte) (out image.Image, err error) { | ||||||
| 	return newRgba.SubImage(r), nil | 	return newRgba.SubImage(r), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func Rotate90(in []byte) image.Image { | func Rotate90(buff *bytes.Buffer) image.Image { | ||||||
| 	m := BuffToImage(in) | 	m, _, _ := image.Decode(buff) | ||||||
| 	rotate90 := image.NewRGBA(image.Rect(0, 0, m.Bounds().Dy(), m.Bounds().Dx())) | 	rotate90 := image.NewRGBA(image.Rect(0, 0, m.Bounds().Dy(), m.Bounds().Dx())) | ||||||
| 	// 矩阵旋转
 | 	// 矩阵旋转
 | ||||||
| 	for x := m.Bounds().Min.Y; x < m.Bounds().Max.Y; x++ { | 	for x := m.Bounds().Min.Y; x < m.Bounds().Max.Y; x++ { | ||||||
|  | @ -78,8 +111,8 @@ func Rotate90(in []byte) image.Image { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Rotate180 旋转180度
 | // Rotate180 旋转180度
 | ||||||
| func Rotate180(in []byte) image.Image { | func Rotate180(buff *bytes.Buffer) image.Image { | ||||||
| 	m := BuffToImage(in) | 	m, _, _ := image.Decode(buff) | ||||||
| 	rotate180 := image.NewRGBA(image.Rect(0, 0, m.Bounds().Dx(), m.Bounds().Dy())) | 	rotate180 := image.NewRGBA(image.Rect(0, 0, m.Bounds().Dx(), m.Bounds().Dy())) | ||||||
| 	// 矩阵旋转
 | 	// 矩阵旋转
 | ||||||
| 	for x := m.Bounds().Min.X; x < m.Bounds().Max.X; x++ { | 	for x := m.Bounds().Min.X; x < m.Bounds().Max.X; x++ { | ||||||
|  | @ -92,8 +125,8 @@ func Rotate180(in []byte) image.Image { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Rotate270 旋转270度
 | // Rotate270 旋转270度
 | ||||||
| func Rotate270(in []byte) image.Image { | func Rotate270(buff *bytes.Buffer) image.Image { | ||||||
| 	m := BuffToImage(in) | 	m, _, _ := image.Decode(buff) | ||||||
| 	rotate270 := image.NewRGBA(image.Rect(0, 0, m.Bounds().Dy(), m.Bounds().Dx())) | 	rotate270 := image.NewRGBA(image.Rect(0, 0, m.Bounds().Dy(), m.Bounds().Dx())) | ||||||
| 	// 矩阵旋转
 | 	// 矩阵旋转
 | ||||||
| 	for x := m.Bounds().Min.Y; x < m.Bounds().Max.Y; x++ { | 	for x := m.Bounds().Min.Y; x < m.Bounds().Max.Y; x++ { | ||||||
|  | @ -125,7 +158,57 @@ func ImageToBuff(img image.Image, imgType string) *bytes.Buffer { | ||||||
| 		_ = tiff.Encode(buff, img, nil) | 		_ = tiff.Encode(buff, img, nil) | ||||||
| 	default: | 	default: | ||||||
| 		imgType = "jpeg" | 		imgType = "jpeg" | ||||||
| 		_ = jpeg.Encode(buff, img, nil) | 		_ = jpeg.Encode(buff, img, &jpeg.Options{ | ||||||
|  | 			Quality: 100, | ||||||
|  | 		}) | ||||||
| 	} | 	} | ||||||
| 	return buff | 	return buff | ||||||
| } | } | ||||||
|  | func SplitImage(buff *bytes.Buffer, w, h int) []image.Image { | ||||||
|  | 	img, _, _ := image.Decode(buff) | ||||||
|  | 	list := make([]image.Image, 0) | ||||||
|  | 	newWidth := int(math.Ceil(float64(img.Bounds().Dx()) / float64(w))) | ||||||
|  | 	newHeight := int(math.Ceil(float64(img.Bounds().Dy()) / float64(h))) | ||||||
|  | 	rect := image.Rect(0, 0, newWidth*w, newHeight*h) | ||||||
|  | 	newImage := image.NewRGBA(rect) | ||||||
|  | 	draw.Draw(newImage, img.Bounds(), img, newImage.Bounds().Min, draw.Over) | ||||||
|  | 	sp := splitPattern(newImage, w, h) | ||||||
|  | 	spLen := len(sp) | ||||||
|  | 	var ( | ||||||
|  | 		square image.Rectangle | ||||||
|  | 	) | ||||||
|  | 	for i := 0; i < spLen; i++ { | ||||||
|  | 		square = image.Rect(sp[i][0], sp[i][1], sp[i][2], sp[i][3]) | ||||||
|  | 		imgPart := img.(interface { | ||||||
|  | 			SubImage(r image.Rectangle) image.Image | ||||||
|  | 		}).SubImage(square) | ||||||
|  | 		list = append(list, imgPart) | ||||||
|  | 	} | ||||||
|  | 	return list | ||||||
|  | } | ||||||
|  | func splitPattern(img image.Image, w, h int) [][]int { | ||||||
|  | 	ret := make([][]int, 0) | ||||||
|  | 	vOffSet := width(img) / w | ||||||
|  | 	hOffSet := height(img) / h | ||||||
|  | 	for r := 0; r < hOffSet; r++ { | ||||||
|  | 		for c := 0; c < vOffSet; c++ { | ||||||
|  | 			//行偏移,仅应用在x
 | ||||||
|  | 			x1 := w * c | ||||||
|  | 			y1 := h * r | ||||||
|  | 
 | ||||||
|  | 			x2 := w * (c + 1) | ||||||
|  | 			y2 := (r + 1) * h | ||||||
|  | 			el := []int{x1, y1, x2, y2} | ||||||
|  | 			ret = append(ret, el) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return ret | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func width(i image.Image) int { | ||||||
|  | 	return i.Bounds().Max.X - i.Bounds().Min.X | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func height(i image.Image) int { | ||||||
|  | 	return i.Bounds().Max.Y - i.Bounds().Min.Y | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -1,6 +1,15 @@ | ||||||
| package proto | package proto | ||||||
| 
 | 
 | ||||||
| type FileCapture struct { | type FileCapture struct { | ||||||
|  | 	FileId      int64  `json:"fileId"` | ||||||
|  | 	FileName    string `json:"fileName"` | ||||||
|  | 	File        string `json:"file"` | ||||||
|  | 	DatasetName string `json:"datasetName"` | ||||||
|  | 	CaptureTime int64  `json:"captureTime"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type SingleFileCapture struct { | ||||||
|  | 	FileId      int64  `json:"fileId"` | ||||||
| 	FileName    string `json:"fileName"` | 	FileName    string `json:"fileName"` | ||||||
| 	File        string `json:"file"` | 	File        string `json:"file"` | ||||||
| 	DatasetName string `json:"datasetName"` | 	DatasetName string `json:"datasetName"` | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue