Remove Nacos binding (#3118)
Signed-off-by: ItalyPaleAle <43508+ItalyPaleAle@users.noreply.github.com> Co-authored-by: Bernd Verst <github@bernd.dev>
This commit is contained in:
parent
3e79d69cc7
commit
33a5fd20c0
|
|
@ -1,464 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2021 The Dapr Authors
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package nacos
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/nacos-group/nacos-sdk-go/v2/clients"
|
|
||||||
"github.com/nacos-group/nacos-sdk-go/v2/clients/config_client"
|
|
||||||
"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
|
|
||||||
"github.com/nacos-group/nacos-sdk-go/v2/vo"
|
|
||||||
|
|
||||||
"github.com/dapr/components-contrib/bindings"
|
|
||||||
"github.com/dapr/components-contrib/metadata"
|
|
||||||
"github.com/dapr/kit/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
defaultGroup = "DEFAULT_GROUP"
|
|
||||||
defaultTimeout = 10 * time.Second
|
|
||||||
metadataConfigID = "config-id"
|
|
||||||
metadataConfigGroup = "config-group"
|
|
||||||
metadataConfigOnchange = "config-onchange"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Config type.
|
|
||||||
type configParam struct {
|
|
||||||
dataID string
|
|
||||||
group string
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nacos allows reading/writing to a Nacos server.
|
|
||||||
type Nacos struct {
|
|
||||||
settings Settings
|
|
||||||
config configParam
|
|
||||||
watchesLock sync.Mutex
|
|
||||||
watches []configParam
|
|
||||||
servers []constant.ServerConfig
|
|
||||||
logger logger.Logger
|
|
||||||
configClient config_client.IConfigClient //nolint:nosnakecase
|
|
||||||
readHandler func(ctx context.Context, response *bindings.ReadResponse) ([]byte, error)
|
|
||||||
wg sync.WaitGroup
|
|
||||||
closed atomic.Bool
|
|
||||||
closeCh chan struct{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewNacos returns a new Nacos instance.
|
|
||||||
func NewNacos(logger logger.Logger) bindings.OutputBinding {
|
|
||||||
return &Nacos{
|
|
||||||
logger: logger,
|
|
||||||
watchesLock: sync.Mutex{},
|
|
||||||
closeCh: make(chan struct{}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Init implements InputBinding/OutputBinding's Init method.
|
|
||||||
func (n *Nacos) Init(_ context.Context, metadata bindings.Metadata) error {
|
|
||||||
n.settings = Settings{
|
|
||||||
Timeout: defaultTimeout,
|
|
||||||
}
|
|
||||||
err := n.settings.Decode(metadata.Properties)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("nacos config error: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = n.settings.Validate(); err != nil {
|
|
||||||
return fmt.Errorf("nacos config error: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if n.settings.Endpoint != "" {
|
|
||||||
n.logger.Infof("nacos server url: %s", n.settings.Endpoint)
|
|
||||||
} else if n.settings.NameServer != "" {
|
|
||||||
n.logger.Infof("nacos nameserver: %s", n.settings.NameServer)
|
|
||||||
}
|
|
||||||
|
|
||||||
if n.settings.Config != "" {
|
|
||||||
n.config, err = convertConfig(n.settings.Config)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n.watches, err = convertConfigs(n.settings.Watches)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
n.servers, err = convertServers(n.settings.Endpoint)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return n.createConfigClient()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Nacos) createConfigClient() error {
|
|
||||||
logRollingConfig := constant.ClientLogRollingConfig{
|
|
||||||
MaxSize: n.settings.MaxSize,
|
|
||||||
MaxAge: n.settings.MaxAge,
|
|
||||||
}
|
|
||||||
|
|
||||||
nacosConfig := map[string]interface{}{}
|
|
||||||
nacosConfig["clientConfig"] = constant.ClientConfig{ //nolint:exhaustivestruct
|
|
||||||
TimeoutMs: uint64(n.settings.Timeout),
|
|
||||||
NamespaceId: n.settings.NamespaceID,
|
|
||||||
Endpoint: n.settings.NameServer,
|
|
||||||
RegionId: n.settings.RegionID,
|
|
||||||
AccessKey: n.settings.AccessKey,
|
|
||||||
SecretKey: n.settings.SecretKey,
|
|
||||||
OpenKMS: n.settings.AccessKey != "" && n.settings.SecretKey != "",
|
|
||||||
CacheDir: n.settings.CacheDir,
|
|
||||||
UpdateThreadNum: n.settings.UpdateThreadNum,
|
|
||||||
NotLoadCacheAtStart: n.settings.NotLoadCacheAtStart,
|
|
||||||
UpdateCacheWhenEmpty: n.settings.UpdateCacheWhenEmpty,
|
|
||||||
Username: n.settings.Username,
|
|
||||||
Password: n.settings.Password,
|
|
||||||
LogDir: n.settings.LogDir,
|
|
||||||
LogRollingConfig: &logRollingConfig,
|
|
||||||
LogLevel: n.settings.LogLevel,
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(n.servers) > 0 {
|
|
||||||
nacosConfig["serverConfigs"] = n.servers
|
|
||||||
}
|
|
||||||
|
|
||||||
var err error
|
|
||||||
n.configClient, err = clients.CreateConfigClient(nacosConfig)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("nacos config error: create config client failed. %w ", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read implements InputBinding's Read method.
|
|
||||||
func (n *Nacos) Read(ctx context.Context, handler bindings.Handler) error {
|
|
||||||
if n.closed.Load() {
|
|
||||||
return errors.New("binding is closed")
|
|
||||||
}
|
|
||||||
|
|
||||||
n.readHandler = handler
|
|
||||||
|
|
||||||
n.watchesLock.Lock()
|
|
||||||
for _, watch := range n.watches {
|
|
||||||
go n.startListen(ctx, watch)
|
|
||||||
}
|
|
||||||
n.watchesLock.Unlock()
|
|
||||||
|
|
||||||
n.wg.Add(1)
|
|
||||||
go func() {
|
|
||||||
defer n.wg.Done()
|
|
||||||
// Cancel all listeners when the context is done
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
case <-n.closeCh:
|
|
||||||
}
|
|
||||||
n.cancelAllListeners()
|
|
||||||
}()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close implements cancel all listeners, see https://github.com/dapr/components-contrib/issues/779
|
|
||||||
func (n *Nacos) Close() error {
|
|
||||||
if n.closed.CompareAndSwap(false, true) {
|
|
||||||
close(n.closeCh)
|
|
||||||
}
|
|
||||||
|
|
||||||
n.cancelAllListeners()
|
|
||||||
|
|
||||||
n.wg.Wait()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invoke implements OutputBinding's Invoke method.
|
|
||||||
func (n *Nacos) Invoke(ctx context.Context, req *bindings.InvokeRequest) (*bindings.InvokeResponse, error) {
|
|
||||||
switch req.Operation {
|
|
||||||
case bindings.CreateOperation:
|
|
||||||
return n.publish(ctx, req)
|
|
||||||
case bindings.GetOperation:
|
|
||||||
return n.fetch(ctx, req)
|
|
||||||
case bindings.DeleteOperation, bindings.ListOperation:
|
|
||||||
return nil, fmt.Errorf("nacos error: unsupported operation %s", req.Operation)
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("nacos error: unsupported operation %s", req.Operation)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Operations implements OutputBinding's Operations method.
|
|
||||||
func (n *Nacos) Operations() []bindings.OperationKind {
|
|
||||||
return []bindings.OperationKind{bindings.CreateOperation, bindings.GetOperation}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Nacos) startListen(ctx context.Context, config configParam) {
|
|
||||||
n.fetchAndNotify(ctx, config)
|
|
||||||
n.addListener(ctx, config)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Nacos) fetchAndNotify(ctx context.Context, config configParam) {
|
|
||||||
content, err := n.configClient.GetConfig(vo.ConfigParam{
|
|
||||||
DataId: config.dataID,
|
|
||||||
Group: config.group,
|
|
||||||
Content: "",
|
|
||||||
OnChange: nil,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
n.logger.Warnf("failed to receive nacos config %s:%s, error: %v", config.dataID, config.group, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n.notifyApp(ctx, config.group, config.dataID, content)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Nacos) addListener(ctx context.Context, config configParam) {
|
|
||||||
err := n.configClient.ListenConfig(vo.ConfigParam{
|
|
||||||
DataId: config.dataID,
|
|
||||||
Group: config.group,
|
|
||||||
Content: "",
|
|
||||||
OnChange: n.listener(ctx),
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
n.logger.Warnf("failed to add nacos listener for %s:%s, error: %v", config.dataID, config.group, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Nacos) addListenerFoInputBinding(ctx context.Context, config configParam) {
|
|
||||||
if n.addToWatches(config) {
|
|
||||||
n.wg.Add(1)
|
|
||||||
go func() {
|
|
||||||
defer n.wg.Done()
|
|
||||||
n.addListener(ctx, config)
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Nacos) publish(_ context.Context, req *bindings.InvokeRequest) (*bindings.InvokeResponse, error) {
|
|
||||||
nacosConfigParam, err := n.findConfig(req.Metadata)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := n.configClient.PublishConfig(vo.ConfigParam{
|
|
||||||
DataId: nacosConfigParam.dataID,
|
|
||||||
Group: nacosConfigParam.group,
|
|
||||||
Content: string(req.Data),
|
|
||||||
OnChange: nil,
|
|
||||||
}); err != nil {
|
|
||||||
return nil, fmt.Errorf("publish failed. %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Nacos) fetch(ctx context.Context, req *bindings.InvokeRequest) (*bindings.InvokeResponse, error) {
|
|
||||||
nacosConfigParam, err := n.findConfig(req.Metadata)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
rst, err := n.configClient.GetConfig(vo.ConfigParam{
|
|
||||||
DataId: nacosConfigParam.dataID,
|
|
||||||
Group: nacosConfigParam.group,
|
|
||||||
Content: "",
|
|
||||||
OnChange: nil,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("fetch failed. err:%w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if onchange := req.Metadata[metadataConfigOnchange]; strings.EqualFold(onchange, "true") {
|
|
||||||
n.addListenerFoInputBinding(ctx, *nacosConfigParam)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &bindings.InvokeResponse{Data: []byte(rst), Metadata: map[string]string{}}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Nacos) addToWatches(c configParam) bool {
|
|
||||||
n.watchesLock.Lock()
|
|
||||||
defer n.watchesLock.Unlock()
|
|
||||||
if n.watches != nil {
|
|
||||||
for _, watch := range n.watches {
|
|
||||||
if c.dataID == watch.dataID && c.group == watch.group {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n.watches = append(n.watches, c)
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Nacos) findConfig(md map[string]string) (*configParam, error) {
|
|
||||||
nacosConfigParam := n.config
|
|
||||||
if _, ok := md[metadataConfigID]; ok {
|
|
||||||
nacosConfigParam = configParam{
|
|
||||||
dataID: md[metadataConfigID],
|
|
||||||
group: md[metadataConfigGroup],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if nacosConfigParam.dataID == "" {
|
|
||||||
return nil, fmt.Errorf("nacos config error: invalid metadata, no dataID found: %v", md)
|
|
||||||
}
|
|
||||||
if nacosConfigParam.group == "" {
|
|
||||||
nacosConfigParam.group = defaultGroup
|
|
||||||
}
|
|
||||||
|
|
||||||
return &nacosConfigParam, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Nacos) listener(ctx context.Context) func(_, group, dataID, data string) {
|
|
||||||
return func(_, group, dataID, data string) {
|
|
||||||
n.notifyApp(ctx, group, dataID, data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Nacos) cancelAllListeners() {
|
|
||||||
n.watchesLock.Lock()
|
|
||||||
defer n.watchesLock.Unlock()
|
|
||||||
for _, configParam := range n.watches {
|
|
||||||
if err := n.cancelListener(configParam); err != nil {
|
|
||||||
n.logger.Warnf("nacos cancel listener failed err: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Nacos) cancelListener(configParam configParam) error {
|
|
||||||
return n.configClient.CancelListenConfig(vo.ConfigParam{
|
|
||||||
DataId: configParam.dataID,
|
|
||||||
Group: configParam.group,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Nacos) notifyApp(ctx context.Context, group, dataID, content string) {
|
|
||||||
metadata := map[string]string{
|
|
||||||
metadataConfigID: dataID,
|
|
||||||
metadataConfigGroup: group,
|
|
||||||
}
|
|
||||||
var err error
|
|
||||||
if n.readHandler != nil {
|
|
||||||
n.logger.Debugf("binding-nacos read content to app")
|
|
||||||
_, err = n.readHandler(ctx, &bindings.ReadResponse{Data: []byte(content), Metadata: metadata})
|
|
||||||
} else {
|
|
||||||
err = errors.New("nacos error: the InputBinding.Read handler not init")
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
n.logger.Errorf("nacos config %s:%s failed to notify application, error: %v", dataID, group, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertConfig(s string) (configParam, error) {
|
|
||||||
nacosConfigParam := configParam{dataID: "", group: ""}
|
|
||||||
pair := strings.Split(s, ":")
|
|
||||||
nacosConfigParam.dataID = strings.TrimSpace(pair[0])
|
|
||||||
if len(pair) == 2 {
|
|
||||||
nacosConfigParam.group = strings.TrimSpace(pair[1])
|
|
||||||
}
|
|
||||||
if nacosConfigParam.group == "" {
|
|
||||||
nacosConfigParam.group = defaultGroup
|
|
||||||
}
|
|
||||||
if nacosConfigParam.dataID == "" {
|
|
||||||
return nacosConfigParam, fmt.Errorf("nacos config error: invalid config keys, no config-id defined: %s", s)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nacosConfigParam, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertConfigs(ss string) ([]configParam, error) {
|
|
||||||
configs := make([]configParam, 0)
|
|
||||||
if ss == "" {
|
|
||||||
return configs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, s := range strings.Split(ss, ",") {
|
|
||||||
nacosConfigParam, err := convertConfig(s)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
configs = append(configs, nacosConfigParam)
|
|
||||||
}
|
|
||||||
|
|
||||||
return configs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertServers(ss string) ([]constant.ServerConfig, error) {
|
|
||||||
serverConfigs := make([]constant.ServerConfig, 0)
|
|
||||||
if ss == "" {
|
|
||||||
return serverConfigs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
array := strings.Split(ss, ",")
|
|
||||||
for _, s := range array {
|
|
||||||
cfg, err := parseServerURL(s)
|
|
||||||
if err != nil {
|
|
||||||
return serverConfigs, fmt.Errorf("parse url:%s error:%w", s, err)
|
|
||||||
}
|
|
||||||
serverConfigs = append(serverConfigs, *cfg)
|
|
||||||
}
|
|
||||||
|
|
||||||
return serverConfigs, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseServerURL(s string) (*constant.ServerConfig, error) {
|
|
||||||
if !strings.HasPrefix(s, "http://") {
|
|
||||||
s = "http://" + s
|
|
||||||
}
|
|
||||||
u, err := url.Parse(s)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("nacos config error: server url %s error: %w", s, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
port := uint64(80)
|
|
||||||
if u.Scheme == "" {
|
|
||||||
u.Scheme = "http"
|
|
||||||
} else if u.Scheme == "https" {
|
|
||||||
port = uint64(443)
|
|
||||||
}
|
|
||||||
|
|
||||||
if u.Port() != "" {
|
|
||||||
port, err = strconv.ParseUint(u.Port(), 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("nacos config error: server port %s err: %w", u.Port(), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if u.Path == "" || u.Path == "/" {
|
|
||||||
u.Path = "/nacos"
|
|
||||||
}
|
|
||||||
|
|
||||||
return &constant.ServerConfig{
|
|
||||||
ContextPath: u.Path,
|
|
||||||
IpAddr: u.Hostname(),
|
|
||||||
Port: port,
|
|
||||||
Scheme: u.Scheme,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetComponentMetadata returns the metadata of the component.
|
|
||||||
func (n *Nacos) GetComponentMetadata() (metadataInfo metadata.MetadataMap) {
|
|
||||||
metadataStruct := Settings{}
|
|
||||||
metadata.GetMetadataInfoFromStructType(reflect.TypeOf(metadataStruct), &metadataInfo, metadata.BindingType)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
@ -1,90 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2021 The Dapr Authors
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package nacos
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"sync/atomic"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
"github.com/dapr/components-contrib/bindings"
|
|
||||||
"github.com/dapr/components-contrib/metadata"
|
|
||||||
"github.com/dapr/kit/logger"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestInputBindingRead(t *testing.T) { //nolint:paralleltest
|
|
||||||
m := bindings.Metadata{Base: metadata.Base{Name: "test", Properties: nil}}
|
|
||||||
var err error
|
|
||||||
m.Properties, err = getNacosLocalCacheMetadata()
|
|
||||||
require.NoError(t, err)
|
|
||||||
n := NewNacos(logger.NewLogger("test")).(*Nacos)
|
|
||||||
err = n.Init(context.Background(), m)
|
|
||||||
require.NoError(t, err)
|
|
||||||
var count int32
|
|
||||||
ch := make(chan bool, 1)
|
|
||||||
|
|
||||||
handler := func(ctx context.Context, in *bindings.ReadResponse) ([]byte, error) {
|
|
||||||
require.Equal(t, "hello", string(in.Data))
|
|
||||||
atomic.AddInt32(&count, 1)
|
|
||||||
ch <- true
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
err = n.Read(context.Background(), handler)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case <-ch:
|
|
||||||
require.Equal(t, int32(1), atomic.LoadInt32(&count))
|
|
||||||
case <-time.After(time.Second):
|
|
||||||
require.FailNow(t, "read timeout")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func getNacosLocalCacheMetadata() (map[string]string, error) {
|
|
||||||
tmpDir := "/tmp/config"
|
|
||||||
dataID := "test"
|
|
||||||
group := "DEFAULT_GROUP"
|
|
||||||
|
|
||||||
if err := os.MkdirAll(tmpDir, os.ModePerm); err != nil {
|
|
||||||
return nil, fmt.Errorf("create dir failed. %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cfgFile := path.Join(tmpDir, fmt.Sprintf("%s@@%s@@", dataID, group))
|
|
||||||
file, err := os.OpenFile(cfgFile, os.O_RDWR|os.O_CREATE, os.ModePerm) //nolint:nosnakecase
|
|
||||||
if err != nil || file == nil {
|
|
||||||
return nil, fmt.Errorf("open %s failed. %w", cfgFile, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
_ = file.Close()
|
|
||||||
}()
|
|
||||||
|
|
||||||
if _, err = file.WriteString("hello"); err != nil {
|
|
||||||
return nil, fmt.Errorf("write file failed. %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return map[string]string{
|
|
||||||
"cacheDir": "/tmp", // default
|
|
||||||
"nameServer": "localhost:8080/fake",
|
|
||||||
"watches": fmt.Sprintf("%s:%s", dataID, group),
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2021 The Dapr Authors
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Nacos is an easy-to-use dynamic service discovery, configuration and service management platform
|
|
||||||
//
|
|
||||||
// See https://github.com/nacos-group/nacos-sdk-go/
|
|
||||||
|
|
||||||
package nacos
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/dapr/components-contrib/metadata"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Settings struct {
|
|
||||||
NameServer string `mapstructure:"nameServer"`
|
|
||||||
Endpoint string `mapstructure:"endpoint"`
|
|
||||||
RegionID string `mapstructure:"region"`
|
|
||||||
NamespaceID string `mapstructure:"namespace"`
|
|
||||||
AccessKey string `mapstructure:"accessKey"`
|
|
||||||
SecretKey string `mapstructure:"secretKey"`
|
|
||||||
Timeout time.Duration `mapstructure:"timeout"`
|
|
||||||
CacheDir string `mapstructure:"cacheDir"`
|
|
||||||
UpdateThreadNum int `mapstructure:"updateThreadNum"`
|
|
||||||
NotLoadCacheAtStart bool `mapstructure:"notLoadCacheAtStart"`
|
|
||||||
UpdateCacheWhenEmpty bool `mapstructure:"updateCacheWhenEmpty"`
|
|
||||||
Username string `mapstructure:"username"`
|
|
||||||
Password string `mapstructure:"password"`
|
|
||||||
LogDir string `mapstructure:"logDir"`
|
|
||||||
MaxAge int `mapstructure:"maxAge"`
|
|
||||||
MaxSize int `mapstructure:"maxSize"`
|
|
||||||
LogLevel string `mapstructure:"logLevel"`
|
|
||||||
Config string `mapstructure:"config"`
|
|
||||||
Watches string `mapstructure:"watches"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Settings) Decode(in interface{}) error {
|
|
||||||
return metadata.DecodeMetadata(in, s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Settings) Validate() error {
|
|
||||||
if s.Timeout <= 0 {
|
|
||||||
return fmt.Errorf("invalid timeout %s", s.Timeout)
|
|
||||||
}
|
|
||||||
|
|
||||||
if s.Endpoint == "" && s.NameServer == "" {
|
|
||||||
return errors.New("either endpoint or nameserver must be configured")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2021 The Dapr Authors
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package nacos_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
"github.com/dapr/components-contrib/bindings/nacos"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestParseMetadata(t *testing.T) { //nolint:paralleltest
|
|
||||||
props := map[string]string{
|
|
||||||
"endpoint": "a",
|
|
||||||
"region": "b",
|
|
||||||
"namespace": "c",
|
|
||||||
"accessKey": "d",
|
|
||||||
"secretKey": "e",
|
|
||||||
"updateThreadNum": "3",
|
|
||||||
}
|
|
||||||
|
|
||||||
var settings nacos.Settings
|
|
||||||
err := settings.Decode(props)
|
|
||||||
require.NoError(t, err)
|
|
||||||
assert.Equal(t, "a", settings.Endpoint)
|
|
||||||
assert.Equal(t, "b", settings.RegionID)
|
|
||||||
assert.Equal(t, "c", settings.NamespaceID)
|
|
||||||
assert.Equal(t, "d", settings.AccessKey)
|
|
||||||
assert.Equal(t, "e", settings.SecretKey)
|
|
||||||
assert.Equal(t, 3, settings.UpdateThreadNum)
|
|
||||||
}
|
|
||||||
3
go.mod
3
go.mod
|
|
@ -83,7 +83,6 @@ require (
|
||||||
github.com/microsoft/go-mssqldb v1.5.0
|
github.com/microsoft/go-mssqldb v1.5.0
|
||||||
github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4
|
github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4
|
||||||
github.com/mrz1836/postmark v1.6.1
|
github.com/mrz1836/postmark v1.6.1
|
||||||
github.com/nacos-group/nacos-sdk-go/v2 v2.2.3
|
|
||||||
github.com/nats-io/nats-server/v2 v2.9.21
|
github.com/nats-io/nats-server/v2 v2.9.21
|
||||||
github.com/nats-io/nats.go v1.28.0
|
github.com/nats-io/nats.go v1.28.0
|
||||||
github.com/nats-io/nkeys v0.4.4
|
github.com/nats-io/nkeys v0.4.4
|
||||||
|
|
@ -158,7 +157,6 @@ require (
|
||||||
github.com/alibabacloud-go/openapi-util v0.0.11 // indirect
|
github.com/alibabacloud-go/openapi-util v0.0.11 // indirect
|
||||||
github.com/alibabacloud-go/tea-xml v1.1.2 // indirect
|
github.com/alibabacloud-go/tea-xml v1.1.2 // indirect
|
||||||
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect
|
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704 // indirect
|
|
||||||
github.com/aliyun/credentials-go v1.1.2 // indirect
|
github.com/aliyun/credentials-go v1.1.2 // indirect
|
||||||
github.com/aliyunmq/mq-http-go-sdk v1.0.3 // indirect
|
github.com/aliyunmq/mq-http-go-sdk v1.0.3 // indirect
|
||||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||||
|
|
@ -172,7 +170,6 @@ require (
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/bits-and-blooms/bitset v1.4.0 // indirect
|
github.com/bits-and-blooms/bitset v1.4.0 // indirect
|
||||||
github.com/bufbuild/protocompile v0.4.0 // indirect
|
github.com/bufbuild/protocompile v0.4.0 // indirect
|
||||||
github.com/buger/jsonparser v1.1.1 // indirect
|
|
||||||
github.com/bytedance/gopkg v0.0.0-20220817015305-b879a72dc90f // indirect
|
github.com/bytedance/gopkg v0.0.0-20220817015305-b879a72dc90f // indirect
|
||||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
|
|
|
||||||
4
go.sum
4
go.sum
|
|
@ -540,7 +540,6 @@ github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGn
|
||||||
github.com/alicebob/miniredis/v2 v2.30.5 h1:3r6kTHdKnuP4fkS8k2IrvSfxpxUTcW1SOL0wN7b7Dt0=
|
github.com/alicebob/miniredis/v2 v2.30.5 h1:3r6kTHdKnuP4fkS8k2IrvSfxpxUTcW1SOL0wN7b7Dt0=
|
||||||
github.com/alicebob/miniredis/v2 v2.30.5/go.mod h1:b25qWj4fCEsBeAAR2mlb0ufImGC6uH3VlUfb/HS5zKg=
|
github.com/alicebob/miniredis/v2 v2.30.5/go.mod h1:b25qWj4fCEsBeAAR2mlb0ufImGC6uH3VlUfb/HS5zKg=
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk=
|
github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk=
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704 h1:PpfENOj/vPfhhy9N2OFRjpue0hjM5XqAp2thFmkXXIk=
|
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU=
|
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU=
|
||||||
github.com/aliyun/aliyun-log-go-sdk v0.1.54 h1:ejQygZTGBqTs4V9qQUunWYtFwyKUWXYryfgrX9OhOlg=
|
github.com/aliyun/aliyun-log-go-sdk v0.1.54 h1:ejQygZTGBqTs4V9qQUunWYtFwyKUWXYryfgrX9OhOlg=
|
||||||
github.com/aliyun/aliyun-log-go-sdk v0.1.54/go.mod h1:/U0mxwX7uG2K2fbfsF92BR64zmbmJyx7WQtyKaCdRL8=
|
github.com/aliyun/aliyun-log-go-sdk v0.1.54/go.mod h1:/U0mxwX7uG2K2fbfsF92BR64zmbmJyx7WQtyKaCdRL8=
|
||||||
|
|
@ -636,7 +635,6 @@ github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y=
|
||||||
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
|
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
|
||||||
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
|
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
|
||||||
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||||
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
|
||||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||||
github.com/bytecodealliance/wasmtime-go/v3 v3.0.2 h1:3uZCA/BLTIu+DqCfguByNMJa2HVHpXvjfy0Dy7g6fuA=
|
github.com/bytecodealliance/wasmtime-go/v3 v3.0.2 h1:3uZCA/BLTIu+DqCfguByNMJa2HVHpXvjfy0Dy7g6fuA=
|
||||||
github.com/bytedance/gopkg v0.0.0-20210705062217-74c74ebadcae/go.mod h1:birsdqRCbwnckJbdAvcSao+AzOyibVEoWB55MjpYpB8=
|
github.com/bytedance/gopkg v0.0.0-20210705062217-74c74ebadcae/go.mod h1:birsdqRCbwnckJbdAvcSao+AzOyibVEoWB55MjpYpB8=
|
||||||
|
|
@ -1566,8 +1564,6 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW
|
||||||
github.com/nacos-group/nacos-sdk-go v1.0.8/go.mod h1:hlAPn3UdzlxIlSILAyOXKxjFSvDJ9oLzTJ9hLAK1KzA=
|
github.com/nacos-group/nacos-sdk-go v1.0.8/go.mod h1:hlAPn3UdzlxIlSILAyOXKxjFSvDJ9oLzTJ9hLAK1KzA=
|
||||||
github.com/nacos-group/nacos-sdk-go v1.1.1/go.mod h1:UHOtQNQY/qpk2dhg6gDq8u5+/CEIc3+lWmrmxEzX0/g=
|
github.com/nacos-group/nacos-sdk-go v1.1.1/go.mod h1:UHOtQNQY/qpk2dhg6gDq8u5+/CEIc3+lWmrmxEzX0/g=
|
||||||
github.com/nacos-group/nacos-sdk-go/v2 v2.1.2/go.mod h1:ys/1adWeKXXzbNWfRNbaFlX/t6HVLWdpsNDvmoWTw0g=
|
github.com/nacos-group/nacos-sdk-go/v2 v2.1.2/go.mod h1:ys/1adWeKXXzbNWfRNbaFlX/t6HVLWdpsNDvmoWTw0g=
|
||||||
github.com/nacos-group/nacos-sdk-go/v2 v2.2.3 h1:sUQx4f1bXDeeOOEQZjGAitzxYApbYY9fVDbxVCaBW+I=
|
|
||||||
github.com/nacos-group/nacos-sdk-go/v2 v2.2.3/go.mod h1:UL4U89WYdnyajgKJUMpuT1Rr6iNmbjrxOO40JRgtA00=
|
|
||||||
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
|
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
|
||||||
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
|
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
|
||||||
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
# Alicloud Nacos Binding certification testing
|
|
||||||
|
|
||||||
This project aims to test the Alicloud Nacos binding component under various conditions.
|
|
||||||
|
|
||||||
## Test plan
|
|
||||||
|
|
||||||
### Functional tests
|
|
||||||
|
|
||||||
- Create config:
|
|
||||||
- Successful
|
|
||||||
|
|
||||||
- Get Config:
|
|
||||||
- Successful Get Config
|
|
||||||
- Config does not exist
|
|
||||||
|
|
||||||
### Running the tests
|
|
||||||
|
|
||||||
This must be run in the GitHub Actions Workflow configured for test infrastructure setup.
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
apiVersion: dapr.io/v1alpha1
|
|
||||||
kind: Component
|
|
||||||
metadata:
|
|
||||||
name: alicloud-nacos-binding
|
|
||||||
namespace: default
|
|
||||||
spec:
|
|
||||||
type: bindings.alicloud.nacos
|
|
||||||
version: v1
|
|
||||||
metadata:
|
|
||||||
- name: endpoint
|
|
||||||
value: localhost:8848
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
apiVersion: dapr.io/v1alpha1
|
|
||||||
kind: Configuration
|
|
||||||
metadata:
|
|
||||||
name: nacosbindingconfig
|
|
||||||
spec:
|
|
||||||
features:
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
version: "3.7"
|
|
||||||
services:
|
|
||||||
nacos:
|
|
||||||
image: nacos/nacos-server:2.0.3-slim
|
|
||||||
environment:
|
|
||||||
- PREFER_HOST_MODE=hostname
|
|
||||||
- MODE=standalone
|
|
||||||
ports:
|
|
||||||
- "8848:8848"
|
|
||||||
|
|
@ -1,200 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2021 The Dapr Authors
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package nacosbinding_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"strconv"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/dapr/components-contrib/tests/certification/flow/dockercompose"
|
|
||||||
"github.com/dapr/kit/logger"
|
|
||||||
"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
|
|
||||||
"github.com/dapr/components-contrib/bindings"
|
|
||||||
nacosbinding "github.com/dapr/components-contrib/bindings/nacos"
|
|
||||||
bindings_loader "github.com/dapr/dapr/pkg/components/bindings"
|
|
||||||
"github.com/dapr/dapr/pkg/runtime"
|
|
||||||
daprsdk "github.com/dapr/go-sdk/client"
|
|
||||||
|
|
||||||
"github.com/dapr/components-contrib/tests/certification/embedded"
|
|
||||||
"github.com/dapr/components-contrib/tests/certification/flow"
|
|
||||||
"github.com/dapr/components-contrib/tests/certification/flow/sidecar"
|
|
||||||
|
|
||||||
nacosclient "github.com/nacos-group/nacos-sdk-go/v2/clients"
|
|
||||||
"github.com/nacos-group/nacos-sdk-go/v2/vo"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
sidecarName = "nacos-sidecar"
|
|
||||||
configData = "my config data"
|
|
||||||
bindingName = "alicloud-nacos-binding"
|
|
||||||
nacosClusterName = "nacos"
|
|
||||||
dockerComposeYAML = "docker-compose.yml"
|
|
||||||
)
|
|
||||||
|
|
||||||
func createConfigAndData() (map[string]interface{}, map[string]string) {
|
|
||||||
config := map[string]string{
|
|
||||||
"config-id": "123abc456def",
|
|
||||||
"config-group": "test-group",
|
|
||||||
}
|
|
||||||
// Another way of create serverConfigs
|
|
||||||
serverConfigs := []constant.ServerConfig{
|
|
||||||
*constant.NewServerConfig(
|
|
||||||
"localhost",
|
|
||||||
8848,
|
|
||||||
constant.WithScheme("http"),
|
|
||||||
constant.WithContextPath("/nacos"),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
nacosConfig := map[string]interface{}{
|
|
||||||
constant.KEY_SERVER_CONFIGS: serverConfigs,
|
|
||||||
}
|
|
||||||
return nacosConfig, config
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNacosBinding(t *testing.T) {
|
|
||||||
invokeCreateWithConfig := func(ctx flow.Context, config map[string]string) error {
|
|
||||||
client, clientErr := daprsdk.NewClientWithPort(fmt.Sprint(runtime.DefaultDaprAPIGRPCPort))
|
|
||||||
if clientErr != nil {
|
|
||||||
panic(clientErr)
|
|
||||||
}
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
invokeRequest := &daprsdk.InvokeBindingRequest{
|
|
||||||
Name: bindingName,
|
|
||||||
Operation: string(bindings.CreateOperation),
|
|
||||||
Data: []byte(configData),
|
|
||||||
Metadata: config,
|
|
||||||
}
|
|
||||||
|
|
||||||
err := client.InvokeOutputBinding(ctx, invokeRequest)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
invokeGetWithConfig := func(ctx flow.Context, config map[string]string) ([]byte, error) {
|
|
||||||
client, clientErr := daprsdk.NewClientWithPort(fmt.Sprint(runtime.DefaultDaprAPIGRPCPort))
|
|
||||||
if clientErr != nil {
|
|
||||||
panic(clientErr)
|
|
||||||
}
|
|
||||||
defer client.Close()
|
|
||||||
|
|
||||||
invokeRequest := &daprsdk.InvokeBindingRequest{
|
|
||||||
Name: bindingName,
|
|
||||||
Operation: string(bindings.GetOperation),
|
|
||||||
Metadata: config,
|
|
||||||
}
|
|
||||||
|
|
||||||
rsp, err := client.InvokeBinding(ctx, invokeRequest)
|
|
||||||
return rsp.Data, err
|
|
||||||
}
|
|
||||||
|
|
||||||
testInvokeCreateAndVerify := func(ctx flow.Context) error {
|
|
||||||
nacosConfig, config := createConfigAndData()
|
|
||||||
invokeErr := invokeCreateWithConfig(ctx, config)
|
|
||||||
assert.NoError(t, invokeErr)
|
|
||||||
|
|
||||||
// sleep to avoid metadata request rate limit before initializing new client
|
|
||||||
flow.Sleep(3 * time.Second)
|
|
||||||
|
|
||||||
client, creatConfigErr := nacosclient.CreateConfigClient(nacosConfig)
|
|
||||||
assert.NoError(t, creatConfigErr)
|
|
||||||
content, getConfigError := client.GetConfig(vo.ConfigParam{
|
|
||||||
DataId: config["config-id"],
|
|
||||||
Group: config["config-group"],
|
|
||||||
Content: "",
|
|
||||||
OnChange: nil,
|
|
||||||
})
|
|
||||||
assert.NoError(t, getConfigError)
|
|
||||||
assert.Equal(t, configData, content)
|
|
||||||
|
|
||||||
// cleanup
|
|
||||||
_, err := client.DeleteConfig(vo.ConfigParam{
|
|
||||||
DataId: config["config-id"],
|
|
||||||
Group: config["config-group"],
|
|
||||||
Content: "",
|
|
||||||
OnChange: nil,
|
|
||||||
})
|
|
||||||
assert.NoError(t, err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
testInvokeGetAndVerify := func(ctx flow.Context) error {
|
|
||||||
nacosConfig, config := createConfigAndData()
|
|
||||||
|
|
||||||
// sleep to avoid metadata request rate limit before initializing new client
|
|
||||||
flow.Sleep(3 * time.Second)
|
|
||||||
|
|
||||||
client, creatConfigErr := nacosclient.CreateConfigClient(nacosConfig)
|
|
||||||
assert.NoError(t, creatConfigErr)
|
|
||||||
ok, getConfigError := client.PublishConfig(vo.ConfigParam{
|
|
||||||
DataId: config["config-id"],
|
|
||||||
Group: config["config-group"],
|
|
||||||
Content: configData,
|
|
||||||
OnChange: nil,
|
|
||||||
})
|
|
||||||
assert.NoError(t, getConfigError)
|
|
||||||
assert.True(t, ok)
|
|
||||||
|
|
||||||
data, invokeErr := invokeGetWithConfig(ctx, config)
|
|
||||||
assert.Equal(t, configData, string(data))
|
|
||||||
assert.NoError(t, invokeErr)
|
|
||||||
|
|
||||||
// cleanup
|
|
||||||
_, err := client.DeleteConfig(vo.ConfigParam{
|
|
||||||
DataId: config["config-id"],
|
|
||||||
Group: config["config-group"],
|
|
||||||
Content: "",
|
|
||||||
OnChange: nil,
|
|
||||||
})
|
|
||||||
assert.NoError(t, err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
testInvokeGetWithErrorAndVerify := func(ctx flow.Context) error {
|
|
||||||
_, config := createConfigAndData()
|
|
||||||
|
|
||||||
// sleep to avoid metadata request rate limit before initializing new client
|
|
||||||
flow.Sleep(3 * time.Second)
|
|
||||||
|
|
||||||
_, invokeErr := invokeGetWithConfig(ctx, config)
|
|
||||||
assert.NotNil(t, invokeErr)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
flow.New(t, "test nacos binding config").
|
|
||||||
Step(dockercompose.Run(nacosClusterName, dockerComposeYAML)).
|
|
||||||
Step(sidecar.Run(sidecarName,
|
|
||||||
embedded.WithoutApp(),
|
|
||||||
embedded.WithComponentsPath("./components"),
|
|
||||||
embedded.WithDaprGRPCPort(strconv.Itoa(runtime.DefaultDaprAPIGRPCPort)),
|
|
||||||
embedded.WithDaprHTTPPort(strconv.Itoa(runtime.DefaultDaprHTTPPort)),
|
|
||||||
embedded.WithBindings(newBindingsRegistry()))).
|
|
||||||
Step("verify data sent to output binding is written to nacos", testInvokeCreateAndVerify).
|
|
||||||
Step("verify data sent in nacos can be got correctly", testInvokeGetAndVerify).
|
|
||||||
Step("verify get config with error", testInvokeGetWithErrorAndVerify).
|
|
||||||
Run()
|
|
||||||
}
|
|
||||||
|
|
||||||
func newBindingsRegistry() *bindings_loader.Registry {
|
|
||||||
log := logger.NewLogger("dapr.components")
|
|
||||||
|
|
||||||
r := bindings_loader.NewRegistry()
|
|
||||||
r.Logger = log
|
|
||||||
r.RegisterOutputBinding(nacosbinding.NewNacos, "alicloud.nacos")
|
|
||||||
return r
|
|
||||||
}
|
|
||||||
|
|
@ -29,7 +29,6 @@ require (
|
||||||
github.com/jackc/pgx/v5 v5.4.3
|
github.com/jackc/pgx/v5 v5.4.3
|
||||||
github.com/joho/godotenv v1.4.0
|
github.com/joho/godotenv v1.4.0
|
||||||
github.com/lestrrat-go/jwx/v2 v2.0.12
|
github.com/lestrrat-go/jwx/v2 v2.0.12
|
||||||
github.com/nacos-group/nacos-sdk-go/v2 v2.2.3
|
|
||||||
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5
|
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5
|
||||||
github.com/rabbitmq/amqp091-go v1.8.1
|
github.com/rabbitmq/amqp091-go v1.8.1
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.8.4
|
||||||
|
|
@ -72,7 +71,6 @@ require (
|
||||||
github.com/Workiva/go-datastructures v1.0.53 // indirect
|
github.com/Workiva/go-datastructures v1.0.53 // indirect
|
||||||
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 // indirect
|
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 // indirect
|
||||||
github.com/alibaba/sentinel-golang v1.0.4 // indirect
|
github.com/alibaba/sentinel-golang v1.0.4 // indirect
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704 // indirect
|
|
||||||
github.com/andybalholm/brotli v1.0.5 // indirect
|
github.com/andybalholm/brotli v1.0.5 // indirect
|
||||||
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
|
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
|
||||||
github.com/apache/dubbo-getty v1.4.9-0.20220610060150-8af010f3f3dc // indirect
|
github.com/apache/dubbo-getty v1.4.9-0.20220610060150-8af010f3f3dc // indirect
|
||||||
|
|
@ -84,7 +82,6 @@ require (
|
||||||
github.com/bits-and-blooms/bitset v1.4.0 // indirect
|
github.com/bits-and-blooms/bitset v1.4.0 // indirect
|
||||||
github.com/bradfitz/gomemcache v0.0.0-20230611145640-acc696258285 // indirect
|
github.com/bradfitz/gomemcache v0.0.0-20230611145640-acc696258285 // indirect
|
||||||
github.com/bufbuild/protocompile v0.4.0 // indirect
|
github.com/bufbuild/protocompile v0.4.0 // indirect
|
||||||
github.com/buger/jsonparser v1.1.1 // indirect
|
|
||||||
github.com/bytedance/gopkg v0.0.0-20220817015305-b879a72dc90f // indirect
|
github.com/bytedance/gopkg v0.0.0-20220817015305-b879a72dc90f // indirect
|
||||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||||
|
|
@ -292,8 +289,6 @@ require (
|
||||||
google.golang.org/grpc v1.57.0 // indirect
|
google.golang.org/grpc v1.57.0 // indirect
|
||||||
google.golang.org/protobuf v1.31.0 // indirect
|
google.golang.org/protobuf v1.31.0 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
k8s.io/api v0.26.3 // indirect
|
k8s.io/api v0.26.3 // indirect
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,6 @@ github.com/alibaba/sentinel-golang v1.0.4/go.mod h1:Lag5rIYyJiPOylK8Kku2P+a23gdK
|
||||||
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk=
|
github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk=
|
||||||
github.com/alicebob/miniredis/v2 v2.30.5 h1:3r6kTHdKnuP4fkS8k2IrvSfxpxUTcW1SOL0wN7b7Dt0=
|
github.com/alicebob/miniredis/v2 v2.30.5 h1:3r6kTHdKnuP4fkS8k2IrvSfxpxUTcW1SOL0wN7b7Dt0=
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk=
|
github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk=
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704 h1:PpfENOj/vPfhhy9N2OFRjpue0hjM5XqAp2thFmkXXIk=
|
|
||||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU=
|
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704/go.mod h1:RcDobYh8k5VP6TNybz9m++gL3ijVI5wueVr0EM10VsU=
|
||||||
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
|
||||||
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||||
|
|
@ -213,7 +212,6 @@ github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y=
|
||||||
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
|
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
|
||||||
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
|
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
|
||||||
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
|
||||||
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
|
|
||||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||||
github.com/bytedance/gopkg v0.0.0-20210705062217-74c74ebadcae/go.mod h1:birsdqRCbwnckJbdAvcSao+AzOyibVEoWB55MjpYpB8=
|
github.com/bytedance/gopkg v0.0.0-20210705062217-74c74ebadcae/go.mod h1:birsdqRCbwnckJbdAvcSao+AzOyibVEoWB55MjpYpB8=
|
||||||
github.com/bytedance/gopkg v0.0.0-20210709064845-3c00f9323f09/go.mod h1:birsdqRCbwnckJbdAvcSao+AzOyibVEoWB55MjpYpB8=
|
github.com/bytedance/gopkg v0.0.0-20210709064845-3c00f9323f09/go.mod h1:birsdqRCbwnckJbdAvcSao+AzOyibVEoWB55MjpYpB8=
|
||||||
|
|
@ -979,8 +977,6 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW
|
||||||
github.com/nacos-group/nacos-sdk-go v1.0.8/go.mod h1:hlAPn3UdzlxIlSILAyOXKxjFSvDJ9oLzTJ9hLAK1KzA=
|
github.com/nacos-group/nacos-sdk-go v1.0.8/go.mod h1:hlAPn3UdzlxIlSILAyOXKxjFSvDJ9oLzTJ9hLAK1KzA=
|
||||||
github.com/nacos-group/nacos-sdk-go v1.1.1/go.mod h1:UHOtQNQY/qpk2dhg6gDq8u5+/CEIc3+lWmrmxEzX0/g=
|
github.com/nacos-group/nacos-sdk-go v1.1.1/go.mod h1:UHOtQNQY/qpk2dhg6gDq8u5+/CEIc3+lWmrmxEzX0/g=
|
||||||
github.com/nacos-group/nacos-sdk-go/v2 v2.1.2/go.mod h1:ys/1adWeKXXzbNWfRNbaFlX/t6HVLWdpsNDvmoWTw0g=
|
github.com/nacos-group/nacos-sdk-go/v2 v2.1.2/go.mod h1:ys/1adWeKXXzbNWfRNbaFlX/t6HVLWdpsNDvmoWTw0g=
|
||||||
github.com/nacos-group/nacos-sdk-go/v2 v2.2.3 h1:sUQx4f1bXDeeOOEQZjGAitzxYApbYY9fVDbxVCaBW+I=
|
|
||||||
github.com/nacos-group/nacos-sdk-go/v2 v2.2.3/go.mod h1:UL4U89WYdnyajgKJUMpuT1Rr6iNmbjrxOO40JRgtA00=
|
|
||||||
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
|
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
|
||||||
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
|
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
|
||||||
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg=
|
||||||
|
|
@ -1930,7 +1926,6 @@ gopkg.in/ini.v1 v1.42.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue