Go SDK
更新时间 2025-06-18 17:56:19
最近更新时间: 2025-06-18 17:56:19
您可使用开源CloudEvents Go SDK发布事件。
前提条件
您已下载Goland等Go研发IDE。
在go.mod中加入依赖。
require (
github.com/cloudevents/sdk-go/v2 v2.15.1
github.com/google/uuid v1.1.1
)
// 然后执行更新依赖
go mod tidy
go mod vendor
注:sdk-go可参考使用版本2.15.1。
签名生成工具
示例代码如下:
package main
import (
"bytes"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"hash"
"io"
"sort"
"strings"
)
// Request is used wrap http request
type Request struct {
Protocol *string
Port *int
Method *string
Pathname *string
Domain *string
Headers map[string]*string
Query map[string]*string
}
// NewRequest is used shortly create Request
func NewRequest() (req *Request) {
return &Request{
Headers: map[string]*string{},
Query: map[string]*string{},
}
}
func String(a string) *string {
return &a
}
func StringValue(a *string) string {
if a == nil {
return ""
}
return *a
}
type Sorter struct {
Keys []string
Vals []string
}
func newSorter(m map[string]string) *Sorter {
hs := &Sorter{
Keys: make([]string, 0, len(m)),
Vals: make([]string, 0, len(m)),
}
for k, v := range m {
hs.Keys = append(hs.Keys, k)
hs.Vals = append(hs.Vals, v)
}
return hs
}
// Sort is an additional function for function SignHeader.
func (hs *Sorter) Sort() {
sort.Sort(hs)
}
// Len is an additional function for function SignHeader.
func (hs *Sorter) Len() int {
return len(hs.Vals)
}
// Less is an additional function for function SignHeader.
func (hs *Sorter) Less(i, j int) bool {
return bytes.Compare([]byte(hs.Keys[i]), []byte(hs.Keys[j])) < 0
}
// Swap is an additional function for function SignHeader.
func (hs *Sorter) Swap(i, j int) {
hs.Vals[i], hs.Vals[j] = hs.Vals[j], hs.Vals[i]
hs.Keys[i], hs.Keys[j] = hs.Keys[j], hs.Keys[i]
}
/**
* Get the string to be signed according to request
* @param request which contains signed messages
* @return the signed string
*/
func GetStringToSign(request *Request) (_result *string) {
return String(getStringToSign(request))
}
func getStringToSign(request *Request) string {
resource := StringValue(request.Pathname)
queryParams := request.Query
// sort QueryParams by key
var queryKeys []string
for key := range queryParams {
queryKeys = append(queryKeys, key)
}
sort.Strings(queryKeys)
tmp := ""
for i := 0; i < len(queryKeys); i++ {
queryKey := queryKeys[i]
tmp = tmp + "&" + queryKey + "=" + StringValue(queryParams[queryKey])
}
if tmp != "" {
tmp = strings.TrimLeft(tmp, "&")
resource = resource + "?" + tmp
}
return getSignedStr(request, resource)
}
func getSignedStr(req *Request, canonicalizedResource string) string {
temp := make(map[string]string)
for k, v := range req.Headers {
if strings.HasPrefix(strings.ToLower(k), "x-acs") {
temp[strings.ToLower(k)] = StringValue(v)
}
}
hs := newSorter(temp)
// Sort the temp by the ascending order
hs.Sort()
// Get the canonicalizedOSSHeaders
canonicalizedHeaders := ""
for i := range hs.Keys {
canonicalizedHeaders += hs.Keys[i] + ":" + hs.Vals[i] + "\n"
}
// Give other parameters values
// when sign URL, date is expires
date := StringValue(req.Headers["date"])
contentType := StringValue(req.Headers["content-type"])
contentMd5 := StringValue(req.Headers["content-md5"])
signStr := StringValue(req.Method) + "\n" + contentMd5 + "\n" + contentType + "\n" + date + "\n" + canonicalizedHeaders + canonicalizedResource
return signStr
}
func GetSignature(stringToSign *string, secret *string) (_result *string) {
h := hmac.New(func() hash.Hash { return sha1.New() }, []byte(StringValue(secret)))
io.WriteString(h, StringValue(stringToSign))
signedStr := base64.StdEncoding.EncodeToString(h.Sum(nil))
return String(signedStr)
}
发布事件
示例代码如下:
package main
import (
"context"
cloudevents "github.com/cloudevents/sdk-go/v2"
"github.com/cloudevents/sdk-go/v2/protocol/http"
"github.com/google/uuid"
"log"
"time"
)
func main() {
ak := "xxx"
sk := "xxx"
target := "http://{endpoint}/api/v1/putEvents"
// CloudEvent client
c, err := cloudevents.NewClientHTTP()
if err != nil {
log.Fatalf("failed to create client, %v", err)
}
//事件内容
event := cloudevents.NewEvent()
event.SetID(uuid.New().String())
event.SetSource("ctyun.oss")
event.SetType("oss:create-bucket")
event.SetSubject("ctyun.oss:huadong1:1234567891234:bucketname-xxx")
event.SetExtension("ctyuneventbusname", "mybus")
event.SetExtension("ctyunaccountid", "5d4ce56axxxxxxxx92ac5884")
event.SetExtension("logproject", "111111111111")
event.SetTime(time.Now())
event.SetDataContentType("application/json;charset=utf-8")
_ = event.SetData(cloudevents.ApplicationJSON, map[string]interface{}{
"aaa": 1234,
"bbb": "Hello, World!",
})
request_ := NewRequest()
request_.Method = String("POST")
request_.Pathname = String("/api/v1/putEvents")
request_.Headers = map[string]*string{
"content-type": String("application/json"),
}
stringToSign := GetStringToSign(request_)
token := "ceb:" + ak + ":" + StringValue(GetSignature(stringToSign, String(sk)))
// Set a target.
ctx := cloudevents.ContextWithTarget(context.Background(), target)
header := map[string][]string{"authorization": {token}}
ctx = http.WithCustomHeader(ctx, header)
// Send that Event.
result := c.Send(ctx, event)
log.Printf("result: %v", result)
}