Skip to content

Commit

Permalink
service discover
Browse files Browse the repository at this point in the history
  • Loading branch information
dchaofei committed Sep 18, 2023
2 parents c697f83 + 8b940b7 commit e1d5ae5
Show file tree
Hide file tree
Showing 12 changed files with 462 additions and 156 deletions.
2 changes: 1 addition & 1 deletion .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ checks:
threshold: 1000
method-complexity: # 函数和方法的逻辑复杂度
config:
threshold: 12
threshold: 14
method-count: # 结构体的方法限制
config:
threshold: 60
Expand Down
68 changes: 68 additions & 0 deletions wechaty-puppet-service/ca.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package puppetservice

import "context"

// TLSInsecureServerCertCommonName Common Name:
// - Server Name Indication (SNI)
// - Case insensitive
// Wechaty Token format: `${SNI}/${UUIDv4}`
const TLSInsecureServerCertCommonName = "insecure"

// TLSCaCert Wechaty Certificate Authority Repo:
/* https://github.com/wechaty/dotenv/tree/main/ca
The SSL_ROOT_CERT is a root certificate generated by and for wechaty community.
Because it's the default root cert for the puppet service,
so all the Polyglot Wechaty SDK should set this cert to be trusted by default.
Update:
- Huan(202108): init, expired in 3650 days (after 2031/07)
*/
const TLSCaCert = `-----BEGIN CERTIFICATE-----
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
-----END CERTIFICATE-----`

type callCredToken struct {
token string
}

func (r callCredToken) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) {
return map[string]string{
"authorization": "Wechaty " + r.token,
}, nil
}

func (r callCredToken) RequireTransportSecurity() bool {
return true
}
2 changes: 2 additions & 0 deletions wechaty-puppet-service/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ var (
WechatyPuppetHostieEndpoint string

// WechatyPuppetServiceToken ...
// Deprecated
WechatyPuppetServiceToken string

// WechatyPuppetServiceEndpoint ...
// Deprecated
WechatyPuppetServiceEndpoint string
)

Expand Down
84 changes: 84 additions & 0 deletions wechaty-puppet-service/envvars.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package puppetservice

import (
"errors"
"os"
)

// ErrTokenNotFound err token not found
var ErrTokenNotFound = errors.New("wechaty-puppet-service: WECHATY_PUPPET_SERVICE_TOKEN not found")

func envServiceToken(token string) (string, error) {
if token != "" {
return token, nil
}

token = os.Getenv("WECHATY_PUPPET_SERVICE_TOKEN")
if token != "" {
return token, nil
}

token = os.Getenv("WECHATY_PUPPET_HOSTIE_ENDPOINT")
if token != "" {
log.Trace("WECHATY_PUPPET_HOSTIE_TOKEN has been deprecated," +
"please use WECHATY_PUPPET_SERVICE_TOKEN instead.")
return token, nil
}

return "", ErrTokenNotFound
}

func envEndpoint(endpoint string) string {
if endpoint != "" {
return endpoint
}

endpoint = os.Getenv("WECHATY_PUPPET_SERVICE_ENDPOINT")
if endpoint != "" {
return endpoint
}

endpoint = os.Getenv("WECHATY_PUPPET_HOSTIE_ENDPOINT")
if endpoint != "" {
log.Println("WECHATY_PUPPET_HOSTIE_ENDPOINT has been deprecated," +
"please use WECHATY_PUPPET_SERVICE_ENDPOINT instead.")
return endpoint
}
return ""
}

func envAuthority(authority string) string {
if authority != "" {
return authority
}

authority = os.Getenv("WECHATY_PUPPET_SERVICE_AUTHORITY")
if authority != "" {
return authority
}

return "api.chatie.io"
}

func envNoTLSInsecureClient(disable bool) bool {
return disable || os.Getenv("WECHATY_PUPPET_SERVICE_NO_TLS_INSECURE_CLIENT") == "true"
}

func envTLSServerName(serverName string) string {
if serverName != "" {
return serverName
}

return os.Getenv("WECHATY_PUPPET_SERVICE_TLS_SERVER_NAME")
}

func envTLSCaCert(caCert string) string {
if caCert != "" {
return caCert
}
caCert = os.Getenv("WECHATY_PUPPET_SERVICE_TLS_CA_CERT")
if caCert != "" {
return caCert
}
return TLSCaCert
}
86 changes: 86 additions & 0 deletions wechaty-puppet-service/grpc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package puppetservice

import (
pbwechaty "github.com/wechaty/go-grpc/wechaty"
"google.golang.org/grpc"
"google.golang.org/grpc/connectivity"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
"time"
)

func (p *PuppetService) startGrpcClient() error {
var err error
var creds credentials.TransportCredentials
var callOptions []grpc.CallOption
if p.disableTLS {
// TODO 目前不支持 tls,不用打印这个提醒
//log.Warn("PuppetService.startGrpcClient TLS: disabled (INSECURE)")
creds = insecure.NewCredentials()
} else {
callOptions = append(callOptions, grpc.PerRPCCredentials(callCredToken{token: p.token}))
creds, err = p.createCred()
if err != nil {
return err
}
}

dialOptions := []grpc.DialOption{
grpc.WithTransportCredentials(creds),
grpc.WithDefaultCallOptions(callOptions...),
grpc.WithResolvers(wechatyResolver()),
}

if p.disableTLS {
// Deprecated: this block will be removed after Dec 21, 2022.
dialOptions = append(dialOptions, grpc.WithAuthority(p.token))
}

conn, err := grpc.Dial(p.endpoint, dialOptions...)
if err != nil {
return err
}
p.grpcConn = conn

go p.autoReconnectGrpcConn()

p.grpcClient = pbwechaty.NewPuppetClient(conn)
return nil
}

func (p *PuppetService) autoReconnectGrpcConn() {
<-p.started
isClose := false
ticker := p.newGrpcReconnectTicket()
defer ticker.Stop()
for {
select {
case <-ticker.C:
connState := p.grpcConn.GetState()
// 重新连接成功
if isClose && connectivity.Ready == connState {
isClose = false
log.Warn("PuppetService.autoReconnectGrpcConn grpc reconnection successful")
if err := p.startGrpcStream(); err != nil {
log.Errorf("PuppetService.autoReconnectGrpcConn startGrpcStream err:%s", err.Error())
}
}

if p.grpcConn.GetState() == connectivity.Idle {
isClose = true
p.grpcConn.Connect()
log.Warn("PuppetService.autoReconnectGrpcConn grpc reconnection...")
}
case <-p.stop:
return
}
}
}

func (p *PuppetService) newGrpcReconnectTicket() *time.Ticker {
interval := 2 * time.Second
if p.opts.GrpcReconnectInterval > 0 {
interval = p.opts.GrpcReconnectInterval
}
return time.NewTicker(interval)
}
23 changes: 23 additions & 0 deletions wechaty-puppet-service/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package puppetservice

import (
wechatypuppet "github.com/wechaty/go-wechaty/wechaty-puppet"
"time"
)

// TLSConfig tls config
type TLSConfig struct {
CaCert string
ServerName string

Disable bool // only for compatible with old clients/servers
}

// Options puppet-service options
type Options struct {
wechatypuppet.Option

GrpcReconnectInterval time.Duration
Authority string
TLS TLSConfig
}
Loading

0 comments on commit e1d5ae5

Please sign in to comment.