From 5a4ea9723db1fb64c2bff3f4e1bafebb6659e7b9 Mon Sep 17 00:00:00 2001 From: "mingzai.ym" Date: Thu, 26 Oct 2017 10:51:11 +0800 Subject: [PATCH 1/2] add HeadBucket, Set/GetBucketStorageCapacity interfaces --- oss/client.go | 78 ++++++++++++++++++++++++++++++++++++++++++++++ oss/client_test.go | 46 +++++++++++++++++++++++++++ oss/type.go | 10 ++++++ 3 files changed, 134 insertions(+) diff --git a/oss/client.go b/oss/client.go index 9f7dac9d..e2edc6b2 100644 --- a/oss/client.go +++ b/oss/client.go @@ -188,6 +188,25 @@ func (client Client) DeleteBucket(bucketName string) error { return checkRespCode(resp.StatusCode, []int{http.StatusNoContent}) } +// +// HeadBucket 查看Bucket元信息 +// +// bucketName 存储空间名称。 +// +// http.Header Bucket的meta +// error 操作无错误时返回nil,非nil为错误信息 +// +func (client Client) HeadBucket(bucketName string) (http.Header, error) { + params := map[string]interface{}{} + resp, err := client.do("HEAD", bucketName, params, nil, nil) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + return resp.Headers, nil +} + // // GetBucketLocation 查看Bucket所属数据中心位置的信息。 // @@ -675,6 +694,45 @@ func (client Client) GetBucketInfo(bucketName string) (GetBucketInfoResult, erro return out, err } +// +// SetBucketStorageCapacity 设置Bucket容量限额 +// +// bucketName 存储空间名称 +// storageCapacity Bucket限额,以GB为单位 +// +// error 操作无错误为nil,非nil为错误信息 +// +func (client Client) SetBucketStorageCapacity(bucketName string, storageCapacity int64) error { + qxml := bucketQos{StorageCapacity: storageCapacity} + + params := map[string]interface{}{"qos": nil} + resp, err := client.doXml("PUT", bucketName, params, nil, qxml) + if err != nil { + return err + } + defer resp.Body.Close() + + return nil +} + +func (client Client) GetBucketStorageCapacity(bucketName string) (int64, error) { + var out getBucketStorageCapacityResult + + params := map[string]interface{}{"qos": nil} + resp, err := client.do("GET", bucketName, params, nil, nil) + if err != nil { + return -1, err + } + defer resp.Body.Close() + + err = xmlUnmarshal(resp.Body, &out) + if err != nil { + return -1, err + } + + return out.StorageCapacity, nil +} + // // UseCname 设置是否使用CNAME,默认不使用。 // @@ -798,3 +856,23 @@ func (client Client) do(method, bucketName string, params map[string]interface{} return client.Conn.Do(method, bucketName, "", params, headers, data, 0, nil) } + +func (client Client) doXml(method, bucketName string, params map[string]interface{}, + headers map[string]string, xmlInput interface{}) (*Response, error) { + bodyString, err := xml.Marshal(xmlInput) + if err != nil { + return nil, err + } + + buffer := new(bytes.Buffer) + buffer.Write(bodyString) + + if headers == nil { + headers = map[string]string{} + } + + contentType := http.DetectContentType(buffer.Bytes()) + headers[HTTPHeaderContentType] = contentType + + return client.do(method, bucketName, params, headers, buffer) +} diff --git a/oss/client_test.go b/oss/client_test.go index 16d2932e..c9985fac 100644 --- a/oss/client_test.go +++ b/oss/client_test.go @@ -1503,3 +1503,49 @@ func (s *OssClientSuite) getBucket(buckets []BucketProperties, bucket string) (b } return false, BucketProperties{} } + +func (s *OssClientSuite) TestHeadBucket(c *C) { + var bucketNameTest = bucketNamePrefix + "thb" + + client, err := New(endpoint, accessID, accessKey) + c.Assert(err, IsNil) + + err = client.CreateBucket(bucketNameTest) + c.Assert(err, IsNil) + + headers, err := client.HeadBucket(bucketNameTest) + c.Assert(err, IsNil) + + location, err := client.GetBucketLocation(bucketNameTest) + c.Assert(err, IsNil) + + c.Assert(location, Equals, headers.Get("X-Oss-Bucket-Region")) + + err = client.DeleteBucket(bucketNameTest) + c.Assert(err, IsNil) +} + +func (s *OssClientSuite) TestStorageCapacityBucket(c *C) { + var bucketNameTest = bucketNamePrefix + "tscb" + + client, err := New(endpoint, accessID, accessKey) + c.Assert(err, IsNil) + + err = client.CreateBucket(bucketNameTest) + c.Assert(err, IsNil) + + oldCapacity, err := client.GetBucketStorageCapacity(bucketNameTest) + c.Assert(err, IsNil) + c.Assert(oldCapacity, Equals, int64(-1)) + + newCapacity := int64(100) + err = client.SetBucketStorageCapacity(bucketNameTest, newCapacity) + c.Assert(err, IsNil) + + gotCapacity, err := client.GetBucketStorageCapacity(bucketNameTest) + c.Assert(err, IsNil) + c.Assert(gotCapacity, Equals, newCapacity) + + err = client.DeleteBucket(bucketNameTest) + c.Assert(err, IsNil) +} diff --git a/oss/type.go b/oss/type.go index 8df36f7b..5dc0a892 100644 --- a/oss/type.go +++ b/oss/type.go @@ -448,3 +448,13 @@ type createBucketConfiguration struct { XMLName xml.Name `xml:"CreateBucketConfiguration"` StorageClass StorageClassType `xml:"StorageClass,omitempty"` } + +type bucketQos struct { + XMLName xml.Name `xml:"BucketUserQos"` + StorageCapacity int64 `xml:"StorageCapacity"` +} + +type getBucketStorageCapacityResult struct { + XMLName xml.Name `xml:"BucketUserQos"` + StorageCapacity int64 `xml:"StorageCapacity"` +} From adfd0f67ab030795bcbeb447c7054ff99deeb326 Mon Sep 17 00:00:00 2001 From: "mingzai.ym" Date: Thu, 26 Oct 2017 13:36:39 +0800 Subject: [PATCH 2/2] refactory client.go for xml handling --- oss/client.go | 122 ++++++++++++++------------------------------------ 1 file changed, 34 insertions(+), 88 deletions(-) diff --git a/oss/client.go b/oss/client.go index e2edc6b2..9925cb79 100644 --- a/oss/client.go +++ b/oss/client.go @@ -97,23 +97,19 @@ func (client Client) CreateBucket(bucketName string, options ...Option) error { headers := make(map[string]string) handleOptions(headers, options) - buffer := new(bytes.Buffer) + params := map[string]interface{}{} + var err error + var resp *Response isOptSet, val, _ := isOptionSet(options, storageClass) if isOptSet { cbConfig := createBucketConfiguration{StorageClass: val.(StorageClassType)} - bs, err := xml.Marshal(cbConfig) - if err != nil { - return err - } - buffer.Write(bs) - - contentType := http.DetectContentType(buffer.Bytes()) - headers[HTTPHeaderContentType] = contentType + resp, err = client.doXml("PUT", bucketName, params, headers, cbConfig) + } else { + buffer := new(bytes.Buffer) + resp, err = client.do("PUT", bucketName, params, headers, buffer) } - params := map[string]interface{}{} - resp, err := client.do("PUT", bucketName, params, headers, buffer) if err != nil { return err } @@ -290,20 +286,9 @@ func (client Client) GetBucketACL(bucketName string) (GetBucketACLResult, error) // func (client Client) SetBucketLifecycle(bucketName string, rules []LifecycleRule) error { lxml := lifecycleXML{Rules: convLifecycleRule(rules)} - bs, err := xml.Marshal(lxml) - if err != nil { - return err - } - buffer := new(bytes.Buffer) - buffer.Write(bs) - - contentType := http.DetectContentType(buffer.Bytes()) - headers := map[string]string{} - headers[HTTPHeaderContentType] = contentType - params := map[string]interface{}{} - params["lifecycle"] = nil - resp, err := client.do("PUT", bucketName, params, headers, buffer) + params := map[string]interface{}{"lifecycle": nil} + resp, err := client.doXml("PUT", bucketName, params, nil, lxml) if err != nil { return err } @@ -379,20 +364,8 @@ func (client Client) SetBucketReferer(bucketName string, referers []string, allo } } - bs, err := xml.Marshal(rxml) - if err != nil { - return err - } - buffer := new(bytes.Buffer) - buffer.Write(bs) - - contentType := http.DetectContentType(buffer.Bytes()) - headers := map[string]string{} - headers[HTTPHeaderContentType] = contentType - - params := map[string]interface{}{} - params["referer"] = nil - resp, err := client.do("PUT", bucketName, params, headers, buffer) + params := map[string]interface{}{"referer": nil} + resp, err := client.doXml("PUT", bucketName, params, nil, rxml) if err != nil { return err } @@ -437,32 +410,21 @@ func (client Client) GetBucketReferer(bucketName string) (GetBucketRefererResult // func (client Client) SetBucketLogging(bucketName, targetBucket, targetPrefix string, isEnable bool) error { - var err error - var bs []byte - if isEnable { - lxml := LoggingXML{} - lxml.LoggingEnabled.TargetBucket = targetBucket - lxml.LoggingEnabled.TargetPrefix = targetPrefix - bs, err = xml.Marshal(lxml) - } else { - lxml := loggingXMLEmpty{} - bs, err = xml.Marshal(lxml) - } + var lxml interface{} - if err != nil { - return err - } + params := map[string]interface{}{"logging": nil} - buffer := new(bytes.Buffer) - buffer.Write(bs) + if isEnable { + xmlLogging := LoggingXML{} + xmlLogging.LoggingEnabled.TargetBucket = targetBucket + xmlLogging.LoggingEnabled.TargetPrefix = targetPrefix - contentType := http.DetectContentType(buffer.Bytes()) - headers := map[string]string{} - headers[HTTPHeaderContentType] = contentType + lxml = xmlLogging + } else { + lxml = loggingXMLEmpty{} + } - params := map[string]interface{}{} - params["logging"] = nil - resp, err := client.do("PUT", bucketName, params, headers, buffer) + resp, err := client.doXml("PUT", bucketName, params, nil, lxml) if err != nil { return err } @@ -527,20 +489,8 @@ func (client Client) SetBucketWebsite(bucketName, indexDocument, errorDocument s wxml.IndexDocument.Suffix = indexDocument wxml.ErrorDocument.Key = errorDocument - bs, err := xml.Marshal(wxml) - if err != nil { - return err - } - buffer := new(bytes.Buffer) - buffer.Write(bs) - - contentType := http.DetectContentType(buffer.Bytes()) - headers := make(map[string]string) - headers[HTTPHeaderContentType] = contentType - - params := map[string]interface{}{} - params["website"] = nil - resp, err := client.do("PUT", bucketName, params, headers, buffer) + params := map[string]interface{}{"website": nil} + resp, err := client.doXml("PUT", bucketName, params, nil, wxml) if err != nil { return err } @@ -610,20 +560,8 @@ func (client Client) SetBucketCORS(bucketName string, corsRules []CORSRule) erro corsxml.CORSRules = append(corsxml.CORSRules, cr) } - bs, err := xml.Marshal(corsxml) - if err != nil { - return err - } - buffer := new(bytes.Buffer) - buffer.Write(bs) - - contentType := http.DetectContentType(buffer.Bytes()) - headers := map[string]string{} - headers[HTTPHeaderContentType] = contentType - - params := map[string]interface{}{} - params["cors"] = nil - resp, err := client.do("PUT", bucketName, params, headers, buffer) + params := map[string]interface{}{"cors": nil} + resp, err := client.doXml("PUT", bucketName, params, nil, corsxml) if err != nil { return err } @@ -715,6 +653,14 @@ func (client Client) SetBucketStorageCapacity(bucketName string, storageCapacity return nil } +// +// GetBucketStorageCapacity 获取Bucket容量限额 +// +// bucketName 存储空间名 +// +// int64 存储限额,以GB为单位 +// error 操作无错误为 nil,非nil为错误信息 +// func (client Client) GetBucketStorageCapacity(bucketName string) (int64, error) { var out getBucketStorageCapacityResult