github.com/qiniu/go-sdk/v7@v7.27.0/storage/pfop.go (about) 1 package storage 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 "time" 8 9 "github.com/qiniu/go-sdk/v7/auth" 10 "github.com/qiniu/go-sdk/v7/client" 11 "github.com/qiniu/go-sdk/v7/internal/clientv2" 12 "github.com/qiniu/go-sdk/v7/media/apis" 13 "github.com/qiniu/go-sdk/v7/storagev2/http_client" 14 "github.com/qiniu/go-sdk/v7/storagev2/region" 15 ) 16 17 // OperationManager 提供了数据处理相关的方法 18 type OperationManager struct { 19 Client *client.Client 20 Mac *auth.Credentials 21 Cfg *Config 22 apiClient *apis.Media 23 } 24 25 // NewOperationManager 用来构建一个新的数据处理对象 26 func NewOperationManager(mac *auth.Credentials, cfg *Config) *OperationManager { 27 return NewOperationManagerEx(mac, cfg, nil) 28 } 29 30 // NewOperationManager 用来构建一个新的数据处理对象 31 func NewOperationManagerEx(mac *auth.Credentials, cfg *Config, clt *client.Client) *OperationManager { 32 if cfg == nil { 33 cfg = NewConfig() 34 } 35 if mac == nil { 36 mac = auth.Default() 37 } 38 39 if clt == nil { 40 clt = &client.DefaultClient 41 } 42 43 bucketQuery, _ := region.NewBucketRegionsQuery(getUcEndpoint(cfg.UseHTTPS, nil), ®ion.BucketRegionsQueryOptions{ 44 UseInsecureProtocol: !cfg.UseHTTPS, 45 Client: clt.Client, 46 }) 47 48 opts := http_client.Options{ 49 BasicHTTPClient: clt.Client, 50 BucketQuery: bucketQuery, 51 Credentials: mac, 52 Interceptors: []clientv2.Interceptor{}, 53 UseInsecureProtocol: !cfg.UseHTTPS, 54 } 55 if region := cfg.GetRegion(); region != nil { 56 opts.Regions = region 57 } 58 59 return &OperationManager{ 60 Client: clt, 61 Mac: mac, 62 Cfg: cfg, 63 apiClient: apis.NewMedia(&opts), 64 } 65 } 66 67 // PfopRet 为数据处理请求的回复内容 68 type PfopRet struct { 69 PersistentID string `json:"persistentId,omitempty"` 70 } 71 72 // PrefopRet 为数据处理请求的状态查询回复内容 73 type PrefopRet struct { 74 ID string `json:"id"` 75 Code int `json:"code"` 76 Desc string `json:"desc"` 77 Type int64 `json:"type,omitempty"` 78 InputBucket string `json:"inputBucket,omitempty"` 79 InputKey string `json:"inputKey,omitempty"` 80 Pipeline string `json:"pipeline,omitempty"` 81 TaskFrom string `json:"taskFrom,omitempty"` 82 Reqid string `json:"reqid,omitempty"` 83 CreatedAt time.Time `json:"creationDate,omitempty"` 84 Items []FopResult 85 } 86 87 func (r *PrefopRet) String() string { 88 strData := fmt.Sprintf("Id: %s\r\nCode: %d\r\nDesc: %s\r\n", r.ID, r.Code, r.Desc) 89 if r.InputBucket != "" { 90 strData += fmt.Sprintf("InputBucket: %s\n", r.InputBucket) 91 } 92 if r.InputKey != "" { 93 strData += fmt.Sprintf("InputKey: %s\n", r.InputKey) 94 } 95 if r.Pipeline != "" { 96 strData += fmt.Sprintf("Pipeline: %s\n", r.Pipeline) 97 } 98 if r.TaskFrom != "" { 99 strData += fmt.Sprintf("TaskFrom: %s\n", r.TaskFrom) 100 } 101 if r.Type != 0 { 102 strData += fmt.Sprintf("Type: %d\n", r.Type) 103 } 104 if r.Reqid != "" { 105 strData += fmt.Sprintf("Reqid: %s\n", r.Reqid) 106 } 107 if !r.CreatedAt.IsZero() { 108 strData += fmt.Sprintf("CreatedAt: %s\n", r.CreatedAt) 109 } 110 111 strData = fmt.Sprintln(strData) 112 for _, item := range r.Items { 113 strData += fmt.Sprintf("\tCmd:\t%s\r\n\tCode:\t%d\r\n\tDesc:\t%s\r\n", item.Cmd, item.Code, item.Desc) 114 if item.Error != "" { 115 strData += fmt.Sprintf("\tError:\t%s\r\n", item.Error) 116 strData += fmt.Sprintf("\tErrorIndex:\t%d\r\n", item.ErrorIndex) 117 } else { 118 if item.Hash != "" { 119 strData += fmt.Sprintf("\tHash:\t%s\r\n", item.Hash) 120 } 121 if item.Result != nil { 122 strData += fmt.Sprintf("\tResult:\t%v\r\n", item.Result) 123 } 124 if item.Key != "" { 125 strData += fmt.Sprintf("\tKey:\t%s\r\n", item.Key) 126 } 127 if item.Keys != nil { 128 if len(item.Keys) > 0 { 129 strData += "\tKeys: {\r\n" 130 for _, key := range item.Keys { 131 strData += fmt.Sprintf("\t\t%s\r\n", key) 132 } 133 strData += "\t}\r\n" 134 } 135 } 136 if item.ReturnOld != 0 { 137 strData += fmt.Sprintf("\tReturnOld:\t%d\r\n", item.ReturnOld) 138 } 139 } 140 strData += "\r\n" 141 } 142 return strData 143 } 144 145 type PfopRequest struct { 146 BucketName string // 空间名称 147 ObjectName string // 对象名称 148 Fops string // 数据处理命令列表,以 `;` 分隔,可以指定多个数据处理命令,与 `workflowTemplateID` 二选一 149 NotifyUrl string // 处理结果通知接收 URL 150 Force int64 // 强制执行数据处理,设为 `1`,则可强制执行数据处理并覆盖原结果 151 Type int64 // 任务类型,支持 `0` 表示普通任务,`1` 表示闲时任务 152 Pipeline string // 对列名,仅适用于普通任务 153 WorkflowTemplateID string // 工作流模板 ID 154 } 155 156 // FopResult 云处理操作列表,包含每个云处理操作的状态信息 157 type FopResult struct { 158 Cmd string `json:"cmd"` 159 Code int `json:"code"` 160 Desc string `json:"desc"` 161 Error string `json:"error,omitempty"` 162 ErrorIndex int64 `json:"errorIndex,omitempty"` 163 Hash string `json:"hash,omitempty"` 164 Result interface{} `json:"result,omitempty"` 165 Key string `json:"key,omitempty"` 166 Keys []string `json:"keys,omitempty"` 167 ReturnOld int64 `json:"returnOld,omitempty"` 168 } 169 170 // Pfop 持久化数据处理 171 // 172 // bucket 资源空间 173 // key 源资源名 174 // fops 云处理操作列表, 175 // notifyURL 处理结果通知接收URL 176 // pipeline 多媒体处理队列名称 177 // force 强制执行数据处理 178 func (m *OperationManager) Pfop(bucket, key, fops, pipeline, notifyURL string, 179 force bool, 180 ) (string, error) { 181 var forceNumber int64 182 if force { 183 forceNumber = 1 184 } 185 response, err := m.apiClient.Pfop(context.Background(), &apis.PfopRequest{ 186 BucketName: bucket, 187 ObjectName: key, 188 Fops: fops, 189 NotifyUrl: notifyURL, 190 Force: forceNumber, 191 Pipeline: pipeline, 192 }, m.makeRequestOptions()) 193 if err != nil { 194 return "", err 195 } 196 return response.PersistentId, nil 197 } 198 199 // Pfop 持久化数据处理 v2 200 func (m *OperationManager) PfopV2(ctx context.Context, pfopRequest *PfopRequest) (*PfopRet, error) { 201 response, err := m.apiClient.Pfop(context.Background(), &apis.PfopRequest{ 202 BucketName: pfopRequest.BucketName, 203 ObjectName: pfopRequest.ObjectName, 204 Fops: pfopRequest.Fops, 205 NotifyUrl: pfopRequest.NotifyUrl, 206 Force: pfopRequest.Force, 207 Type: pfopRequest.Type, 208 Pipeline: pfopRequest.Pipeline, 209 WorkflowTemplateId: pfopRequest.WorkflowTemplateID, 210 }, m.makeRequestOptions()) 211 if err != nil { 212 return nil, err 213 } 214 return &PfopRet{PersistentID: response.PersistentId}, nil 215 } 216 217 // Prefop 持久化处理状态查询 218 func (m *OperationManager) Prefop(persistentID string) (PrefopRet, error) { 219 response, err := m.apiClient.Prefop(context.Background(), &apis.PrefopRequest{ 220 PersistentId: persistentID, 221 }, m.makeRequestOptions()) 222 if err != nil { 223 return PrefopRet{}, err 224 } 225 createdAt, err := time.Parse(time.RFC3339, response.CreatedAt) 226 if err != nil { 227 return PrefopRet{}, err 228 } 229 ret := PrefopRet{ 230 ID: response.PersistentId, 231 Code: int(response.Code), 232 Desc: response.Description, 233 Type: response.Type, 234 InputBucket: response.BucketName, 235 InputKey: response.ObjectName, 236 Pipeline: response.Pipeline, 237 TaskFrom: response.TaskFrom, 238 Reqid: response.RequestId, 239 CreatedAt: createdAt, 240 Items: make([]FopResult, 0, len(response.Items)), 241 } 242 for _, item := range response.Items { 243 ret.Items = append(ret.Items, FopResult{ 244 Cmd: item.Command, 245 Code: int(item.Code), 246 Desc: item.Description, 247 Error: item.Error, 248 ErrorIndex: item.ErrorIndex, 249 Hash: item.Hash, 250 Result: item.Result, 251 Key: item.ObjectName, 252 Keys: item.ObjectNames, 253 ReturnOld: item.ReturnOld, 254 }) 255 } 256 return ret, nil 257 } 258 259 // Deprecated 260 func (m *OperationManager) ApiHost(bucket string) (apiHost string, err error) { 261 var zone *Zone 262 if m.Cfg.Zone != nil { 263 zone = m.Cfg.Zone 264 } else { 265 if v, zoneErr := GetZone(m.Mac.AccessKey, bucket); zoneErr != nil { 266 err = zoneErr 267 return 268 } else { 269 zone = v 270 } 271 } 272 273 if zone == nil || len(zone.ApiHost) == 0 { 274 return "", errors.New("can't get region api host with bucket:" + bucket) 275 } 276 277 apiHost = endpoint(m.Cfg.UseHTTPS, zone.ApiHost) 278 return 279 } 280 281 // Deprecated 282 func (m *OperationManager) PrefopApiHost(persistentID string) (apiHost string) { 283 apiHost = "api.qiniu.com" 284 if m.Cfg.Zone != nil { 285 apiHost = m.Cfg.Zone.ApiHost 286 } 287 apiHost = endpoint(m.Cfg.UseHTTPS, apiHost) 288 return 289 } 290 291 func (m *OperationManager) makeRequestOptions() *apis.Options { 292 return &apis.Options{OverwrittenBucketHosts: getUcEndpointProvider(m.Cfg.UseHTTPS, nil)} 293 }