mirror of
https://github.com/mainflux/mainflux.git
synced 2025-04-27 13:48:49 +08:00
NOISSUE - Implement errors package in senml transformer, readers and writers (#1108)
* Implement errors package in senml transformer, readers and writers Signed-off-by: Ivan Milošević <iva@blokovi.com> * Remove unused const Return wrapped error in postgres writer Signed-off-by: Ivan Milošević <iva@blokovi.com> * fix default db host in postgres writer Signed-off-by: Ivan Milošević <iva@blokovi.com> * fix capital letters in errors messages Signed-off-by: Ivan Milošević <iva@blokovi.com> * use svcName instead of postgres for Promethius initialization Signed-off-by: Ivan Milošević <iva@blokovi.com>
This commit is contained in:
parent
e438be4250
commit
880e193b0a
@ -31,7 +31,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
svcName = "postgres-writer"
|
svcName = "postgres-reader"
|
||||||
sep = ","
|
sep = ","
|
||||||
|
|
||||||
defLogLevel = "error"
|
defLogLevel = "error"
|
||||||
@ -112,7 +112,7 @@ func main() {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
err = <-errs
|
err = <-errs
|
||||||
logger.Error(fmt.Sprintf("Postgres writer service terminated: %s", err))
|
logger.Error(fmt.Sprintf("Postgres reader service terminated: %s", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadConfig() config {
|
func loadConfig() config {
|
||||||
@ -213,14 +213,14 @@ func newService(db *sqlx.DB, logger logger.Logger) readers.MessageRepository {
|
|||||||
svc = api.MetricsMiddleware(
|
svc = api.MetricsMiddleware(
|
||||||
svc,
|
svc,
|
||||||
kitprometheus.NewCounterFrom(stdprometheus.CounterOpts{
|
kitprometheus.NewCounterFrom(stdprometheus.CounterOpts{
|
||||||
Namespace: "postgres",
|
Namespace: svcName,
|
||||||
Subsystem: "message_writer",
|
Subsystem: "message_reader",
|
||||||
Name: "request_count",
|
Name: "request_count",
|
||||||
Help: "Number of requests received.",
|
Help: "Number of requests received.",
|
||||||
}, []string{"method"}),
|
}, []string{"method"}),
|
||||||
kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
|
kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
|
||||||
Namespace: "postgres",
|
Namespace: svcName,
|
||||||
Subsystem: "message_writer",
|
Subsystem: "message_reader",
|
||||||
Name: "request_latency_microseconds",
|
Name: "request_latency_microseconds",
|
||||||
Help: "Total duration of requests in microseconds.",
|
Help: "Total duration of requests in microseconds.",
|
||||||
}, []string{"method"}),
|
}, []string{"method"}),
|
||||||
|
@ -30,7 +30,7 @@ const (
|
|||||||
defLogLevel = "error"
|
defLogLevel = "error"
|
||||||
defNatsURL = "nats://localhost:4222"
|
defNatsURL = "nats://localhost:4222"
|
||||||
defPort = "8180"
|
defPort = "8180"
|
||||||
defDBHost = "postgres"
|
defDBHost = "localhost"
|
||||||
defDBPort = "5432"
|
defDBPort = "5432"
|
||||||
defDBUser = "mainflux"
|
defDBUser = "mainflux"
|
||||||
defDBPass = "mainflux"
|
defDBPass = "mainflux"
|
||||||
@ -139,13 +139,13 @@ func newService(db *sqlx.DB, logger logger.Logger) writers.MessageRepository {
|
|||||||
svc = api.MetricsMiddleware(
|
svc = api.MetricsMiddleware(
|
||||||
svc,
|
svc,
|
||||||
kitprometheus.NewCounterFrom(stdprometheus.CounterOpts{
|
kitprometheus.NewCounterFrom(stdprometheus.CounterOpts{
|
||||||
Namespace: "postgres",
|
Namespace: svcName,
|
||||||
Subsystem: "message_writer",
|
Subsystem: "message_writer",
|
||||||
Name: "request_count",
|
Name: "request_count",
|
||||||
Help: "Number of requests received.",
|
Help: "Number of requests received.",
|
||||||
}, []string{"method"}),
|
}, []string{"method"}),
|
||||||
kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
|
kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
|
||||||
Namespace: "postgres",
|
Namespace: svcName,
|
||||||
Subsystem: "message_writer",
|
Subsystem: "message_writer",
|
||||||
Name: "request_latency_microseconds",
|
Name: "request_latency_microseconds",
|
||||||
Help: "Total duration of requests in microseconds.",
|
Help: "Total duration of requests in microseconds.",
|
||||||
|
@ -30,3 +30,7 @@ func (res pageRes) Code() int {
|
|||||||
func (res pageRes) Empty() bool {
|
func (res pageRes) Empty() bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type errorRes struct {
|
||||||
|
Err string `json:"error"`
|
||||||
|
}
|
||||||
|
@ -6,7 +6,6 @@ package api
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
@ -14,6 +13,7 @@ import (
|
|||||||
kithttp "github.com/go-kit/kit/transport/http"
|
kithttp "github.com/go-kit/kit/transport/http"
|
||||||
"github.com/go-zoo/bone"
|
"github.com/go-zoo/bone"
|
||||||
"github.com/mainflux/mainflux"
|
"github.com/mainflux/mainflux"
|
||||||
|
"github.com/mainflux/mainflux/errors"
|
||||||
"github.com/mainflux/mainflux/readers"
|
"github.com/mainflux/mainflux/readers"
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
@ -111,15 +111,22 @@ func encodeResponse(_ context.Context, w http.ResponseWriter, response interface
|
|||||||
}
|
}
|
||||||
|
|
||||||
func encodeError(_ context.Context, err error, w http.ResponseWriter) {
|
func encodeError(_ context.Context, err error, w http.ResponseWriter) {
|
||||||
switch err {
|
switch {
|
||||||
case nil:
|
case errors.Contains(err, nil):
|
||||||
case errInvalidRequest:
|
case errors.Contains(err, errInvalidRequest):
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
case errUnauthorizedAccess:
|
case errors.Contains(err, errUnauthorizedAccess):
|
||||||
w.WriteHeader(http.StatusForbidden)
|
w.WriteHeader(http.StatusForbidden)
|
||||||
default:
|
default:
|
||||||
w.WriteHeader(http.StatusInternalServerError)
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
|
errorVal, ok := err.(errors.Error)
|
||||||
|
if ok {
|
||||||
|
w.Header().Set("Content-Type", contentType)
|
||||||
|
if err := json.NewEncoder(w).Encode(errorRes{Err: errorVal.Msg()}); err != nil {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func authorize(r *http.Request, chanID string) error {
|
func authorize(r *http.Request, chanID string) error {
|
||||||
|
@ -7,10 +7,13 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/gocql/gocql"
|
"github.com/gocql/gocql"
|
||||||
|
"github.com/mainflux/mainflux/errors"
|
||||||
"github.com/mainflux/mainflux/readers"
|
"github.com/mainflux/mainflux/readers"
|
||||||
"github.com/mainflux/mainflux/transformers/senml"
|
"github.com/mainflux/mainflux/transformers/senml"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var errReadMessages = errors.New("faled to read messages from cassandra database")
|
||||||
|
|
||||||
var _ readers.MessageRepository = (*cassandraRepository)(nil)
|
var _ readers.MessageRepository = (*cassandraRepository)(nil)
|
||||||
|
|
||||||
type cassandraRepository struct {
|
type cassandraRepository struct {
|
||||||
@ -59,13 +62,13 @@ func (cr cassandraRepository) ReadAll(chanID string, offset, limit uint64, query
|
|||||||
&msg.Name, &msg.Unit, &msg.Value, &msg.StringValue, &msg.BoolValue,
|
&msg.Name, &msg.Unit, &msg.Value, &msg.StringValue, &msg.BoolValue,
|
||||||
&msg.DataValue, &msg.Sum, &msg.Time, &msg.UpdateTime)
|
&msg.DataValue, &msg.Sum, &msg.Time, &msg.UpdateTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return readers.MessagesPage{}, err
|
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||||
}
|
}
|
||||||
page.Messages = append(page.Messages, msg)
|
page.Messages = append(page.Messages, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := cr.session.Query(countCQL, vals[:len(vals)-1]...).Scan(&page.Total); err != nil {
|
if err := cr.session.Query(countCQL, vals[:len(vals)-1]...).Scan(&page.Total); err != nil {
|
||||||
return readers.MessagesPage{}, err
|
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return page, nil
|
return page, nil
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/mainflux/mainflux/errors"
|
||||||
"github.com/mainflux/mainflux/readers"
|
"github.com/mainflux/mainflux/readers"
|
||||||
|
|
||||||
influxdata "github.com/influxdata/influxdb/client/v2"
|
influxdata "github.com/influxdata/influxdb/client/v2"
|
||||||
@ -16,6 +17,8 @@ import (
|
|||||||
|
|
||||||
const countCol = "count"
|
const countCol = "count"
|
||||||
|
|
||||||
|
var errReadMessages = errors.New("faled to read messages from influxdb database")
|
||||||
|
|
||||||
var _ readers.MessageRepository = (*influxRepository)(nil)
|
var _ readers.MessageRepository = (*influxRepository)(nil)
|
||||||
|
|
||||||
type influxRepository struct {
|
type influxRepository struct {
|
||||||
@ -43,10 +46,10 @@ func (repo *influxRepository) ReadAll(chanID string, offset, limit uint64, query
|
|||||||
|
|
||||||
resp, err := repo.client.Query(q)
|
resp, err := repo.client.Query(q)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return readers.MessagesPage{}, err
|
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||||
}
|
}
|
||||||
if resp.Error() != nil {
|
if resp.Error() != nil {
|
||||||
return readers.MessagesPage{}, resp.Error()
|
return readers.MessagesPage{}, errors.Wrap(errReadMessages, resp.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(resp.Results) < 1 || len(resp.Results[0].Series) < 1 {
|
if len(resp.Results) < 1 || len(resp.Results[0].Series) < 1 {
|
||||||
@ -60,7 +63,7 @@ func (repo *influxRepository) ReadAll(chanID string, offset, limit uint64, query
|
|||||||
|
|
||||||
total, err := repo.count(condition)
|
total, err := repo.count(condition)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return readers.MessagesPage{}, err
|
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return readers.MessagesPage{
|
return readers.MessagesPage{
|
||||||
|
@ -6,6 +6,7 @@ package mongodb
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/mainflux/mainflux/errors"
|
||||||
"github.com/mainflux/mainflux/readers"
|
"github.com/mainflux/mainflux/readers"
|
||||||
"github.com/mainflux/mainflux/transformers/senml"
|
"github.com/mainflux/mainflux/transformers/senml"
|
||||||
"go.mongodb.org/mongo-driver/bson"
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
@ -15,6 +16,8 @@ import (
|
|||||||
|
|
||||||
const collection = "mainflux"
|
const collection = "mainflux"
|
||||||
|
|
||||||
|
var errReadMessages = errors.New("faled to read messages from mongodb database")
|
||||||
|
|
||||||
var _ readers.MessageRepository = (*mongoRepository)(nil)
|
var _ readers.MessageRepository = (*mongoRepository)(nil)
|
||||||
|
|
||||||
type mongoRepository struct {
|
type mongoRepository struct {
|
||||||
@ -54,7 +57,7 @@ func (repo mongoRepository) ReadAll(chanID string, offset, limit uint64, query m
|
|||||||
filter := fmtCondition(chanID, query)
|
filter := fmtCondition(chanID, query)
|
||||||
cursor, err := col.Find(context.Background(), filter, options.Find().SetSort(sortMap).SetLimit(int64(limit)).SetSkip(int64(offset)))
|
cursor, err := col.Find(context.Background(), filter, options.Find().SetSort(sortMap).SetLimit(int64(limit)).SetSkip(int64(offset)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return readers.MessagesPage{}, err
|
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||||
}
|
}
|
||||||
defer cursor.Close(context.Background())
|
defer cursor.Close(context.Background())
|
||||||
|
|
||||||
@ -62,7 +65,7 @@ func (repo mongoRepository) ReadAll(chanID string, offset, limit uint64, query m
|
|||||||
for cursor.Next(context.Background()) {
|
for cursor.Next(context.Background()) {
|
||||||
var m message
|
var m message
|
||||||
if err := cursor.Decode(&m); err != nil {
|
if err := cursor.Decode(&m); err != nil {
|
||||||
return readers.MessagesPage{}, err
|
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := senml.Message{
|
msg := senml.Message{
|
||||||
@ -93,7 +96,7 @@ func (repo mongoRepository) ReadAll(chanID string, offset, limit uint64, query m
|
|||||||
|
|
||||||
total, err := col.CountDocuments(context.Background(), filter)
|
total, err := col.CountDocuments(context.Background(), filter)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return readers.MessagesPage{}, err
|
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||||
}
|
}
|
||||||
if total < 0 {
|
if total < 0 {
|
||||||
return readers.MessagesPage{}, nil
|
return readers.MessagesPage{}, nil
|
||||||
|
@ -4,17 +4,17 @@
|
|||||||
package postgres
|
package postgres
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx" // required for DB access
|
"github.com/jmoiron/sqlx" // required for DB access
|
||||||
|
"github.com/mainflux/mainflux/errors"
|
||||||
"github.com/mainflux/mainflux/readers"
|
"github.com/mainflux/mainflux/readers"
|
||||||
"github.com/mainflux/mainflux/transformers/senml"
|
"github.com/mainflux/mainflux/transformers/senml"
|
||||||
)
|
)
|
||||||
|
|
||||||
const errInvalid = "invalid_text_representation"
|
const errInvalid = "invalid_text_representation"
|
||||||
|
|
||||||
var errInvalidMessage = errors.New("invalid message representation")
|
var errReadMessages = errors.New("faled to read messages from postgres database")
|
||||||
|
|
||||||
var _ readers.MessageRepository = (*postgresRepository)(nil)
|
var _ readers.MessageRepository = (*postgresRepository)(nil)
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ func (tr postgresRepository) ReadAll(chanID string, offset, limit uint64, query
|
|||||||
|
|
||||||
rows, err := tr.db.NamedQuery(q, params)
|
rows, err := tr.db.NamedQuery(q, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return readers.MessagesPage{}, err
|
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||||
}
|
}
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ func (tr postgresRepository) ReadAll(chanID string, offset, limit uint64, query
|
|||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
dbm := dbMessage{Channel: chanID}
|
dbm := dbMessage{Channel: chanID}
|
||||||
if err := rows.StructScan(&dbm); err != nil {
|
if err := rows.StructScan(&dbm); err != nil {
|
||||||
return readers.MessagesPage{}, err
|
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := toMessage(dbm)
|
msg := toMessage(dbm)
|
||||||
@ -74,7 +74,7 @@ func (tr postgresRepository) ReadAll(chanID string, offset, limit uint64, query
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := tr.db.QueryRow(q, qParams...).Scan(&page.Total); err != nil {
|
if err := tr.db.QueryRow(q, qParams...).Scan(&page.Total); err != nil {
|
||||||
return readers.MessagesPage{}, err
|
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return page, nil
|
return page, nil
|
||||||
|
@ -5,10 +5,16 @@ package senml
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/mainflux/mainflux/broker"
|
"github.com/mainflux/mainflux/broker"
|
||||||
|
"github.com/mainflux/mainflux/errors"
|
||||||
"github.com/mainflux/mainflux/transformers"
|
"github.com/mainflux/mainflux/transformers"
|
||||||
"github.com/mainflux/senml"
|
"github.com/mainflux/senml"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
errDecode = errors.New("failed to decode senml")
|
||||||
|
errNormalize = errors.New("faled to normalize senml")
|
||||||
|
)
|
||||||
|
|
||||||
var formats = map[string]senml.Format{
|
var formats = map[string]senml.Format{
|
||||||
JSON: senml.JSON,
|
JSON: senml.JSON,
|
||||||
CBOR: senml.CBOR,
|
CBOR: senml.CBOR,
|
||||||
@ -29,12 +35,12 @@ func (n transformer) Transform(msg broker.Message) (interface{}, error) {
|
|||||||
|
|
||||||
raw, err := senml.Decode(msg.Payload, format)
|
raw, err := senml.Decode(msg.Payload, format)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(errDecode, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
normalized, err := senml.Normalize(raw)
|
normalized, err := senml.Normalize(raw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(errNormalize, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
msgs := make([]Message, len(normalized.Records))
|
msgs := make([]Message, len(normalized.Records))
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/mainflux/mainflux/broker"
|
"github.com/mainflux/mainflux/broker"
|
||||||
|
"github.com/mainflux/mainflux/errors"
|
||||||
"github.com/mainflux/mainflux/transformers/senml"
|
"github.com/mainflux/mainflux/transformers/senml"
|
||||||
mfsenml "github.com/mainflux/senml"
|
mfsenml "github.com/mainflux/senml"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -102,6 +103,6 @@ func TestTransform(t *testing.T) {
|
|||||||
for _, tc := range cases {
|
for _, tc := range cases {
|
||||||
msgs, err := tr.Transform(tc.msg)
|
msgs, err := tr.Transform(tc.msg)
|
||||||
assert.Equal(t, tc.msgs, msgs, fmt.Sprintf("%s expected %v, got %v", tc.desc, tc.msgs, msgs))
|
assert.Equal(t, tc.msgs, msgs, fmt.Sprintf("%s expected %v, got %v", tc.desc, tc.msgs, msgs))
|
||||||
assert.Equal(t, tc.err, err, fmt.Sprintf("%s expected %s, got %s", tc.desc, tc.err, err))
|
assert.True(t, errors.Contains(err, tc.err), fmt.Sprintf("%s expected %s, got %s", tc.desc, tc.err, err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,13 @@ package cassandra
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gocql/gocql"
|
"github.com/gocql/gocql"
|
||||||
|
"github.com/mainflux/mainflux/errors"
|
||||||
"github.com/mainflux/mainflux/transformers/senml"
|
"github.com/mainflux/mainflux/transformers/senml"
|
||||||
"github.com/mainflux/mainflux/writers"
|
"github.com/mainflux/mainflux/writers"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var errSaveMessage = errors.New("faled to save message to cassandra database")
|
||||||
|
|
||||||
var _ writers.MessageRepository = (*cassandraRepository)(nil)
|
var _ writers.MessageRepository = (*cassandraRepository)(nil)
|
||||||
|
|
||||||
type cassandraRepository struct {
|
type cassandraRepository struct {
|
||||||
@ -32,7 +35,7 @@ func (cr *cassandraRepository) Save(messages ...senml.Message) error {
|
|||||||
msg.Protocol, msg.Name, msg.Unit, msg.Value, msg.StringValue,
|
msg.Protocol, msg.Name, msg.Unit, msg.Value, msg.StringValue,
|
||||||
msg.BoolValue, msg.DataValue, msg.Sum, msg.Time, msg.UpdateTime).Exec()
|
msg.BoolValue, msg.DataValue, msg.Sum, msg.Time, msg.UpdateTime).Exec()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(errSaveMessage, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/mainflux/mainflux/errors"
|
||||||
"github.com/mainflux/mainflux/transformers/senml"
|
"github.com/mainflux/mainflux/transformers/senml"
|
||||||
"github.com/mainflux/mainflux/writers"
|
"github.com/mainflux/mainflux/writers"
|
||||||
|
|
||||||
@ -16,6 +17,8 @@ import (
|
|||||||
|
|
||||||
const pointName = "messages"
|
const pointName = "messages"
|
||||||
|
|
||||||
|
var errSaveMessage = errors.New("faled to save message to influxdb database")
|
||||||
|
|
||||||
var _ writers.MessageRepository = (*influxRepo)(nil)
|
var _ writers.MessageRepository = (*influxRepo)(nil)
|
||||||
|
|
||||||
type influxRepo struct {
|
type influxRepo struct {
|
||||||
@ -39,7 +42,7 @@ func New(client influxdata.Client, database string) writers.MessageRepository {
|
|||||||
func (repo *influxRepo) Save(messages ...senml.Message) error {
|
func (repo *influxRepo) Save(messages ...senml.Message) error {
|
||||||
pts, err := influxdata.NewBatchPoints(repo.cfg)
|
pts, err := influxdata.NewBatchPoints(repo.cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(errSaveMessage, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, msg := range messages {
|
for _, msg := range messages {
|
||||||
@ -50,12 +53,14 @@ func (repo *influxRepo) Save(messages ...senml.Message) error {
|
|||||||
|
|
||||||
pt, err := influxdata.NewPoint(pointName, tgs, flds, t)
|
pt, err := influxdata.NewPoint(pointName, tgs, flds, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(errSaveMessage, err)
|
||||||
}
|
}
|
||||||
pts.AddPoint(pt)
|
pts.AddPoint(pt)
|
||||||
}
|
}
|
||||||
|
if err := repo.client.Write(pts); err != nil {
|
||||||
return repo.client.Write(pts)
|
return errors.Wrap(errSaveMessage, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (repo *influxRepo) tagsOf(msg *senml.Message) tags {
|
func (repo *influxRepo) tagsOf(msg *senml.Message) tags {
|
||||||
|
@ -8,12 +8,15 @@ import (
|
|||||||
|
|
||||||
"go.mongodb.org/mongo-driver/mongo"
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
|
||||||
|
"github.com/mainflux/mainflux/errors"
|
||||||
"github.com/mainflux/mainflux/transformers/senml"
|
"github.com/mainflux/mainflux/transformers/senml"
|
||||||
"github.com/mainflux/mainflux/writers"
|
"github.com/mainflux/mainflux/writers"
|
||||||
)
|
)
|
||||||
|
|
||||||
const collectionName string = "mainflux"
|
const collectionName string = "mainflux"
|
||||||
|
|
||||||
|
var errSaveMessage = errors.New("faled to save message to mongodb database")
|
||||||
|
|
||||||
var _ writers.MessageRepository = (*mongoRepo)(nil)
|
var _ writers.MessageRepository = (*mongoRepo)(nil)
|
||||||
|
|
||||||
type mongoRepo struct {
|
type mongoRepo struct {
|
||||||
@ -73,5 +76,8 @@ func (repo *mongoRepo) Save(messages ...senml.Message) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_, err := coll.InsertMany(context.Background(), msgs)
|
_, err := coll.InsertMany(context.Background(), msgs)
|
||||||
return err
|
if err != nil {
|
||||||
|
return errors.Wrap(errSaveMessage, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -5,21 +5,23 @@ package postgres
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/gofrs/uuid"
|
"github.com/gofrs/uuid"
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
"github.com/lib/pq" // required for DB access
|
"github.com/lib/pq" // required for DB access
|
||||||
|
"github.com/mainflux/mainflux/errors"
|
||||||
"github.com/mainflux/mainflux/transformers/senml"
|
"github.com/mainflux/mainflux/transformers/senml"
|
||||||
"github.com/mainflux/mainflux/writers"
|
"github.com/mainflux/mainflux/writers"
|
||||||
)
|
)
|
||||||
|
|
||||||
const errInvalid = "invalid_text_representation"
|
const errInvalid = "invalid_text_representation"
|
||||||
|
|
||||||
// ErrInvalidMessage indicates that service received message that
|
var (
|
||||||
// doesn't fit required format.
|
// ErrInvalidMessage indicates that service received message that
|
||||||
var ErrInvalidMessage = errors.New("invalid message representation")
|
// doesn't fit required format.
|
||||||
|
ErrInvalidMessage = errors.New("invalid message representation")
|
||||||
|
errSaveMessage = errors.New("faled to save message to postgress database")
|
||||||
|
)
|
||||||
|
|
||||||
var _ writers.MessageRepository = (*postgresRepo)(nil)
|
var _ writers.MessageRepository = (*postgresRepo)(nil)
|
||||||
|
|
||||||
@ -42,13 +44,13 @@ func (pr postgresRepo) Save(messages ...senml.Message) error {
|
|||||||
|
|
||||||
tx, err := pr.db.BeginTxx(context.Background(), nil)
|
tx, err := pr.db.BeginTxx(context.Background(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(errSaveMessage, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, msg := range messages {
|
for _, msg := range messages {
|
||||||
dbth, err := toDBMessage(msg)
|
dbth, err := toDBMessage(msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(errSaveMessage, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := tx.NamedExec(q, dbth); err != nil {
|
if _, err := tx.NamedExec(q, dbth); err != nil {
|
||||||
@ -56,15 +58,17 @@ func (pr postgresRepo) Save(messages ...senml.Message) error {
|
|||||||
if ok {
|
if ok {
|
||||||
switch pqErr.Code.Name() {
|
switch pqErr.Code.Name() {
|
||||||
case errInvalid:
|
case errInvalid:
|
||||||
return ErrInvalidMessage
|
return errors.Wrap(errSaveMessage, ErrInvalidMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return errors.Wrap(errSaveMessage, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if err := tx.Commit(); err != nil {
|
||||||
return tx.Commit()
|
return errors.Wrap(errSaveMessage, err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type dbMessage struct {
|
type dbMessage struct {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user