對象自定義元數(shù)據(jù)--使用AWS SDK接口添加

之前文章用go http API實現(xiàn)了給ceph對象添加和修改自定義元數(shù)據(jù)。后面思考是否還有其他路徑。

專門查看了aws-sdk-go中的接口(代碼路徑service/s3/api.go)。其中S3客戶端API中提供了一個CopyObject接口,和之前文章s3cmd的addHeader功能Go實現(xiàn) 中描述使用x-amz-copy-source類似,可以完成對象的拷貝任務。特別的一點,在文檔說明中有這樣一段話:

The method is useful when you want to inject custom logic of configuration into the the SDK's request lifecycle. Such as custom headers, or retry logic.

說明該接口可以用來添加定制化的信息。于是,驗證一下這個接口完成添加自定義元數(shù)據(jù)的任務。

1、前提

  • 安裝Ceph RGW服務;
  • 安裝aws-sdk-go。

2、 aws-sdk-go提供的接口

以下接口信息均在 service/s3/api.go中。

2.1 拷貝對象接口 CopyObject

接收輸入結(jié)構(gòu)體CopyObjectInput,輸出CopyObjectOutput結(jié)構(gòu)體和error錯誤。流程也很簡單:
1、調(diào)用CopyObjectRequest函數(shù)創(chuàng)建一個請求。
2、使用aws/request.Request的Send()方法發(fā)送到指定服務,將返回結(jié)果寫到out中。

func (c *S3) CopyObject(input *CopyObjectInput) (*CopyObjectOutput, error) {
        req, out := c.CopyObjectRequest(input)
        return out, req.Send()
}

2.2 創(chuàng)建拷貝對象請求接口 CopyObjectRequest

創(chuàng)建一個request.Request請求。設置request.Operation的結(jié)構(gòu)體,包含請求的方法、路徑、參數(shù)和返回等。

func (c *S3) CopyObjectRequest(input *CopyObjectInput) (req *request.Request, output *CopyObjectOutput) {
        op := &request.Operation{
                Name:       opCopyObject,
                HTTPMethod: "PUT",
                HTTPPath:   "/{Bucket}/{Key+}",
        }

        if input == nil {
                input = &CopyObjectInput{}
        }

        output = &CopyObjectOutput{}
        req = c.newRequest(op, input, output)
        return
}

2.3 輸入結(jié)構(gòu)體 CopyObjectInput

設置拷貝對象輸入?yún)?shù)的結(jié)構(gòu)體。這個結(jié)構(gòu)體比較長,截取了比較重要的幾個屬性。

  • Bucket 目的桶名稱
  • CopySource 源對象的具體路徑
  • Key 目的對象的名稱
  • Metadata Metadata是一個哈希結(jié)構(gòu),存儲鍵值對。在寫添加Key-Value的時候會自動給Key添加x-amz-meta-的前綴。
  • MetadataDirective 值為COPY或REPLACE。表示元數(shù)據(jù)是完全拷貝還是替換方式設置。
type  CopyObjectInput struct {

// Bucket is a required field
Bucket *string `location:"uri" locationName:"Bucket" type:"string" required:"true"`

// CopySource is a required field
CopySource *string `location:"header" locationName:"x-amz-copy-source" type:"string" required:"true"`

// The key of the destination object. Key is a required field
Key *string `location:"uri" locationName:"Key" min:"1" type:"string" required:"true"`

 // A map of metadata to store with the object in S3.
Metadata map[string]*string `location:"headers" locationName:"x-amz-meta-" type:"map"` 

// Specifies whether the metadata is copied from the source object or replaced
 // with metadata provided in the request.
 MetadataDirective *string `location:"header" locationName:"x-amz-metadata-directive" type:"string" enum:"MetadataDirective"`

......
}

SDK封裝了對應結(jié)構(gòu)體的方法,如設置元數(shù)據(jù)的方法SetMetadata。

// SetMetadata sets the Metadata field's value.
func (s *CopyObjectInput) SetMetadata(v map[string]*string) *CopyObjectInput {
        s.Metadata = v
        return s
}

設置元數(shù)據(jù)復制參數(shù)的SetMetadataDirective。

// SetMetadataDirective sets the MetadataDirective field's value.
func (s *CopyObjectInput) SetMetadataDirective(v string) *CopyObjectInput {
        s.MetadataDirective = &v
        return s
}

對應輸出結(jié)構(gòu)體CopyObjectOutput,暫時可以不用不做介紹。

3、測試用例代碼

流程簡單:
1、創(chuàng)建會話;
2、設置請求;
3、調(diào)用接口發(fā)送請求。

3.1 創(chuàng)建會話

s3客戶端的創(chuàng)建需要傳遞一個會話結(jié)構(gòu)體Session。會話的存放了配置信息和處理句柄。

type Session struct {
        Config   *aws.Config
        Handlers request.Handlers
        options Options
}

會話結(jié)構(gòu)體的初始化,需要使用aws.config 結(jié)構(gòu)體(默認會去~/.aws/config讀取相應的配置初始化),具體結(jié)構(gòu)體可查看aws/config.go文件中的定義。

aws.config 設置參數(shù),如訪問點Endpoint、區(qū)域、認證信息等。其中S3ForcePathStyle參數(shù)在本實驗中設置成True。

S3ForcePathStyle *bool 

該參數(shù)要求請求以 http://s3.amazonaws.com/BUCKET/KEY 形式發(fā)送(目前測試環(huán)境用的Ceph是這種方式)。默認S3客戶端使用的形式是http://BUCKET.s3.amazonaws.com/KEY。如果不設置請求會找不到請求去向而報錯。

3.2 創(chuàng)建請求

創(chuàng)建CopyObjectInput請求,并設置自定義元數(shù)據(jù)和MetadataDirective值。

    input := &s3.CopyObjectInput{
        Bucket:         aws.String(bucketName),
        Key:            aws.String(destFile),
        CopySource:     aws.String("/cephgo/file3"),
    }

    cusMeta := make(map[string]*string)
    city := "New York"
    cusMeta["city"] = &city
    input = input.SetMetadata(cusMeta)
    input = input.SetMetadataDirective("REPLACE")

3.3 發(fā)送請求

調(diào)用S3 客戶端API的CopyObject方法發(fā)送請求。

ret, err := svc.CopyObject(input)

3.4 完整測試代碼

附上功能測試的代碼。

package main

import (
    "fmt"
    "github.com/aws/aws-sdk-go/aws/credentials"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
)

const (
    authRegion = "default"
    bucketName = "cephgo"
    endPoint = "http://192.168.99.103:8080"
    accessKey = "654321"
    secretKey = "654321"
    srcFile = "file3"
    destFile = "file3"
)


func main() {
    cred := credentials.NewStaticCredentials(accessKey, secretKey, "")
    
    svc := s3.New(session.New(&aws.Config{
                                Region:             aws.String(authRegion),
                                Endpoint:           aws.String(endPoint),
                                Credentials:        cred,
                                S3ForcePathStyle:   aws.Bool(true),
                                }))
                                
    input := &s3.CopyObjectInput{
        Bucket:         aws.String(bucketName),
        Key:            aws.String(destFile),
        CopySource:     aws.String("/cephgo/file3"),
    }

    cusMeta := make(map[string]*string)
    city := "New York"
    cusMeta["city"] = &city
    input = input.SetMetadata(cusMeta)
    input = input.SetMetadataDirective("REPLACE")

    ret, err := svc.CopyObject(input)
    if err != nil {
        fmt.Println(err.Error())
        return
    }
    fmt.Println(ret.String())
}

結(jié)果

自定義標簽展示。

數(shù)據(jù)標簽.png

寫在最后

  • 仔細研讀aws的go sdk,相比較http API接口,aws提供的接口屏蔽了一些操作,更High Level一些,讓代碼更清晰。
  • aws的接口代碼提供了比較實用的注釋,理解起來容易。
  • 直接使用REPLACE方式會導致元數(shù)據(jù)的丟失,最標準的方式(和文章s3cmd的addHeader功能Go實現(xiàn) 類似):
    1、通過HEAD請求獲得頭部信息;
    2、將結(jié)果HeadObjectOutput復制到CopyObjectInput結(jié)構(gòu)中,并做自定義元數(shù)據(jù)的增加或修改;
    3、發(fā)送CopyObject請求。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容