10 changed files with 1070 additions and 11 deletions
			
			
		- 
					262batch.go
- 
					389batch_test.go
- 
					5cos.go
- 
					2cos_test.go
- 
					138costesting/ci_test.go
- 
					99example/batch/create_job.go
- 
					44example/batch/describe_job.go
- 
					43example/batch/list_jobs.go
- 
					48example/batch/update_priority.go
- 
					49example/batch/update_status.go
| @ -0,0 +1,262 @@ | |||
| package cos | |||
| 
 | |||
| import ( | |||
| 	"context" | |||
| 	"encoding/xml" | |||
| 	"fmt" | |||
| 	"net/http" | |||
| ) | |||
| 
 | |||
| type BatchService service | |||
| 
 | |||
| type BatchRequestHeaders struct { | |||
| 	XCosAppid     int          `header:"x-cos-appid"` | |||
| 	ContentLength string       `header:"Content-Length,omitempty"` | |||
| 	ContentType   string       `header:"Content-Type,omitempty"` | |||
| 	Headers       *http.Header `header:"-"` | |||
| } | |||
| 
 | |||
| // BatchProgressSummary
 | |||
| type BatchProgressSummary struct { | |||
| 	NumberOfTasksFailed    int `xml:"NumberOfTasksFailed"` | |||
| 	NumberOfTasksSucceeded int `xml:"NumberOfTasksSucceeded"` | |||
| 	TotalNumberOfTasks     int `xml:"TotalNumberOfTasks"` | |||
| } | |||
| 
 | |||
| // BatchJobReport
 | |||
| type BatchJobReport struct { | |||
| 	Bucket      string `xml:"Bucket"` | |||
| 	Enabled     string `xml:"Enabled"` | |||
| 	Format      string `xml:"Format"` | |||
| 	Prefix      string `xml:"Prefix,omitempty"` | |||
| 	ReportScope string `xml:"ReportScope"` | |||
| } | |||
| 
 | |||
| // BatchJobOperationCopy
 | |||
| type BatchMetadata struct { | |||
| 	Key   string `xml:"Key"` | |||
| 	Value string `xml:"Value"` | |||
| } | |||
| type BatchNewObjectMetadata struct { | |||
| 	CacheControl       string          `xml:"CacheControl,omitempty"` | |||
| 	ContentDisposition string          `xml:"ContentDisposition,omitempty"` | |||
| 	ContentEncoding    string          `xml:"ContentEncoding,omitempty"` | |||
| 	ContentType        string          `xml:"ContentType,omitempty"` | |||
| 	HttpExpiresDate    string          `xml:"HttpExpiresDate,omitempty"` | |||
| 	SSEAlgorithm       string          `xml:"SSEAlgorithm,omitempty"` | |||
| 	UserMetadata       []BatchMetadata `xml:"UserMetadata>member,omitempty"` | |||
| } | |||
| type BatchGrantee struct { | |||
| 	DisplayName    string `xml:"DisplayName,omitempty"` | |||
| 	Identifier     string `xml:"Identifier"` | |||
| 	TypeIdentifier string `xml:"TypeIdentifier"` | |||
| } | |||
| type BatchCOSGrant struct { | |||
| 	Grantee    *BatchGrantee `xml:"Grantee"` | |||
| 	Permission string        `xml:"Permission"` | |||
| } | |||
| type BatchAccessControlGrants struct { | |||
| 	COSGrants *BatchCOSGrant `xml:"COSGrant,omitempty"` | |||
| } | |||
| type BatchJobOperationCopy struct { | |||
| 	AccessControlGrants       *BatchAccessControlGrants `xml:"AccessControlGrants,omitempty"` | |||
| 	CannedAccessControlList   string                    `xml:"CannedAccessControlList,omitempty"` | |||
| 	MetadataDirective         string                    `xml:"MetadataDirective,omitempty"` | |||
| 	ModifiedSinceConstraint   int64                     `xml:"ModifiedSinceConstraint,omitempty"` | |||
| 	UnModifiedSinceConstraint int64                     `xml:"UnModifiedSinceConstraint,omitempty"` | |||
| 	NewObjectMetadata         *BatchNewObjectMetadata   `xml:"NewObjectMetadata,omitempty"` | |||
| 	StorageClass              string                    `xml:"StorageClass,omitempty"` | |||
| 	TargetResource            string                    `xml:"TargetResource"` | |||
| } | |||
| 
 | |||
| // BatchJobOperation
 | |||
| type BatchJobOperation struct { | |||
| 	PutObjectCopy *BatchJobOperationCopy `xml:"COSPutObjectCopy,omitempty" header:"-"` | |||
| } | |||
| 
 | |||
| // BatchJobManifest
 | |||
| type BatchJobManifestLocation struct { | |||
| 	ETag            string `xml:"ETag" header:"-"` | |||
| 	ObjectArn       string `xml:"ObjectArn" header:"-"` | |||
| 	ObjectVersionId string `xml:"ObjectVersionId,omitempty" header:"-"` | |||
| } | |||
| type BatchJobManifestSpec struct { | |||
| 	Fields []string `xml:"Fields>member,omitempty" header:"-"` | |||
| 	Format string   `xml:"Format" header:"-"` | |||
| } | |||
| type BatchJobManifest struct { | |||
| 	Location *BatchJobManifestLocation `xml:"Location" header:"-"` | |||
| 	Spec     *BatchJobManifestSpec     `xml:"Spec" header:"-"` | |||
| } | |||
| 
 | |||
| type BatchCreateJobOptions struct { | |||
| 	XMLName              xml.Name           `xml:"CreateJobRequest" header:"-"` | |||
| 	ClientRequestToken   string             `xml:"ClientRequestToken" header:"-"` | |||
| 	ConfirmationRequired string             `xml:"ConfirmationRequired,omitempty" header:"-"` | |||
| 	Description          string             `xml:"Description,omitempty" header:"-"` | |||
| 	Manifest             *BatchJobManifest  `xml:"Manifest" header:"-"` | |||
| 	Operation            *BatchJobOperation `xml:"Operation" header:"-"` | |||
| 	Priority             int                `xml:"Priority" header:"-"` | |||
| 	Report               *BatchJobReport    `xml:"Report" header:"-"` | |||
| 	RoleArn              string             `xml:"RoleArn" header:"-"` | |||
| } | |||
| 
 | |||
| type BatchCreateJobResult struct { | |||
| 	XMLName xml.Name `xml:"CreateJobResult"` | |||
| 	JobId   string   `xml:"JobId"` | |||
| } | |||
| 
 | |||
| func processETag(opt *BatchCreateJobOptions) *BatchCreateJobOptions { | |||
| 	if opt != nil && opt.Manifest != nil && opt.Manifest.Location != nil { | |||
| 		opt.Manifest.Location.ETag = "<ETag>" + opt.Manifest.Location.ETag + "</ETag>" | |||
| 	} | |||
| 	return opt | |||
| } | |||
| 
 | |||
| func (s *BatchService) CreateJob(ctx context.Context, opt *BatchCreateJobOptions, headers *BatchRequestHeaders) (*BatchCreateJobResult, *Response, error) { | |||
| 	var res BatchCreateJobResult | |||
| 	sendOpt := sendOptions{ | |||
| 		baseURL:   s.client.BaseURL.BatchURL, | |||
| 		uri:       "/jobs", | |||
| 		method:    http.MethodPost, | |||
| 		optHeader: headers, | |||
| 		body:      opt, | |||
| 		result:    &res, | |||
| 	} | |||
| 
 | |||
| 	resp, err := s.client.send(ctx, &sendOpt) | |||
| 	return &res, resp, err | |||
| } | |||
| 
 | |||
| type BatchJobFailureReasons struct { | |||
| 	FailureCode   string `xml:"FailureCode"` | |||
| 	FailureReason string `xml:"FailureReason"` | |||
| } | |||
| 
 | |||
| type BatchDescribeJob struct { | |||
| 	ConfirmationRequired string                  `xml:"ConfirmationRequired,omitempty"` | |||
| 	CreationTime         string                  `xml:"CreationTime,omitempty"` | |||
| 	Description          string                  `xml:"Description,omitempty"` | |||
| 	FailureReasons       *BatchJobFailureReasons `xml:"FailureReasons>JobFailure,omitempty"` | |||
| 	JobId                string                  `xml:"JobId"` | |||
| 	Manifest             *BatchJobManifest       `xml:"Manifest"` | |||
| 	Operation            *BatchJobOperation      `xml:"Operation"` | |||
| 	Priority             int                     `xml:"Priority"` | |||
| 	ProgressSummary      *BatchProgressSummary   `xml:"ProgressSummary"` | |||
| 	Report               *BatchJobReport         `xml:"Report,omitempty"` | |||
| 	RoleArn              string                  `xml:"RoleArn,omitempty"` | |||
| 	Status               string                  `xml:"Status,omitempty"` | |||
| 	StatusUpdateReason   string                  `xml:"StatusUpdateReason,omitempty"` | |||
| 	SuspendedCause       string                  `xml:"SuspendedCause,omitempty"` | |||
| 	SuspendedDate        string                  `xml:"SuspendedDate,omitempty"` | |||
| 	TerminationDate      string                  `xml:"TerminationDate,omitempty"` | |||
| } | |||
| type BatchDescribeJobResult struct { | |||
| 	XMLName xml.Name          `xml:"DescribeJobResult"` | |||
| 	Job     *BatchDescribeJob `xml:"Job"` | |||
| } | |||
| 
 | |||
| func (s *BatchService) DescribeJob(ctx context.Context, id string, headers *BatchRequestHeaders) (*BatchDescribeJobResult, *Response, error) { | |||
| 	var res BatchDescribeJobResult | |||
| 	u := fmt.Sprintf("/jobs/%s", id) | |||
| 	sendOpt := sendOptions{ | |||
| 		baseURL:   s.client.BaseURL.BatchURL, | |||
| 		uri:       u, | |||
| 		method:    http.MethodGet, | |||
| 		optHeader: headers, | |||
| 		result:    &res, | |||
| 	} | |||
| 	resp, err := s.client.send(ctx, &sendOpt) | |||
| 	return &res, resp, err | |||
| } | |||
| 
 | |||
| type BatchListJobsOptions struct { | |||
| 	JobStatuses string `url:"jobStatuses,omitempty" header:"-"` | |||
| 	MaxResults  int    `url:"maxResults,omitempty" header:"-"` | |||
| 	NextToken   string `url:"nextToken,omitempty" header:"-"` | |||
| } | |||
| 
 | |||
| type BatchListJobsMember struct { | |||
| 	CreationTime    string                `xml:"CreationTime,omitempty"` | |||
| 	Description     string                `xml:"Description,omitempty"` | |||
| 	JobId           string                `xml:"JobId,omitempty"` | |||
| 	Operation       string                `xml:"Operation,omitempty"` | |||
| 	Priority        int                   `xml:"Priority,omitempty"` | |||
| 	ProgressSummary *BatchProgressSummary `xml:"ProgressSummary,omitempty"` | |||
| 	Status          string                `xml:"Status,omitempty"` | |||
| 	TerminationDate string                `xml:"TerminationDate,omitempty"` | |||
| } | |||
| type BatchListJobs struct { | |||
| 	Members []BatchListJobsMember `xml:"member,omitempty"` | |||
| } | |||
| type BatchListJobsResult struct { | |||
| 	XMLName   xml.Name       `xml:"ListJobsResult"` | |||
| 	Jobs      *BatchListJobs `xml:"Jobs"` | |||
| 	NextToken string         `xml:"NextToken,omitempty"` | |||
| } | |||
| 
 | |||
| func (s *BatchService) ListJobs(ctx context.Context, opt *BatchListJobsOptions, headers *BatchRequestHeaders) (*BatchListJobsResult, *Response, error) { | |||
| 	var res BatchListJobsResult | |||
| 	sendOpt := sendOptions{ | |||
| 		baseURL:   s.client.BaseURL.BatchURL, | |||
| 		uri:       "/jobs", | |||
| 		method:    http.MethodGet, | |||
| 		optQuery:  opt, | |||
| 		optHeader: headers, | |||
| 		result:    &res, | |||
| 	} | |||
| 	resp, err := s.client.send(ctx, &sendOpt) | |||
| 	return &res, resp, err | |||
| } | |||
| 
 | |||
| type BatchUpdatePriorityOptions struct { | |||
| 	JobId    string `url:"-" header:"-" xml:"-"` | |||
| 	Priority int    `url:"priority" header:"-" xml:"-"` | |||
| } | |||
| type BatchUpdatePriorityResult struct { | |||
| 	XMLName  xml.Name `xml:"UpdateJobPriorityResult"` | |||
| 	JobId    string   `xml:"JobId,omitempty"` | |||
| 	Priority int      `xml:"Priority,omitempty"` | |||
| } | |||
| 
 | |||
| func (s *BatchService) UpdateJobPriority(ctx context.Context, opt *BatchUpdatePriorityOptions, headers *BatchRequestHeaders) (*BatchUpdatePriorityResult, *Response, error) { | |||
| 	u := fmt.Sprintf("/jobs/%s/priority", opt.JobId) | |||
| 	var res BatchUpdatePriorityResult | |||
| 	sendOpt := sendOptions{ | |||
| 		baseURL:   s.client.BaseURL.BatchURL, | |||
| 		uri:       u, | |||
| 		method:    http.MethodPost, | |||
| 		optQuery:  opt, | |||
| 		optHeader: headers, | |||
| 		result:    &res, | |||
| 	} | |||
| 	resp, err := s.client.send(ctx, &sendOpt) | |||
| 	return &res, resp, err | |||
| } | |||
| 
 | |||
| type BatchUpdateStatusOptions struct { | |||
| 	JobId              string `header:"-" url:"-" xml:"-"` | |||
| 	RequestedJobStatus string `url:"requestedJobStatus" header:"-" xml:"-"` | |||
| 	StatusUpdateReason string `url:"statusUpdateReason,omitempty" header:"-", xml:"-"` | |||
| } | |||
| type BatchUpdateStatusResult struct { | |||
| 	XMLName            xml.Name `xml:"UpdateJobStatusResult"` | |||
| 	JobId              string   `xml:"JobId,omitempty"` | |||
| 	Status             string   `xml:"Status,omitempty"` | |||
| 	StatusUpdateReason string   `xml:"StatusUpdateReason,omitempty"` | |||
| } | |||
| 
 | |||
| func (s *BatchService) UpdateJobStatus(ctx context.Context, opt *BatchUpdateStatusOptions, headers *BatchRequestHeaders) (*BatchUpdateStatusResult, *Response, error) { | |||
| 	u := fmt.Sprintf("/jobs/%s/status", opt.JobId) | |||
| 	var res BatchUpdateStatusResult | |||
| 	sendOpt := sendOptions{ | |||
| 		baseURL:   s.client.BaseURL.BatchURL, | |||
| 		uri:       u, | |||
| 		method:    http.MethodPost, | |||
| 		optQuery:  opt, | |||
| 		optHeader: headers, | |||
| 		result:    &res, | |||
| 	} | |||
| 	resp, err := s.client.send(ctx, &sendOpt) | |||
| 	return &res, resp, err | |||
| } | |||
| @ -0,0 +1,389 @@ | |||
| package cos | |||
| 
 | |||
| import ( | |||
| 	"context" | |||
| 	"encoding/xml" | |||
| 	"fmt" | |||
| 	"net/http" | |||
| 	"reflect" | |||
| 	"testing" | |||
| 
 | |||
|     "github.com/google/uuid" | |||
| ) | |||
| 
 | |||
| func TestBatchService_CreateJob(t *testing.T) { | |||
| 	setup() | |||
| 	defer teardown() | |||
| 	uuid_str := uuid.New().String() | |||
| 	opt := &BatchCreateJobOptions{ | |||
| 		ClientRequestToken: uuid_str, | |||
| 		Description:        "test batch", | |||
| 		Manifest: &BatchJobManifest{ | |||
| 			Location: &BatchJobManifestLocation{ | |||
| 				ETag:      "15150651828fa9cdcb8356b6d1c7638b", | |||
| 				ObjectArn: "qcs::cos:ap-chengdu::sourcebucket-1250000000/manifests/batch-copy-manifest.csv", | |||
| 			}, | |||
| 			Spec: &BatchJobManifestSpec{ | |||
| 				Fields: []string{"Bucket", "Key"}, | |||
| 				Format: "COSBatchOperations_CSV_V1", | |||
| 			}, | |||
| 		}, | |||
| 		Operation: &BatchJobOperation{ | |||
| 			PutObjectCopy: &BatchJobOperationCopy{ | |||
| 				TargetResource: "qcs::cos:ap-chengdu::destinationbucket-1250000000", | |||
| 			}, | |||
| 		}, | |||
| 		Priority: 1, | |||
| 		Report: &BatchJobReport{ | |||
| 			Bucket:      "qcs::cos:ap-chengdu::sourcebucket-1250000000", | |||
| 			Enabled:     "true", | |||
| 			Format:      "Report_CSV_V1", | |||
| 			Prefix:      "job-result", | |||
| 			ReportScope: "AllTasks", | |||
| 		}, | |||
| 		RoleArn: "qcs::cam::uin/100000000001:roleName/COS_Batch_QcsRole", | |||
| 	} | |||
| 
 | |||
| 	mux.HandleFunc("/jobs", func(w http.ResponseWriter, r *http.Request) { | |||
| 		testHeader(t, r, "x-cos-appid", "1250000000") | |||
| 		testMethod(t, r, http.MethodPost) | |||
| 		v := new(BatchCreateJobOptions) | |||
| 		xml.NewDecoder(r.Body).Decode(v) | |||
| 
 | |||
| 		want := opt | |||
| 		want.XMLName = xml.Name{Local: "CreateJobRequest"} | |||
| 		if !reflect.DeepEqual(v, want) { | |||
| 			t.Errorf("Batch.CreateJob request body: %+v, want %+v", v, want) | |||
| 		} | |||
| 		fmt.Fprint(w, `<?xml version='1.0' encoding='utf-8' ?> | |||
| <CreateJobResult> | |||
|     <JobId>53dc6228-c50b-46f7-8ad7-65e7159f1aae</JobId> | |||
| </CreateJobResult>`) | |||
| 	}) | |||
| 
 | |||
| 	headers := &BatchRequestHeaders{ | |||
| 		XCosAppid: 1250000000, | |||
| 	} | |||
| 	ref, _, err := client.Batch.CreateJob(context.Background(), opt, headers) | |||
| 	if err != nil { | |||
| 		t.Fatalf("Batch.CreateJob returned error: %v", err) | |||
| 	} | |||
| 
 | |||
| 	want := &BatchCreateJobResult{ | |||
| 		XMLName: xml.Name{Local: "CreateJobResult"}, | |||
| 		JobId:   "53dc6228-c50b-46f7-8ad7-65e7159f1aae", | |||
| 	} | |||
| 
 | |||
| 	if !reflect.DeepEqual(ref, want) { | |||
| 		t.Errorf("Batch.CreateJob returned %+v, want %+v", ref, want) | |||
| 	} | |||
| 
 | |||
| } | |||
| 
 | |||
| func TestBatchService_DescribeJob(t *testing.T) { | |||
| 	setup() | |||
| 	defer teardown() | |||
| 
 | |||
| 	mux.HandleFunc("/jobs/53dc6228-c50b-46f7-8ad7-65e7159f1aae", func(w http.ResponseWriter, r *http.Request) { | |||
| 		testHeader(t, r, "x-cos-appid", "1250000000") | |||
| 		testMethod(t, r, http.MethodGet) | |||
| 
 | |||
| 		fmt.Fprint(w, `<?xml version='1.0' encoding='utf-8' ?> | |||
| <DescribeJobResult> | |||
|     <Job> | |||
|         <ConfirmationRequired>false</ConfirmationRequired> | |||
|         <CreationTime>2019-12-19T18:00:30Z</CreationTime> | |||
|         <Description>example-job</Description> | |||
|         <FailureReasons> | |||
|             <JobFailure> | |||
|                 <FailureCode/> | |||
|                 <FailureReason/> | |||
|             </JobFailure> | |||
|         </FailureReasons> | |||
|         <JobId>53dc6228-c50b-46f7-8ad7-65e7159f1aae</JobId> | |||
|         <Manifest> | |||
|             <Location> | |||
|                 <ETag>"15150651828fa9cdcb8356b6d1c7638b"</ETag> | |||
|                 <ObjectArn>qcs::cos:ap-chengdu::sourcebucket-1250000000/manifests/batch-copy-manifest.csv</ObjectArn> | |||
|             </Location> | |||
|             <Spec> | |||
|                 <Fields> | |||
|                     <member>Bucket</member> | |||
|                     <member>Key</member> | |||
|                 </Fields> | |||
|                 <Format>COSBatchOperations_CSV_V1</Format> | |||
|             </Spec> | |||
|         </Manifest> | |||
|         <Operation> | |||
|             <COSPutObjectCopy> | |||
|                 <TargetResource>qcs::cos:ap-chengdu::destinationbucket-1250000000</TargetResource> | |||
|             </COSPutObjectCopy> | |||
|         </Operation> | |||
|         <Priority>10</Priority> | |||
|         <ProgressSummary> | |||
|             <NumberOfTasksFailed>0</NumberOfTasksFailed> | |||
|             <NumberOfTasksSucceeded>10</NumberOfTasksSucceeded> | |||
|             <TotalNumberOfTasks>10</TotalNumberOfTasks> | |||
|         </ProgressSummary> | |||
|         <Report> | |||
|             <Bucket>qcs::cos:ap-chengdu::sourcebucket-1250000000</Bucket> | |||
|             <Enabled>true</Enabled> | |||
|             <Format>Report_CSV_V1</Format> | |||
|             <Prefix>job-result</Prefix> | |||
|             <ReportScope>AllTasks</ReportScope> | |||
|         </Report> | |||
|         <RoleArn>qcs::cam::uin/100000000001:roleName/COS_Batch_QcsRole</RoleArn> | |||
|         <Status>Complete</Status> | |||
|         <StatusUpdateReason>Job complete</StatusUpdateReason> | |||
|         <TerminationDate>2019-12-19T18:00:42Z</TerminationDate> | |||
|     </Job> | |||
| </DescribeJobResult>`) | |||
| 	}) | |||
| 
 | |||
| 	headers := &BatchRequestHeaders{ | |||
| 		XCosAppid: 1250000000, | |||
| 	} | |||
| 	ref, _, err := client.Batch.DescribeJob(context.Background(), "53dc6228-c50b-46f7-8ad7-65e7159f1aae", headers) | |||
| 	if err != nil { | |||
| 		t.Fatalf("Batch.DescribeJob returned error: %v", err) | |||
| 	} | |||
| 
 | |||
| 	want := &BatchDescribeJobResult{ | |||
| 		XMLName: xml.Name{Local: "DescribeJobResult"}, | |||
| 		Job: &BatchDescribeJob{ | |||
| 			ConfirmationRequired: "false", | |||
| 			CreationTime:         "2019-12-19T18:00:30Z", | |||
| 			Description:          "example-job", | |||
| 			FailureReasons:       &BatchJobFailureReasons{}, | |||
| 			JobId:                "53dc6228-c50b-46f7-8ad7-65e7159f1aae", | |||
| 			Manifest: &BatchJobManifest{ | |||
| 				Location: &BatchJobManifestLocation{ | |||
| 					ETag:      "\"15150651828fa9cdcb8356b6d1c7638b\"", | |||
| 					ObjectArn: "qcs::cos:ap-chengdu::sourcebucket-1250000000/manifests/batch-copy-manifest.csv", | |||
| 				}, | |||
| 				Spec: &BatchJobManifestSpec{ | |||
| 					Fields: []string{"Bucket", "Key"}, | |||
| 					Format: "COSBatchOperations_CSV_V1", | |||
| 				}, | |||
| 			}, | |||
| 			Operation: &BatchJobOperation{ | |||
| 				PutObjectCopy: &BatchJobOperationCopy{ | |||
| 					TargetResource: "qcs::cos:ap-chengdu::destinationbucket-1250000000", | |||
| 				}, | |||
| 			}, | |||
| 			Priority: 10, | |||
| 			ProgressSummary: &BatchProgressSummary{ | |||
| 				NumberOfTasksFailed:    0, | |||
| 				NumberOfTasksSucceeded: 10, | |||
| 				TotalNumberOfTasks:     10, | |||
| 			}, | |||
| 			Report: &BatchJobReport{ | |||
| 				Bucket:      "qcs::cos:ap-chengdu::sourcebucket-1250000000", | |||
| 				Enabled:     "true", | |||
| 				Format:      "Report_CSV_V1", | |||
| 				Prefix:      "job-result", | |||
| 				ReportScope: "AllTasks", | |||
| 			}, | |||
| 			RoleArn:            "qcs::cam::uin/100000000001:roleName/COS_Batch_QcsRole", | |||
| 			Status:             "Complete", | |||
| 			StatusUpdateReason: "Job complete", | |||
| 			TerminationDate:    "2019-12-19T18:00:42Z", | |||
| 		}, | |||
| 	} | |||
| 
 | |||
| 	if !reflect.DeepEqual(ref, want) { | |||
| 		t.Errorf("Batch.DescribeJob returned %+v, want %+v", ref, want) | |||
| 	} | |||
| 
 | |||
| } | |||
| 
 | |||
| func TestBatchService_ListJobs(t *testing.T) { | |||
| 	setup() | |||
| 	defer teardown() | |||
| 
 | |||
| 	mux.HandleFunc("/jobs", func(w http.ResponseWriter, r *http.Request) { | |||
| 		testHeader(t, r, "x-cos-appid", "1250000000") | |||
| 		testMethod(t, r, http.MethodGet) | |||
| 		vs := values{ | |||
| 			"maxResults": "2", | |||
| 		} | |||
| 		testFormValues(t, r, vs) | |||
| 
 | |||
| 		fmt.Fprint(w, `<?xml version='1.0' encoding='utf-8' ?> | |||
| <ListJobsResult> | |||
|     <Jobs> | |||
|         <member> | |||
|             <CreationTime>2019-12-19T11:05:40Z</CreationTime> | |||
|             <Description>example-job</Description> | |||
|             <JobId>021140d8-67ca-4e89-8089-0de9a1e40943</JobId> | |||
|             <Operation>COSPutObjectCopy</Operation> | |||
|             <Priority>10</Priority> | |||
|             <ProgressSummary> | |||
|                 <NumberOfTasksFailed>0</NumberOfTasksFailed> | |||
|                 <NumberOfTasksSucceeded>10</NumberOfTasksSucceeded> | |||
|                 <TotalNumberOfTasks>10</TotalNumberOfTasks> | |||
|             </ProgressSummary> | |||
|             <Status>Complete</Status> | |||
|             <TerminationDate>2019-12-19T11:05:56Z</TerminationDate> | |||
|         </member> | |||
|         <member> | |||
|             <CreationTime>2019-12-19T11:07:05Z</CreationTime> | |||
|             <Description>example-job</Description> | |||
|             <JobId>066d919e-49b9-429e-b844-e17ea7b16421</JobId> | |||
|             <Operation>COSPutObjectCopy</Operation> | |||
|             <Priority>10</Priority> | |||
|             <ProgressSummary> | |||
|                 <NumberOfTasksFailed>0</NumberOfTasksFailed> | |||
|                 <NumberOfTasksSucceeded>10</NumberOfTasksSucceeded> | |||
|                 <TotalNumberOfTasks>10</TotalNumberOfTasks> | |||
|             </ProgressSummary> | |||
|             <Status>Complete</Status> | |||
|             <TerminationDate>2019-12-19T11:07:21Z</TerminationDate> | |||
|         </member> | |||
|     </Jobs> | |||
|     <NextToken>066d919e-49b9-429e-b844-e17ea7b16421</NextToken> | |||
| </ListJobsResult>`) | |||
| 	}) | |||
| 
 | |||
| 	opt := &BatchListJobsOptions{ | |||
| 		MaxResults: 2, | |||
| 	} | |||
| 	headers := &BatchRequestHeaders{ | |||
| 		XCosAppid: 1250000000, | |||
| 	} | |||
| 
 | |||
| 	ref, _, err := client.Batch.ListJobs(context.Background(), opt, headers) | |||
| 	if err != nil { | |||
| 		t.Fatalf("Batch.DescribeJob returned error: %v", err) | |||
| 	} | |||
| 
 | |||
| 	want := &BatchListJobsResult{ | |||
| 		XMLName: xml.Name{Local: "ListJobsResult"}, | |||
| 		Jobs: &BatchListJobs{ | |||
| 			Members: []BatchListJobsMember{ | |||
| 				{ | |||
| 					CreationTime: "2019-12-19T11:05:40Z", | |||
| 					Description:  "example-job", | |||
| 					JobId:        "021140d8-67ca-4e89-8089-0de9a1e40943", | |||
| 					Operation:    "COSPutObjectCopy", | |||
| 					Priority:     10, | |||
| 					ProgressSummary: &BatchProgressSummary{ | |||
| 						NumberOfTasksFailed:    0, | |||
| 						NumberOfTasksSucceeded: 10, | |||
| 						TotalNumberOfTasks:     10, | |||
| 					}, | |||
| 					Status:          "Complete", | |||
| 					TerminationDate: "2019-12-19T11:05:56Z", | |||
| 				}, | |||
| 				{ | |||
| 					CreationTime: "2019-12-19T11:07:05Z", | |||
| 					Description:  "example-job", | |||
| 					JobId:        "066d919e-49b9-429e-b844-e17ea7b16421", | |||
| 					Operation:    "COSPutObjectCopy", | |||
| 					Priority:     10, | |||
| 					ProgressSummary: &BatchProgressSummary{ | |||
| 						NumberOfTasksFailed:    0, | |||
| 						NumberOfTasksSucceeded: 10, | |||
| 						TotalNumberOfTasks:     10, | |||
| 					}, | |||
| 					Status:          "Complete", | |||
| 					TerminationDate: "2019-12-19T11:07:21Z", | |||
| 				}, | |||
| 			}, | |||
| 		}, | |||
| 		NextToken: "066d919e-49b9-429e-b844-e17ea7b16421", | |||
| 	} | |||
| 	if !reflect.DeepEqual(ref, want) { | |||
| 		t.Errorf("Batch.ListJobs returned %+v, want %+v", ref, want) | |||
| 	} | |||
| } | |||
| 
 | |||
| func TestBatchService_UpdateJobsPriority(t *testing.T) { | |||
| 	setup() | |||
| 	defer teardown() | |||
| 
 | |||
| 	mux.HandleFunc("/jobs/021140d8-67ca-4e89-8089-0de9a1e40943/priority", func(w http.ResponseWriter, r *http.Request) { | |||
| 		testHeader(t, r, "x-cos-appid", "1250000000") | |||
| 		testMethod(t, r, http.MethodPost) | |||
| 		vs := values{ | |||
| 			"priority": "10", | |||
| 		} | |||
| 		testFormValues(t, r, vs) | |||
| 
 | |||
| 		fmt.Fprint(w, `<?xml version='1.0' encoding='utf-8' ?> | |||
| <UpdateJobPriorityResult> | |||
|     <JobId>021140d8-67ca-4e89-8089-0de9a1e40943</JobId> | |||
|     <Priority>10</Priority> | |||
| </UpdateJobPriorityResult>`) | |||
| 	}) | |||
| 
 | |||
| 	opt := &BatchUpdatePriorityOptions{ | |||
| 		JobId:    "021140d8-67ca-4e89-8089-0de9a1e40943", | |||
| 		Priority: 10, | |||
| 	} | |||
| 
 | |||
| 	headers := &BatchRequestHeaders{ | |||
| 		XCosAppid: 1250000000, | |||
| 	} | |||
| 
 | |||
| 	ref, _, err := client.Batch.UpdateJobPriority(context.Background(), opt, headers) | |||
| 	if err != nil { | |||
| 		t.Fatalf("Batch.UpdateJobPriority returned error: %v", err) | |||
| 	} | |||
| 
 | |||
| 	want := &BatchUpdatePriorityResult{ | |||
| 		XMLName:  xml.Name{Local: "UpdateJobPriorityResult"}, | |||
| 		JobId:    "021140d8-67ca-4e89-8089-0de9a1e40943", | |||
| 		Priority: 10, | |||
| 	} | |||
| 	if !reflect.DeepEqual(ref, want) { | |||
| 		t.Errorf("Batch.UpdateJobsPriority returned %+v, want %+v", ref, want) | |||
| 	} | |||
| } | |||
| 
 | |||
| func TestBatchService_UpdateJobsStatus(t *testing.T) { | |||
| 	setup() | |||
| 	defer teardown() | |||
| 
 | |||
| 	mux.HandleFunc("/jobs/021140d8-67ca-4e89-8089-0de9a1e40943/status", func(w http.ResponseWriter, r *http.Request) { | |||
| 		testHeader(t, r, "x-cos-appid", "1250000000") | |||
| 		testMethod(t, r, http.MethodPost) | |||
| 		vs := values{ | |||
| 			"requestedJobStatus": "Ready", | |||
| 			"statusUpdateReason": "to do", | |||
| 		} | |||
| 		testFormValues(t, r, vs) | |||
| 
 | |||
| 		fmt.Fprint(w, `<?xml version='1.0' encoding='utf-8' ?> | |||
| <UpdateJobStatusResult> | |||
|     <JobId>021140d8-67ca-4e89-8089-0de9a1e40943</JobId> | |||
|     <Status>Ready</Status> | |||
|     <StatusUpdateReason>to do</StatusUpdateReason> | |||
| </UpdateJobStatusResult>`) | |||
| 	}) | |||
| 
 | |||
| 	opt := &BatchUpdateStatusOptions{ | |||
| 		JobId:              "021140d8-67ca-4e89-8089-0de9a1e40943", | |||
| 		RequestedJobStatus: "Ready", | |||
| 		StatusUpdateReason: "to do", | |||
| 	} | |||
| 
 | |||
| 	headers := &BatchRequestHeaders{ | |||
| 		XCosAppid: 1250000000, | |||
| 	} | |||
| 
 | |||
| 	ref, _, err := client.Batch.UpdateJobStatus(context.Background(), opt, headers) | |||
| 	if err != nil { | |||
| 		t.Fatalf("Batch.UpdateJobStatus returned error: %v", err) | |||
| 	} | |||
| 
 | |||
| 	want := &BatchUpdateStatusResult{ | |||
| 		XMLName:            xml.Name{Local: "UpdateJobStatusResult"}, | |||
| 		JobId:              "021140d8-67ca-4e89-8089-0de9a1e40943", | |||
| 		Status:             "Ready", | |||
| 		StatusUpdateReason: "to do", | |||
| 	} | |||
| 	if !reflect.DeepEqual(ref, want) { | |||
| 		t.Errorf("Batch.UpdateJobsStatus returned %+v, want %+v", ref, want) | |||
| 	} | |||
| } | |||
| @ -0,0 +1,99 @@ | |||
| package main | |||
| 
 | |||
| import ( | |||
| 	"context" | |||
| 	"net/http" | |||
| 	"net/url" | |||
| 	"os" | |||
| 	"strings" | |||
| 
 | |||
| 	"fmt" | |||
| 	"github.com/tencentyun/cos-go-sdk-v5" | |||
| 	"github.com/tencentyun/cos-go-sdk-v5/debug" | |||
| 	"github.com/google/uuid" | |||
| ) | |||
| 
 | |||
| func main() { | |||
| 	test_batch_bucket := "testcd-1259654469" | |||
| 	target_batch_bucket := "targetcd-1259654469" | |||
| 	appid := 1259654469 | |||
| 	uin := "100010805041" | |||
| 	region := "ap-chengdu" | |||
| 
 | |||
| 	// bucket url:<Bucketname-Appid>.cos.<region>.mycloud.com
 | |||
| 	bucketurl, _ := url.Parse("https://" + test_batch_bucket + ".cos." + region + ".myqcloud.com") | |||
| 	// batch url:<uin>.cos-control.<region>.myqcloud.ccom
 | |||
| 	batchurl, _ := url.Parse("https://" + uin + ".cos-control." + region + ".myqcloud.com") | |||
| 
 | |||
| 	b := &cos.BaseURL{BucketURL: bucketurl, BatchURL: batchurl} | |||
| 	c := cos.NewClient(b, &http.Client{ | |||
| 		Transport: &cos.AuthorizationTransport{ | |||
| 			SecretID:  os.Getenv("COS_SECRETID"), | |||
| 			SecretKey: os.Getenv("COS_SECRETKEY"), | |||
| 			Transport: &debug.DebugRequestTransport{ | |||
| 				RequestHeader:  true, | |||
| 				RequestBody:    true, | |||
| 				ResponseHeader: true, | |||
| 				ResponseBody:   true, | |||
| 			}, | |||
| 		}, | |||
| 	}) | |||
| 
 | |||
| 	// 创建需要复制的文件
 | |||
| 	source_name := "test/1.txt" | |||
| 	sf := strings.NewReader("batch test content") | |||
| 	_, err := c.Object.Put(context.Background(), source_name, sf, nil) | |||
| 	if err != nil { | |||
| 		panic(err) | |||
| 	} | |||
| 
 | |||
| 	// 创建清单文件
 | |||
| 	manifest_name := "test/manifest.csv" | |||
| 	f := strings.NewReader(test_batch_bucket + "," + source_name) | |||
| 	resp, err := c.Object.Put(context.Background(), manifest_name, f, nil) | |||
| 	if err != nil { | |||
| 		panic(err) | |||
| 	} | |||
| 	etag := resp.Header.Get("ETag") | |||
| 
 | |||
| 	uuid_str := uuid.New().String() | |||
| 	opt := &cos.BatchCreateJobOptions{ | |||
| 		ClientRequestToken:   uuid_str, | |||
| 		ConfirmationRequired: "true", | |||
| 		Description:          "test batch", | |||
| 		Manifest: &cos.BatchJobManifest{ | |||
| 			Location: &cos.BatchJobManifestLocation{ | |||
| 				ETag:      etag, | |||
| 				ObjectArn: "qcs::cos:" + region + "::" + test_batch_bucket + "/" + manifest_name, | |||
| 			}, | |||
| 			Spec: &cos.BatchJobManifestSpec{ | |||
| 				Fields: []string{"Bucket", "Key"}, | |||
| 				Format: "COSBatchOperations_CSV_V1", | |||
| 			}, | |||
| 		}, | |||
| 		Operation: &cos.BatchJobOperation{ | |||
| 			PutObjectCopy: &cos.BatchJobOperationCopy{ | |||
| 				TargetResource: "qcs::cos:" + region + "::" + target_batch_bucket, | |||
| 			}, | |||
| 		}, | |||
| 		Priority: 1, | |||
| 		Report: &cos.BatchJobReport{ | |||
| 			Bucket:      "qcs::cos:" + region + "::" + test_batch_bucket, | |||
| 			Enabled:     "true", | |||
| 			Format:      "Report_CSV_V1", | |||
| 			Prefix:      "job-result", | |||
| 			ReportScope: "AllTasks", | |||
| 		}, | |||
| 		RoleArn: "qcs::cam::uin/" + uin + ":roleName/COSBatch_QcsRole", | |||
| 	} | |||
| 	headers := &cos.BatchRequestHeaders{ | |||
| 		XCosAppid: appid, | |||
| 	} | |||
| 
 | |||
| 	res, _, err := c.Batch.CreateJob(context.Background(), opt, headers) | |||
| 	if err != nil { | |||
| 		panic(err) | |||
| 	} | |||
| 	fmt.Println(res) | |||
| 
 | |||
| } | |||
| @ -0,0 +1,44 @@ | |||
| package main | |||
| 
 | |||
| import ( | |||
| 	"context" | |||
| 	"net/http" | |||
| 	"net/url" | |||
| 	"os" | |||
| 
 | |||
| 	"fmt" | |||
| 	"github.com/tencentyun/cos-go-sdk-v5" | |||
| 	"github.com/tencentyun/cos-go-sdk-v5/debug" | |||
| ) | |||
| 
 | |||
| func main() { | |||
| 	uin := "100010805041" | |||
| 	appid := 1259654469 | |||
| 	jobid := "795ad997-5557-4869-9a19-b66ec087d460" | |||
| 	u, _ := url.Parse("https://" + uin + ".cos-control.ap-chengdu.myqcloud.com") | |||
| 	b := &cos.BaseURL{BatchURL: u} | |||
| 	c := cos.NewClient(b, &http.Client{ | |||
| 		Transport: &cos.AuthorizationTransport{ | |||
| 			SecretID:  os.Getenv("COS_SECRETID"), | |||
| 			SecretKey: os.Getenv("COS_SECRETKEY"), | |||
| 			Transport: &debug.DebugRequestTransport{ | |||
| 				RequestHeader:  true, | |||
| 				RequestBody:    true, | |||
| 				ResponseHeader: true, | |||
| 				ResponseBody:   true, | |||
| 			}, | |||
| 		}, | |||
| 	}) | |||
| 
 | |||
| 	headers := &cos.BatchRequestHeaders{ | |||
| 		XCosAppid: appid, | |||
| 	} | |||
| 
 | |||
| 	res, _, err := c.Batch.DescribeJob(context.Background(), jobid, headers) | |||
| 	if err != nil { | |||
| 		panic(err) | |||
| 	} | |||
| 	if res != nil && res.Job != nil { | |||
| 		fmt.Printf("%+v", res.Job) | |||
| 	} | |||
| } | |||
| @ -0,0 +1,43 @@ | |||
| package main | |||
| 
 | |||
| import ( | |||
| 	"context" | |||
| 	"net/http" | |||
| 	"net/url" | |||
| 	"os" | |||
| 
 | |||
| 	"fmt" | |||
| 	"github.com/tencentyun/cos-go-sdk-v5" | |||
| 	"github.com/tencentyun/cos-go-sdk-v5/debug" | |||
| ) | |||
| 
 | |||
| func main() { | |||
| 	uin := "100010805041" | |||
| 	appid := 1259654469 | |||
| 	u, _ := url.Parse("https://" + uin + ".cos-control.ap-chengdu.myqcloud.com") | |||
| 	b := &cos.BaseURL{BatchURL: u} | |||
| 	c := cos.NewClient(b, &http.Client{ | |||
| 		Transport: &cos.AuthorizationTransport{ | |||
| 			SecretID:  os.Getenv("COS_SECRETID"), | |||
| 			SecretKey: os.Getenv("COS_SECRETKEY"), | |||
| 			Transport: &debug.DebugRequestTransport{ | |||
| 				RequestHeader:  true, | |||
| 				RequestBody:    true, | |||
| 				ResponseHeader: true, | |||
| 				ResponseBody:   true, | |||
| 			}, | |||
| 		}, | |||
| 	}) | |||
| 
 | |||
| 	headers := &cos.BatchRequestHeaders{ | |||
| 		XCosAppid: appid, | |||
| 	} | |||
| 
 | |||
| 	res, _, err := c.Batch.ListJobs(context.Background(), nil, headers) | |||
| 	if err != nil { | |||
| 		panic(err) | |||
| 	} | |||
| 	if res != nil && res.Jobs != nil { | |||
| 		fmt.Printf("%+v", res.Jobs) | |||
| 	} | |||
| } | |||
| @ -0,0 +1,48 @@ | |||
| package main | |||
| 
 | |||
| import ( | |||
| 	"context" | |||
| 	"net/http" | |||
| 	"net/url" | |||
| 	"os" | |||
| 
 | |||
| 	"fmt" | |||
| 	"github.com/tencentyun/cos-go-sdk-v5" | |||
| 	"github.com/tencentyun/cos-go-sdk-v5/debug" | |||
| ) | |||
| 
 | |||
| func main() { | |||
| 	uin := "100010805041" | |||
| 	appid := 1259654469 | |||
| 	jobid := "795ad997-5557-4869-9a19-b66ec087d460" | |||
| 	u, _ := url.Parse("https://" + uin + ".cos-control.ap-chengdu.myqcloud.com") | |||
| 	b := &cos.BaseURL{BatchURL: u} | |||
| 	c := cos.NewClient(b, &http.Client{ | |||
| 		Transport: &cos.AuthorizationTransport{ | |||
| 			SecretID:  os.Getenv("COS_SECRETID"), | |||
| 			SecretKey: os.Getenv("COS_SECRETKEY"), | |||
| 			Transport: &debug.DebugRequestTransport{ | |||
| 				RequestHeader:  true, | |||
| 				RequestBody:    true, | |||
| 				ResponseHeader: true, | |||
| 				ResponseBody:   true, | |||
| 			}, | |||
| 		}, | |||
| 	}) | |||
| 
 | |||
| 	opt := &cos.BatchUpdatePriorityOptions{ | |||
| 		JobId:    jobid, | |||
| 		Priority: 3, | |||
| 	} | |||
| 	headers := &cos.BatchRequestHeaders{ | |||
| 		XCosAppid: appid, | |||
| 	} | |||
| 
 | |||
| 	res, _, err := c.Batch.UpdateJobPriority(context.Background(), opt, headers) | |||
| 	if err != nil { | |||
| 		panic(err) | |||
| 	} | |||
| 	if res != nil { | |||
| 		fmt.Printf("%+v", res) | |||
| 	} | |||
| } | |||
| @ -0,0 +1,49 @@ | |||
| package main | |||
| 
 | |||
| import ( | |||
| 	"context" | |||
| 	"net/http" | |||
| 	"net/url" | |||
| 	"os" | |||
| 
 | |||
| 	"fmt" | |||
| 	"github.com/tencentyun/cos-go-sdk-v5" | |||
| 	"github.com/tencentyun/cos-go-sdk-v5/debug" | |||
| ) | |||
| 
 | |||
| func main() { | |||
| 	uin := "100010805041" | |||
| 	appid := 1259654469 | |||
| 	jobid := "289b0ea1-5ac5-453d-8a61-7f452dd4a209" | |||
| 	u, _ := url.Parse("https://" + uin + ".cos-control.ap-chengdu.myqcloud.com") | |||
| 	b := &cos.BaseURL{BatchURL: u} | |||
| 	c := cos.NewClient(b, &http.Client{ | |||
| 		Transport: &cos.AuthorizationTransport{ | |||
| 			SecretID:  os.Getenv("COS_SECRETID"), | |||
| 			SecretKey: os.Getenv("COS_SECRETKEY"), | |||
| 			Transport: &debug.DebugRequestTransport{ | |||
| 				RequestHeader:  true, | |||
| 				RequestBody:    true, | |||
| 				ResponseHeader: true, | |||
| 				ResponseBody:   true, | |||
| 			}, | |||
| 		}, | |||
| 	}) | |||
| 
 | |||
| 	opt := &cos.BatchUpdateStatusOptions{ | |||
| 		JobId:              jobid, | |||
| 		RequestedJobStatus: "Ready", // 允许状态转换见 https://cloud.tencent.com/document/product/436/38604
 | |||
| 		StatusUpdateReason: "to test", | |||
| 	} | |||
| 	headers := &cos.BatchRequestHeaders{ | |||
| 		XCosAppid: appid, | |||
| 	} | |||
| 
 | |||
| 	res, _, err := c.Batch.UpdateJobStatus(context.Background(), opt, headers) | |||
| 	if err != nil { | |||
| 		panic(err) | |||
| 	} | |||
| 	if res != nil { | |||
| 		fmt.Printf("%+v", res) | |||
| 	} | |||
| } | |||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue