add Ping operation to`store` interface. (#757)
* add `Ping` operation. * add `Ping` implementation of GA components * add context to an argument for Ping * add `Ping` implementation of blobstorage * fix error string for passing lint * Update blobstorage.go Co-authored-by: Artur Souza <artursouza.ms@outlook.com>
This commit is contained in:
parent
efd198026f
commit
b387fcdff3
|
@ -230,6 +230,10 @@ func (aspike *Aerospike) Delete(req *state.DeleteRequest) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (aspike *Aerospike) Ping() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseHosts(hostsMeta string) ([]*as.Host, error) {
|
||||
hostPorts := []*as.Host{}
|
||||
for _, hostPort := range strings.Split(hostsMeta, ",") {
|
||||
|
|
|
@ -51,6 +51,10 @@ func (d *StateStore) Init(metadata state.Metadata) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (d *StateStore) Ping() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Features returns the features available in this state store
|
||||
func (d *StateStore) Features() []state.Feature {
|
||||
return nil
|
||||
|
|
|
@ -138,6 +138,16 @@ func (r *StateStore) Set(req *state.SetRequest) error {
|
|||
return r.writeFile(req)
|
||||
}
|
||||
|
||||
func (r *StateStore) Ping() error {
|
||||
accessConditions := azblob.BlobAccessConditions{}
|
||||
|
||||
if _, err := r.containerURL.GetProperties(context.Background(), accessConditions.LeaseAccessConditions); err != nil {
|
||||
return fmt.Errorf("blob storage: error connecting to Blob storage at %s: %s", r.containerURL.URL().Host, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewAzureBlobStorageStore instance
|
||||
func NewAzureBlobStorageStore(logger logger.Logger) *StateStore {
|
||||
s := &StateStore{
|
||||
|
|
|
@ -28,6 +28,7 @@ type StateStore struct {
|
|||
collection *documentdb.Collection
|
||||
db *documentdb.Database
|
||||
sp *documentdb.Sproc
|
||||
metadata metadata
|
||||
contentType string
|
||||
|
||||
features []state.Feature
|
||||
|
@ -139,6 +140,7 @@ func (c *StateStore) Init(meta state.Metadata) error {
|
|||
return fmt.Errorf("collection %s for CosmosDB state store not found. This must be created before Dapr uses it", m.Collection)
|
||||
}
|
||||
|
||||
c.metadata = m
|
||||
c.collection = &colls[0]
|
||||
c.client = client
|
||||
c.contentType = m.ContentType
|
||||
|
@ -359,6 +361,24 @@ func (c *StateStore) Multi(request *state.TransactionalStateRequest) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *StateStore) Ping() error {
|
||||
m := c.metadata
|
||||
|
||||
colls, err := c.client.QueryCollections(c.db.Self, &documentdb.Query{
|
||||
Query: "SELECT * FROM ROOT r WHERE r.id=@id",
|
||||
Parameters: []documentdb.Parameter{
|
||||
{Name: "@id", Value: m.Collection},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
} else if len(colls) == 0 {
|
||||
return fmt.Errorf("collection %s for CosmosDB state store not found", m.Collection)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createUpsertItem(contentType string, req state.SetRequest, partitionKey string) CosmosItem {
|
||||
byteArray, isBinary := req.Value.([]uint8)
|
||||
if isBinary {
|
||||
|
|
|
@ -236,6 +236,10 @@ func (r *StateStore) deleteRow(req *state.DeleteRequest) error {
|
|||
return entity.Delete(true, nil)
|
||||
}
|
||||
|
||||
func (r *StateStore) Ping() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func getPartitionAndRowKey(key string) (string, string) {
|
||||
pr := strings.Split(key, keyDelimiter)
|
||||
if len(pr) != 2 {
|
||||
|
|
|
@ -289,6 +289,10 @@ func (c *Cassandra) Set(req *state.SetRequest) error {
|
|||
return session.Query("INSERT INTO ? (key, value) VALUES (?, ?)", c.table, req.Key, bt).Exec()
|
||||
}
|
||||
|
||||
func (c *Cassandra) Ping() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Cassandra) createSession(consistency gocql.Consistency) (*gocql.Session, error) {
|
||||
session, err := c.cluster.CreateSession()
|
||||
if err != nil {
|
||||
|
|
|
@ -265,6 +265,10 @@ func (c *CRDT) Init(metadata state.Metadata) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *CRDT) Ping() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Features returns the features available in this state store
|
||||
func (c *CRDT) Features() []state.Feature {
|
||||
return c.features
|
||||
|
|
|
@ -228,6 +228,10 @@ func (cbs *Couchbase) Delete(req *state.DeleteRequest) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (cbs *Couchbase) Ping() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// converts string etag sent by the application into a gocb.Cas object, which can then be used for optimistic locking for set and delete operations
|
||||
func eTagToCas(eTag string) (gocb.Cas, error) {
|
||||
var cas gocb.Cas = 0
|
||||
|
|
|
@ -136,6 +136,10 @@ func (f *Firestore) Set(req *state.SetRequest) error {
|
|||
return state.SetWithOptions(f.setValue, req)
|
||||
}
|
||||
|
||||
func (f *Firestore) Ping() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *Firestore) deleteValue(req *state.DeleteRequest) error {
|
||||
ctx := context.Background()
|
||||
key := datastore.NameKey(f.entityKind, req.Key, nil)
|
||||
|
|
|
@ -10,11 +10,10 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/agrea/ptr"
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/dapr/components-contrib/state"
|
||||
"github.com/dapr/kit/logger"
|
||||
"github.com/hashicorp/consul/api"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// Consul is a state store implementation for HashiCorp Consul.
|
||||
|
@ -138,6 +137,10 @@ func (c *Consul) Set(req *state.SetRequest) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (c *Consul) Ping() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete performes a Consul KV delete operation
|
||||
func (c *Consul) Delete(req *state.DeleteRequest) error {
|
||||
keyWithPath := fmt.Sprintf("%s/%s", c.keyPrefixPath, req.Key)
|
||||
|
|
|
@ -123,6 +123,10 @@ func (store *Hazelcast) Get(req *state.GetRequest) (*state.GetResponse, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
func (store *Hazelcast) Ping() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete performs a delete operation
|
||||
func (store *Hazelcast) Delete(req *state.DeleteRequest) error {
|
||||
err := state.CheckRequestOptions(req.Options)
|
||||
|
|
|
@ -141,3 +141,7 @@ func (m *Memcached) Get(req *state.GetRequest) (*state.GetResponse, error) {
|
|||
func (m *Memcached) Set(req *state.SetRequest) error {
|
||||
return state.SetWithOptions(m.setValue, req)
|
||||
}
|
||||
|
||||
func (m *Memcached) Ping() error {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ type MongoDB struct {
|
|||
client *mongo.Client
|
||||
collection *mongo.Collection
|
||||
operationTimeout time.Duration
|
||||
metadata mongoDBMetadata
|
||||
|
||||
features []state.Feature
|
||||
logger logger.Logger
|
||||
|
@ -125,6 +126,7 @@ func (m *MongoDB) Init(metadata state.Metadata) error {
|
|||
return fmt.Errorf("error in getting read concern object: %s", err)
|
||||
}
|
||||
|
||||
m.metadata = *meta
|
||||
opts := options.Collection().SetWriteConcern(wc).SetReadConcern(rc)
|
||||
collection := m.client.Database(meta.databaseName).Collection(meta.collectionName, opts)
|
||||
|
||||
|
@ -151,6 +153,14 @@ func (m *MongoDB) Set(req *state.SetRequest) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (m *MongoDB) Ping() error {
|
||||
if err := m.client.Ping(context.Background(), nil); err != nil {
|
||||
return fmt.Errorf("mongoDB store: error connecting to mongoDB at %s: %s", m.metadata.host, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MongoDB) setInternal(ctx context.Context, req *state.SetRequest) error {
|
||||
var vStr string
|
||||
b, ok := req.Value.([]byte)
|
||||
|
|
|
@ -149,6 +149,10 @@ func (m *MySQL) Init(metadata state.Metadata) error {
|
|||
return m.finishInit(db, err)
|
||||
}
|
||||
|
||||
func (m *MySQL) Ping() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Features returns the features available in this state store
|
||||
func (m *MySQL) Features() []state.Feature {
|
||||
return m.features
|
||||
|
|
|
@ -41,6 +41,10 @@ func (p *PostgreSQL) Init(metadata state.Metadata) error {
|
|||
return p.dbaccess.Init(metadata)
|
||||
}
|
||||
|
||||
func (p *PostgreSQL) Ping() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Features returns the features available in this state store
|
||||
func (p *PostgreSQL) Features() []state.Feature {
|
||||
return p.features
|
||||
|
|
|
@ -130,6 +130,14 @@ func parseRedisMetadata(meta state.Metadata) (metadata, error) {
|
|||
return m, nil
|
||||
}
|
||||
|
||||
func (r *StateStore) Ping() error {
|
||||
if _, err := r.client.Ping(context.Background()).Result(); err != nil {
|
||||
return fmt.Errorf("redis store: error connecting to redis at %s: %s", r.metadata.host, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Init does metadata and connection parsing
|
||||
func (r *StateStore) Init(metadata state.Metadata) error {
|
||||
m, err := parseRedisMetadata(metadata)
|
||||
|
|
|
@ -181,6 +181,24 @@ func TestTransactionalDelete(t *testing.T) {
|
|||
assert.Equal(t, 0, len(vals))
|
||||
}
|
||||
|
||||
func TestPing(t *testing.T) {
|
||||
s, c := setupMiniredis()
|
||||
|
||||
ss := &StateStore{
|
||||
client: c,
|
||||
json: jsoniter.ConfigFastest,
|
||||
logger: logger.NewLogger("test"),
|
||||
}
|
||||
|
||||
err := ss.Ping()
|
||||
assert.Nil(t, err)
|
||||
|
||||
s.Close()
|
||||
|
||||
err = ss.Ping()
|
||||
assert.NotNil(t, err)
|
||||
}
|
||||
|
||||
func TestTransactionalDeleteNoEtag(t *testing.T) {
|
||||
s, c := setupMiniredis()
|
||||
defer s.Close()
|
||||
|
|
|
@ -123,6 +123,10 @@ func (s *RethinkDB) Init(metadata state.Metadata) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *RethinkDB) Ping() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Features returns the features available in this state store
|
||||
func (s *RethinkDB) Features() []state.Feature {
|
||||
return s.features
|
||||
|
|
|
@ -253,6 +253,10 @@ func (s *SQLServer) Init(metadata state.Metadata) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *SQLServer) Ping() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Features returns the features available in this state store
|
||||
func (s *SQLServer) Features() []state.Feature {
|
||||
return s.features
|
||||
|
|
|
@ -13,6 +13,7 @@ type Store interface {
|
|||
Delete(req *DeleteRequest) error
|
||||
Get(req *GetRequest) (*GetResponse, error)
|
||||
Set(req *SetRequest) error
|
||||
Ping() error
|
||||
}
|
||||
|
||||
// BulkStore is an interface to perform bulk operations on store
|
||||
|
|
|
@ -115,6 +115,10 @@ func (s *Store1) Set(req *SetRequest) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *Store1) Ping() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// example of store which supports bulk method
|
||||
type Store2 struct {
|
||||
// DefaultBulkStore
|
||||
|
@ -150,6 +154,10 @@ func (s *Store2) Set(req *SetRequest) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (s *Store2) Ping() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Store2) BulkGet(req []GetRequest) (bool, []BulkGetResponse, error) {
|
||||
if s.supportBulkGet {
|
||||
s.bulkCount++
|
||||
|
|
|
@ -295,6 +295,10 @@ func (s *StateStore) BulkSet(reqs []state.SetRequest) error {
|
|||
}
|
||||
}
|
||||
|
||||
func (s *StateStore) Ping() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *StateStore) newCreateRequest(req *zk.SetDataRequest) *zk.CreateRequest {
|
||||
return &zk.CreateRequest{Path: req.Path, Data: req.Data}
|
||||
}
|
||||
|
|
|
@ -196,6 +196,11 @@ func ConformanceTests(t *testing.T, props map[string]string, statestore state.St
|
|||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
t.Run("ping", func(t *testing.T) {
|
||||
err := statestore.Ping()
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
if config.HasOperation("set") {
|
||||
t.Run("set", func(t *testing.T) {
|
||||
for _, scenario := range scenarios {
|
||||
|
|
Loading…
Reference in New Issue