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), &region.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  }