mirror of
https://github.com/mainflux/mainflux.git
synced 2025-05-11 19:29:16 +08:00

* Add twins redis cache Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Add connectToRedis to twins main and twinCache to twins service Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Add tracing to twins cache Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Add twins cache mock and test setup for redis cache Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Add TestTwinSave to redis twins cache tests Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Add remove twin redis cache test Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Add channels param to CreateDefinition helper method in mocks Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Add IDs test to redis twins cache Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Simplify senml rec array and attribute creation funcs by removing unnecessary params Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Align cache remove twin method with service remove twin method Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Add cache funcs to twins save, update and remove Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Add def SaveIDs to redis cache and ref to service SaveStates Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Add TwinSaveIDs tests for redis cache Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Add cache related env vars desc to README.md Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Add twinid bson key constant Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Add Update method to cache Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Integrate uuid unification related changes Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Use named arguments in interface method declarations Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Add env vars to docker-compose file Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Make parameter names in interface methods and implementations consistent Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com> * Wrap vars and consts in var and const blocks Signed-off-by: Darko Draskovic <darko.draskovic@gmail.com>
124 lines
3.3 KiB
Go
124 lines
3.3 KiB
Go
// Copyright (c) Mainflux
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package redis
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/go-redis/redis"
|
|
"github.com/mainflux/mainflux/pkg/errors"
|
|
"github.com/mainflux/mainflux/twins"
|
|
)
|
|
|
|
const (
|
|
prefix = "twin"
|
|
)
|
|
|
|
var (
|
|
// ErrRedisTwinSave indicates error while saving Twin in redis cache
|
|
ErrRedisTwinSave = errors.New("failed to save twin in redis cache")
|
|
|
|
// ErrRedisTwinUpdate indicates error while saving Twin in redis cache
|
|
ErrRedisTwinUpdate = errors.New("failed to update twin in redis cache")
|
|
|
|
// ErrRedisTwinIDs indicates error while geting Twin IDs from redis cache
|
|
ErrRedisTwinIDs = errors.New("failed to get twin id from redis cache")
|
|
|
|
// ErrRedisTwinRemove indicates error while removing Twin from redis cache
|
|
ErrRedisTwinRemove = errors.New("failed to remove twin from redis cache")
|
|
)
|
|
|
|
var _ twins.TwinCache = (*twinCache)(nil)
|
|
|
|
type twinCache struct {
|
|
client *redis.Client
|
|
}
|
|
|
|
// NewTwinCache returns redis twin cache implementation.
|
|
func NewTwinCache(client *redis.Client) twins.TwinCache {
|
|
return &twinCache{
|
|
client: client,
|
|
}
|
|
}
|
|
|
|
func (tc *twinCache) Save(_ context.Context, twin twins.Twin) error {
|
|
return tc.save(twin)
|
|
}
|
|
|
|
func (tc *twinCache) Update(_ context.Context, twin twins.Twin) error {
|
|
if err := tc.remove(twin.ID); err != nil {
|
|
return errors.Wrap(ErrRedisTwinUpdate, err)
|
|
}
|
|
if err := tc.save(twin); err != nil {
|
|
return errors.Wrap(ErrRedisTwinUpdate, err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (tc *twinCache) SaveIDs(_ context.Context, channel, subtopic string, ids []string) error {
|
|
for _, id := range ids {
|
|
if err := tc.client.SAdd(attrKey(channel, subtopic), id).Err(); err != nil {
|
|
return errors.Wrap(ErrRedisTwinSave, err)
|
|
}
|
|
if err := tc.client.SAdd(twinKey(id), attrKey(channel, subtopic)).Err(); err != nil {
|
|
return errors.Wrap(ErrRedisTwinSave, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (tc *twinCache) IDs(_ context.Context, channel, subtopic string) ([]string, error) {
|
|
ids, err := tc.client.SMembers(attrKey(channel, subtopic)).Result()
|
|
if err != nil {
|
|
return nil, errors.Wrap(ErrRedisTwinIDs, err)
|
|
}
|
|
return ids, nil
|
|
}
|
|
|
|
func (tc *twinCache) Remove(_ context.Context, twinID string) error {
|
|
return tc.remove(twinID)
|
|
}
|
|
|
|
func (tc *twinCache) save(twin twins.Twin) error {
|
|
if len(twin.Definitions) < 1 {
|
|
return nil
|
|
}
|
|
attributes := twin.Definitions[len(twin.Definitions)-1].Attributes
|
|
for _, attr := range attributes {
|
|
if err := tc.client.SAdd(attrKey(attr.Channel, attr.Subtopic), twin.ID).Err(); err != nil {
|
|
return errors.Wrap(ErrRedisTwinSave, err)
|
|
}
|
|
if err := tc.client.SAdd(twinKey(twin.ID), attrKey(attr.Channel, attr.Subtopic)).Err(); err != nil {
|
|
return errors.Wrap(ErrRedisTwinSave, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (tc *twinCache) remove(twinID string) error {
|
|
twinKey := twinKey(twinID)
|
|
attrKeys, err := tc.client.SMembers(twinKey).Result()
|
|
if err != nil {
|
|
return errors.Wrap(ErrRedisTwinRemove, err)
|
|
}
|
|
if err := tc.client.Del(twinKey).Err(); err != nil {
|
|
return errors.Wrap(ErrRedisTwinRemove, err)
|
|
}
|
|
for _, attrKey := range attrKeys {
|
|
if err := tc.client.SRem(attrKey, twinID).Err(); err != nil {
|
|
return errors.Wrap(ErrRedisTwinRemove, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func twinKey(twinID string) string {
|
|
return fmt.Sprintf("%s:%s", prefix, twinID)
|
|
}
|
|
|
|
func attrKey(channel, subtopic string) string {
|
|
return fmt.Sprintf("%s:%s-%s", prefix, channel, subtopic)
|
|
}
|