前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊rocketmq-client-go的ACLInterceptor

聊聊rocketmq-client-go的ACLInterceptor

原创
作者头像
code4it
修改2020-07-09 09:59:10
5110
修改2020-07-09 09:59:10
举报
文章被收录于专栏:码匠的流水账码匠的流水账

本文主要研究一下rocketmq-client-go的ACLInterceptor

ACLInterceptor

rocketmq-client-go-v2.0.0/internal/remote/interceptor.go

代码语言:javascript
复制
func ACLInterceptor(credentials primitive.Credentials) primitive.Interceptor {
    return func(ctx context.Context, req, reply interface{}, next primitive.Invoker) error {
        cmd := req.(*RemotingCommand)
        m := make(map[string]string)
        order := make([]string, 1)
        m[accessKey] = credentials.AccessKey
        order[0] = accessKey
        if credentials.SecurityToken != "" {
            m[securityToken] = credentials.SecurityToken
        }
        for k, v := range cmd.ExtFields {
            m[k] = v
            order = append(order, k)
        }
        sort.Slice(order, func(i, j int) bool {
            return strings.Compare(order[i], order[j]) < 0
        })
        content := ""
        for idx := range order {
            content += m[order[idx]]
        }
        buf := make([]byte, len(content)+len(cmd.Body))
        copy(buf, []byte(content))
        copy(buf[len(content):], cmd.Body)
​
        cmd.ExtFields[signature] = calculateSignature(buf, []byte(credentials.SecretKey))
        cmd.ExtFields[accessKey] = credentials.AccessKey
​
        // The SecurityToken value is unnecessary, user can choose this one.
        if credentials.SecurityToken != "" {
            cmd.ExtFields[securityToken] = credentials.SecurityToken
        }
        err := next(ctx, req, reply)
        return err
    }
}
  • ACLInterceptor方法会调用calculateSignature计算签名,然后执行next

calculateSignature

rocketmq-client-go-v2.0.0/internal/remote/interceptor.go

代码语言:javascript
复制
func calculateSignature(data, sk []byte) string {
    mac := hmac.New(func() hash.Hash {
        return sha1.New()
    }, sk)
    mac.Write(data)
    return base64.StdEncoding.EncodeToString(mac.Sum(nil))
}
  • calculateSignature方法通过base64来将mac.Sum的结果编码为string

SetCredentials

rocketmq-client-go-v2.0.0/internal/namesrv.go

代码语言:javascript
复制
func (s *namesrvs) SetCredentials(credentials primitive.Credentials) {
    s.nameSrvClient.RegisterInterceptor(remote.ACLInterceptor(credentials))
}
  • namesrv的SetCredentials方法执行的是s.nameSrvClient.RegisterInterceptor(remote.ACLInterceptor(credentials))

RegisterInterceptor

rocketmq-client-go-v2.0.0/internal/remote/remote_client.go

代码语言:javascript
复制
func (c *remotingClient) RegisterInterceptor(interceptors ...primitive.Interceptor) {
    c.interceptor = primitive.ChainInterceptors(interceptors...)
}
  • RegisterInterceptor方法主要是执行primitive.ChainInterceptors

ChainInterceptors

rocketmq-client-go-v2.0.0/primitive/interceptor.go

代码语言:javascript
复制
func ChainInterceptors(interceptors ...Interceptor) Interceptor {
    if len(interceptors) == 0 {
        return nil
    }
    if len(interceptors) == 1 {
        return interceptors[0]
    }
    return func(ctx context.Context, req, reply interface{}, invoker Invoker) error {
        return interceptors[0](ctx, req, reply, getChainedInterceptor(interceptors, 0, invoker))
    }
}
  • ChainInterceptors方法会执行getChainedInterceptor

getChainedInterceptor

rocketmq-client-go-v2.0.0/primitive/interceptor.go

代码语言:javascript
复制
func getChainedInterceptor(interceptors []Interceptor, cur int, finalInvoker Invoker) Invoker {
    if cur == len(interceptors)-1 {
        return finalInvoker
    }
    return func(ctx context.Context, req, reply interface{}) error {
        return interceptors[cur+1](ctx, req, reply, getChainedInterceptor(interceptors, cur+1, finalInvoker))
    }
}
  • getChainedInterceptor方法递归执行getChainedInterceptor(interceptors, cur+1, finalInvoker)直到cur == len(interceptors)-1

小结

ACLInterceptor方法会调用calculateSignature计算签名,然后执行next;calculateSignature方法通过base64来将mac.Sum的结果编码为string

doc

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ACLInterceptor
  • calculateSignature
  • SetCredentials
  • RegisterInterceptor
  • ChainInterceptors
  • getChainedInterceptor
  • 小结
  • doc
相关产品与服务
消息队列 CMQ 版
消息队列 CMQ 版(TDMQ for CMQ,简称 TDMQ CMQ 版)是一款分布式高可用的消息队列服务,它能够提供可靠的,基于消息的异步通信机制,能够将分布式部署的不同应用(或同一应用的不同组件)中的信息传递,存储在可靠有效的 CMQ 队列中,防止消息丢失。TDMQ CMQ 版支持多进程同时读写,收发互不干扰,无需各应用或组件始终处于运行状态。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档