API访问etcd, kv对增删改查

package etcd

import (
	"context"
	"fmt"
	"github.com/golang/glog"
	"go.etcd.io/etcd/clientv3"
	"go.etcd.io/etcd/pkg/transport"
	"sync"
	"time"
)

type ThreadSafeEtcd struct {
	client *clientv3.Client
	lock   sync.Mutex

	certdir string
	endpoints []string
}

type KvPair struct {
	Key string
	Value string
}

var (
	dialTimeout    = 5 * time.Second
	requestTimeout = 10 * time.Second
	instance *ThreadSafeEtcd
	once sync.Once
)

func (etcd *ThreadSafeEtcd) KV_delete(key string) error {
	etcd.lock.Lock()
	defer etcd.lock.Unlock()

	tlsInfo := transport.TLSInfo{
		CertFile:      fmt.Sprintf("%s%s", etcd.certdir, "/peer.crt"),
		KeyFile:       fmt.Sprintf("%s%s", etcd.certdir, "/peer.key"),
		TrustedCAFile: fmt.Sprintf("%s%s", etcd.certdir, "/ca.crt"),
	}

	tlsConfig, err := tlsInfo.ClientConfig()
	if err != nil {
		return err
	}
	cli, err := clientv3.New(clientv3.Config{
		Endpoints:   etcd.endpoints,
		DialTimeout: dialTimeout,
		TLS:         tlsConfig,
	})
	if err != nil {
		return err
	}

	defer cli.Close() // make sure to close the client

	ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
	_, err = cli.Delete(ctx, key)
	cancel()

	if err != nil {
		return err
	}

	return nil
}

func (etcd *ThreadSafeEtcd) KV_put(kv *KvPair) error {
	etcd.lock.Lock()
	defer etcd.lock.Unlock()

	tlsInfo := transport.TLSInfo{
		CertFile:      fmt.Sprintf("%s%s", etcd.certdir, "/peer.crt"),
		KeyFile:       fmt.Sprintf("%s%s", etcd.certdir, "/peer.key"),
		TrustedCAFile: fmt.Sprintf("%s%s", etcd.certdir, "/ca.crt"),
	}

	tlsConfig, err := tlsInfo.ClientConfig()
	if err != nil {
		return err
	}
	cli, err := clientv3.New(clientv3.Config{
		Endpoints:   etcd.endpoints,
		DialTimeout: dialTimeout,
		TLS:         tlsConfig,
	})
	if err != nil {
		return err
	}

	defer cli.Close() // make sure to close the client

	ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
	_, err = cli.Put(ctx, kv.Key, kv.Value)
	cancel()

	if err != nil {
		return err
	}

	return nil
}

func (etcd *ThreadSafeEtcd) KV_get(key string) (*KvPair, error) {
	etcd.lock.Lock()
	defer etcd.lock.Unlock()

	var kv KvPair

	tlsInfo := transport.TLSInfo{
		CertFile:      fmt.Sprintf("%s%s", etcd.certdir, "/peer.crt"),
		KeyFile:       fmt.Sprintf("%s%s", etcd.certdir, "/peer.key"),
		TrustedCAFile: fmt.Sprintf("%s%s", etcd.certdir, "/ca.crt"),
	}

	tlsConfig, err := tlsInfo.ClientConfig()
	if err != nil {
		return nil, err
	}
	cli, err := clientv3.New(clientv3.Config{
		Endpoints:   etcd.endpoints,
		DialTimeout: dialTimeout,
		TLS:         tlsConfig,
	})
	if err != nil {
		return nil, err
	}

	defer cli.Close() // make sure to close the client

	ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
	resp, err := cli.Get(ctx, key)
	cancel()

	if err != nil {
		glog.V(5).Infof("etcd KV_get, Get %s fail, err %v", key, err)
		return nil, err
	}
	
	for _, ev := range resp.Kvs {
		kv.Key = string(ev.Key)
		kv.Value = string(ev.Value)
		break
	}

	glog.V(5).Infof("KV_get, key: %s, value %s", kv.Key, kv.Value)
	return &kv, nil
}


func (etcd *ThreadSafeEtcd) Init(endpoints []string, certdir string) (*ThreadSafeEtcd, error) {
	etcd.lock.Lock()
	defer etcd.lock.Unlock()

	tlsInfo := transport.TLSInfo{
		CertFile:      fmt.Sprintf("%s%s", certdir, "/peer.crt"),
		KeyFile:       fmt.Sprintf("%s%s", certdir, "/peer.key"),
		TrustedCAFile: fmt.Sprintf("%s%s", certdir, "/ca.crt"),
	}

	tlsConfig, err := tlsInfo.ClientConfig()
	if err != nil {
		return nil, err
	}
	cli, err := clientv3.New(clientv3.Config{
		Endpoints:   endpoints,
		DialTimeout: dialTimeout,
		TLS:         tlsConfig,
	})

	if err != nil {
		return nil, err
	}

	defer cli.Close() // make sure to close the client

	etcd.certdir = certdir
	etcd.endpoints = endpoints


	return etcd, nil
}

func GetInstance() *ThreadSafeEtcd {
	once.Do(func() {
		instance = &ThreadSafeEtcd{}
	})
	return instance
}

 

在Vue3中,可以使用`v-for`指令循环遍历配置项,并使用`v-model`指令绑定每个属性的值,从而实现对配置项的操作。对于数组对象里包裹数组对象的情况,可以使用嵌套的`v-for`指令来循环遍历,然后将每个元素转换成数据,从而实现对数组的操作。 以下是一个示例代码: ```html <template> <div> <div v-for="(group, index) in groups" :key="index"> <h2>Group {{ index + 1 }}</h2> <div v-for="(item, i) in group.items" :key="i"> <input type="text" v-model="item.name"> <button @click="deleteItem(group, i)">删除</button> </div> <button @click="addItem(group)">新增</button> </div> </div> </template> <script> export default { data() { return { groups: [ { id: 1, items: [{ name: 'Item 1' }, { name: 'Item 2' }, { name: 'Item 3' }] }, { id: 2, items: [{ name: 'Item 4' }, { name: 'Item 5' }] } ] } }, methods: { deleteItem(group, itemIndex) { group.items.splice(itemIndex, 1) }, addItem(group) { group.items.push({ name: '' }) } } } </script> ``` 在上面的代码中,我们使用了两层嵌套的`v-for`指令来循环遍历数组对象里的数组对象。对于每个子数组对象中的元素,我们将其转换成一个数据,包含一个name属性和一个删除按钮。当用户点击删除按钮时,我们调用`deleteItem`方法来从数组中删除该元素;当用户点击新增按钮时,我们调用`addItem`方法来向数组中添加一个新的元素。这样,我们就可以通过界面来操作数组对象里的数组对象了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值