Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 140 additions & 0 deletions oss/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ func (client Client) CreateBucket(bucketName string, options ...Option) error {
isStorageSet, valStroage, _ := IsOptionSet(options, storageClass)
isRedundancySet, valRedundancy, _ := IsOptionSet(options, redundancyType)
isObjectHashFuncSet, valHashFunc, _ := IsOptionSet(options, objectHashFunc)
isReservedCapacityInstanceIdSet, valReservedCapacityInstanceId, _ := IsOptionSet(options, reservedCapacityInstanceId)
if isStorageSet {
cbConfig.StorageClass = valStroage.(StorageClassType)
}
Expand All @@ -152,6 +153,10 @@ func (client Client) CreateBucket(bucketName string, options ...Option) error {
cbConfig.ObjectHashFunction = valHashFunc.(ObjecthashFuncType)
}

if isReservedCapacityInstanceIdSet {
cbConfig.ReservedCapacityInstanceId = valReservedCapacityInstanceId.(string)
}

bs, err := xml.Marshal(cbConfig)
if err != nil {
return err
Expand Down Expand Up @@ -2666,6 +2671,141 @@ func (client Client) DescribeRegionsXml(options ...Option) (string, error) {
return out, err
}

// CreateReservedCapacity create the bucket reserved capacity.
// crcConfig the reserved capacity in struct format.
// error it's nil if no error, otherwise it's an error object.
func (client Client) CreateReservedCapacity(crcConfig CreateReservedCapacity, options ...Option) error {
xmlData, err := xml.Marshal(crcConfig)
if err != nil {
return err
}
return client.CreateReservedCapacityXml("", string(xmlData), options...)
}

// CreateReservedCapacityXml create the reserved capacity.
// id the the reserved capacity id.
// xmlData the reserved capacity config in xml format
// error it's nil if no error, otherwise it's an error object.
func (client Client) CreateReservedCapacityXml(id, xmlData string, options ...Option) error {
buffer := new(bytes.Buffer)
buffer.Write([]byte(xmlData))
contentType := http.DetectContentType(buffer.Bytes())
headers := map[string]string{}
headers[HTTPHeaderContentType] = contentType
params := map[string]interface{}{}
params["reservedCapacity"] = nil
if id != "" {
params["x-oss-reserved-capacity-id"] = id
}
resp, err := client.do("PUT", "", params, headers, buffer, options...)
if err != nil {
return err
}
defer resp.Body.Close()
return CheckRespCode(resp.StatusCode, []int{http.StatusOK})
}

// UpdateReservedCapacity create the reserved capacity.
// id the reserved capacity id.
// urcConfig UpdateReservedCapacity
// error it's nil if no error, otherwise it's an error object.
func (client Client) UpdateReservedCapacity(id string, urcConfig UpdateReservedCapacity, options ...Option) error {
xmlData, err := xml.Marshal(urcConfig)
if err != nil {
return err
}
return client.CreateReservedCapacityXml(id, string(xmlData), options...)
}

// GetReservedCapacity get the reserved capacity.
// id the reserved capacity id.
// GetReservedCapacityResult the reserved capacity result in struct format.
// error it's nil if no error, otherwise it's an error object.
func (client Client) GetReservedCapacity(id string, options ...Option) (GetReservedCapacityResult, error) {
var out GetReservedCapacityResult
body, err := client.GetReservedCapacityXml(id, options...)
if err != nil {
return out, err
}
err = xmlUnmarshal(strings.NewReader(body), &out)
return out, err
}

// GetReservedCapacityXml get the reserved capacity.
// id the reserved capacity id.
// string the reserved capacity result in xml format.
// error it's nil if no error, otherwise it's an error object.
func (client Client) GetReservedCapacityXml(id string, options ...Option) (string, error) {
params := map[string]interface{}{}
params["reservedCapacity"] = nil
if id != "" {
params["x-oss-reserved-capacity-id"] = id
}
resp, err := client.do("GET", "", params, nil, nil, options...)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
out := string(body)
return out, err
}

// ListReservedCapacity list the reserved capacity.
// bucketName the bucket name.
// ListReservedCapacityResult list reserved capacity result in struct format.
// error it's nil if no error, otherwise it's an error object.
func (client Client) ListReservedCapacity(options ...Option) (ListReservedCapacityResult, error) {
var out ListReservedCapacityResult
body, err := client.GetReservedCapacityXml("", options...)
if err != nil {
return out, err
}
err = xmlUnmarshal(strings.NewReader(body), &out)
return out, err
}

// ListBucketWithReservedCapacity list the bucket with reserved capacity.
// id the reserved capacity id.
// ListBucketWithReservedCapacityResult list reserved capacity result in struct format.
// error it's nil if no error, otherwise it's an error object.
func (client Client) ListBucketWithReservedCapacity(id string, options ...Option) (ListBucketWithReservedCapacityResult, error) {
var out ListBucketWithReservedCapacityResult
body, err := client.ListBucketWithReservedCapacityXml(id, options...)
if err != nil {
return out, err
}
err = xmlUnmarshal(strings.NewReader(body), &out)
return out, err
}

// ListBucketWithReservedCapacityXml list the bucket with reserved capacity.
// id the reserved capacity id.
// string list reserved capacity result in xml format.
// error it's nil if no error, otherwise it's an error object.
func (client Client) ListBucketWithReservedCapacityXml(id string, options ...Option) (string, error) {
params := map[string]interface{}{}
params["reservedCapacity"] = nil
if id != "" {
params["x-oss-reserved-capacity-id"] = id
}
params["comp"] = "queryBucketList"
resp, err := client.do("GET", "", params, nil, nil, options...)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
out := string(body)
return out, err
}

// LimitUploadSpeed set upload bandwidth limit speed,default is 0,unlimited
// upSpeed KB/s, 0 is unlimited,default is 0
// error it's nil if success, otherwise failure
Expand Down
76 changes: 76 additions & 0 deletions oss/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5881,3 +5881,79 @@ func (s *OssClientSuite) TestBucketResponseHeader(c *C) {
c.Assert(err, IsNil)
client.DeleteBucket(bucketName)
}

// TestReservedCapacity
func (s *OssClientSuite) TestReservedCapacity(c *C) {
var bucketNameTest = bucketNamePrefix + "-rc-" + RandLowStr(6)
client, err := New(endpoint, accessID, accessKey)
c.Assert(err, IsNil)

var ctcConfig CreateReservedCapacity
name := "rc-" + RandLowStr(12)
ctcConfig.Name = name
ctcConfig.ReservedCapacity = 10240
ctcConfig.DataRedundancyType = string(RedundancyLRS)
var respHeader http.Header
err = client.CreateReservedCapacity(ctcConfig, GetResponseHeader(&respHeader))
c.Assert(err, IsNil)
time.Sleep(3 * time.Second)

id := respHeader.Get("X-Oss-Reserved-Capacity-Id")
var urcConfig UpdateReservedCapacity
urcConfig.Status = "Enabled"
urcConfig.ReservedCapacity = 10240
urcConfig.AutoExpansionSize = 100
urcConfig.AutoExpansionMaxSize = 20480
err = client.UpdateReservedCapacity(id, urcConfig)
c.Assert(err, IsNil)
time.Sleep(3 * time.Second)

record, err := client.GetReservedCapacity(id)
c.Assert(err, IsNil)
c.Assert(record.InstanceId, Equals, id)
c.Assert(record.Name, Equals, name)
c.Assert(record.Owner.ID != "", Equals, true)
c.Assert(record.Owner.DisplayName != "", Equals, true)
c.Assert(record.Owner.DisplayName != "", Equals, true)
c.Assert(record.Region != "", Equals, true)
c.Assert(record.Status, Equals, "Enabled")
c.Assert(record.DataRedundancyType, Equals, string(RedundancyLRS))
c.Assert(record.ReservedCapacity, Equals, int64(10240))
c.Assert(record.AutoExpansionSize, Equals, int64(100))
c.Assert(record.AutoExpansionMaxSize, Equals, int64(20480))
c.Assert(record.CreateTime != 0, Equals, true)
c.Assert(record.LastModifyTime != 0, Equals, true)
c.Assert(record.EnableTime != 0, Equals, true)

list, err := client.ListBucketWithReservedCapacity(id)
c.Assert(err, IsNil)
c.Assert(list.InstanceId, Equals, id)
c.Assert(len(list.BucketList), Equals, 0)

rs, err := client.ListReservedCapacity()
c.Assert(err, IsNil)
c.Assert(len(rs.ReservedCapacityRecord) > 0, Equals, true)

err = client.CreateBucket(bucketNameTest, StorageClass(StorageReservedCapacity), ReservedCapacityInstanceId(id), RedundancyType(RedundancyLRS))
c.Assert(err, IsNil)
time.Sleep(3 * time.Second)

list, err = client.ListBucketWithReservedCapacity(id)
c.Assert(err, IsNil)
c.Assert(list.InstanceId, Equals, id)
c.Assert(len(list.BucketList), Equals, 1)

res, err := client.GetBucketInfo(bucketNameTest)
c.Assert(err, IsNil)
c.Assert(res.BucketInfo.ReservedCapacityInstanceId, Equals, id)

stat, err := client.GetBucketStat(bucketNameTest)
c.Assert(err, IsNil)
c.Assert(stat.ReservedCapacityStorage, Equals, int64(0))
c.Assert(stat.ReservedCapacityObjectCount, Equals, int64(0))
c.Assert(stat.DeepColdArchiveStorage, Equals, int64(0))
c.Assert(stat.DeepColdArchiveRealStorage, Equals, int64(0))
c.Assert(stat.DeepColdArchiveObjectCount, Equals, int64(0))

ForceDeleteBucket(client, bucketNameTest, c)
}
2 changes: 1 addition & 1 deletion oss/conn.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ var signKeyList = []string{"acl", "uploads", "location", "cors",
"x-oss-enable-md5", "x-oss-enable-sha1", "x-oss-enable-sha256",
"x-oss-hash-ctx", "x-oss-md5-ctx", "transferAcceleration",
"regionList", "cloudboxes", "x-oss-ac-source-ip", "x-oss-ac-subnet-mask", "x-oss-ac-vpc-id", "x-oss-ac-forward-allow",
"metaQuery", "resourceGroup", "rtc", "x-oss-async-process", "responseHeader",
"metaQuery", "resourceGroup", "rtc", "x-oss-async-process", "responseHeader", "reservedCapacity", "x-oss-reserved-capacity-id", "queryBucketList",
}

// init initializes Conn
Expand Down
3 changes: 3 additions & 0 deletions oss/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ const (

// StorageDeepColdArchive deep cold archive
StorageDeepColdArchive StorageClassType = "DeepColdArchive"

// StorageReservedCapacity reserved capacity
StorageReservedCapacity StorageClassType = "ReservedCapacity"
)

//RedundancyType bucket data Redundancy type
Expand Down
30 changes: 18 additions & 12 deletions oss/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,18 @@ const (
)

const (
deleteObjectsQuiet = "delete-objects-quiet"
routineNum = "x-routine-num"
checkpointConfig = "x-cp-config"
initCRC64 = "init-crc64"
progressListener = "x-progress-listener"
storageClass = "storage-class"
responseHeader = "x-response-header"
redundancyType = "redundancy-type"
objectHashFunc = "object-hash-func"
responseBody = "x-response-body"
contextArg = "x-context-arg"
deleteObjectsQuiet = "delete-objects-quiet"
routineNum = "x-routine-num"
checkpointConfig = "x-cp-config"
initCRC64 = "init-crc64"
progressListener = "x-progress-listener"
storageClass = "storage-class"
responseHeader = "x-response-header"
redundancyType = "redundancy-type"
objectHashFunc = "object-hash-func"
responseBody = "x-response-body"
contextArg = "x-context-arg"
reservedCapacityInstanceId = "reserved-capacity-instance-id"
)

type (
Expand Down Expand Up @@ -449,7 +450,7 @@ func RedundancyType(value DataRedundancyType) Option {
return addArg(redundancyType, value)
}

// RedundancyType bucket data redundancy type
// ObjectHashFunc bucket data object hash func
func ObjectHashFunc(value ObjecthashFuncType) Option {
return addArg(objectHashFunc, value)
}
Expand All @@ -459,6 +460,11 @@ func WithContext(ctx context.Context) Option {
return addArg(contextArg, ctx)
}

// ReservedCapacityInstanceId bucket reserved capacity instance id
func ReservedCapacityInstanceId(value string) Option {
return addArg(reservedCapacityInstanceId, value)
}

// Checkpoint configuration
type cpConfig struct {
IsEnable bool
Expand Down
Loading