mirror of
https://github.com/mainflux/mainflux.git
synced 2025-04-26 13:48:53 +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 (
|
||||
svcName = "postgres-writer"
|
||||
svcName = "postgres-reader"
|
||||
sep = ","
|
||||
|
||||
defLogLevel = "error"
|
||||
@ -112,7 +112,7 @@ func main() {
|
||||
}()
|
||||
|
||||
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 {
|
||||
@ -213,14 +213,14 @@ func newService(db *sqlx.DB, logger logger.Logger) readers.MessageRepository {
|
||||
svc = api.MetricsMiddleware(
|
||||
svc,
|
||||
kitprometheus.NewCounterFrom(stdprometheus.CounterOpts{
|
||||
Namespace: "postgres",
|
||||
Subsystem: "message_writer",
|
||||
Namespace: svcName,
|
||||
Subsystem: "message_reader",
|
||||
Name: "request_count",
|
||||
Help: "Number of requests received.",
|
||||
}, []string{"method"}),
|
||||
kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
|
||||
Namespace: "postgres",
|
||||
Subsystem: "message_writer",
|
||||
Namespace: svcName,
|
||||
Subsystem: "message_reader",
|
||||
Name: "request_latency_microseconds",
|
||||
Help: "Total duration of requests in microseconds.",
|
||||
}, []string{"method"}),
|
||||
|
@ -30,7 +30,7 @@ const (
|
||||
defLogLevel = "error"
|
||||
defNatsURL = "nats://localhost:4222"
|
||||
defPort = "8180"
|
||||
defDBHost = "postgres"
|
||||
defDBHost = "localhost"
|
||||
defDBPort = "5432"
|
||||
defDBUser = "mainflux"
|
||||
defDBPass = "mainflux"
|
||||
@ -139,13 +139,13 @@ func newService(db *sqlx.DB, logger logger.Logger) writers.MessageRepository {
|
||||
svc = api.MetricsMiddleware(
|
||||
svc,
|
||||
kitprometheus.NewCounterFrom(stdprometheus.CounterOpts{
|
||||
Namespace: "postgres",
|
||||
Namespace: svcName,
|
||||
Subsystem: "message_writer",
|
||||
Name: "request_count",
|
||||
Help: "Number of requests received.",
|
||||
}, []string{"method"}),
|
||||
kitprometheus.NewSummaryFrom(stdprometheus.SummaryOpts{
|
||||
Namespace: "postgres",
|
||||
Namespace: svcName,
|
||||
Subsystem: "message_writer",
|
||||
Name: "request_latency_microseconds",
|
||||
Help: "Total duration of requests in microseconds.",
|
||||
|
@ -30,3 +30,7 @@ func (res pageRes) Code() int {
|
||||
func (res pageRes) Empty() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type errorRes struct {
|
||||
Err string `json:"error"`
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ package api
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
@ -14,6 +13,7 @@ import (
|
||||
kithttp "github.com/go-kit/kit/transport/http"
|
||||
"github.com/go-zoo/bone"
|
||||
"github.com/mainflux/mainflux"
|
||||
"github.com/mainflux/mainflux/errors"
|
||||
"github.com/mainflux/mainflux/readers"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"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) {
|
||||
switch err {
|
||||
case nil:
|
||||
case errInvalidRequest:
|
||||
switch {
|
||||
case errors.Contains(err, nil):
|
||||
case errors.Contains(err, errInvalidRequest):
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
case errUnauthorizedAccess:
|
||||
case errors.Contains(err, errUnauthorizedAccess):
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
default:
|
||||
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 {
|
||||
|
@ -7,10 +7,13 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gocql/gocql"
|
||||
"github.com/mainflux/mainflux/errors"
|
||||
"github.com/mainflux/mainflux/readers"
|
||||
"github.com/mainflux/mainflux/transformers/senml"
|
||||
)
|
||||
|
||||
var errReadMessages = errors.New("faled to read messages from cassandra database")
|
||||
|
||||
var _ readers.MessageRepository = (*cassandraRepository)(nil)
|
||||
|
||||
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.DataValue, &msg.Sum, &msg.Time, &msg.UpdateTime)
|
||||
if err != nil {
|
||||
return readers.MessagesPage{}, err
|
||||
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||
}
|
||||
page.Messages = append(page.Messages, msg)
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/mainflux/mainflux/errors"
|
||||
"github.com/mainflux/mainflux/readers"
|
||||
|
||||
influxdata "github.com/influxdata/influxdb/client/v2"
|
||||
@ -16,6 +17,8 @@ import (
|
||||
|
||||
const countCol = "count"
|
||||
|
||||
var errReadMessages = errors.New("faled to read messages from influxdb database")
|
||||
|
||||
var _ readers.MessageRepository = (*influxRepository)(nil)
|
||||
|
||||
type influxRepository struct {
|
||||
@ -43,10 +46,10 @@ func (repo *influxRepository) ReadAll(chanID string, offset, limit uint64, query
|
||||
|
||||
resp, err := repo.client.Query(q)
|
||||
if err != nil {
|
||||
return readers.MessagesPage{}, err
|
||||
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||
}
|
||||
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 {
|
||||
@ -60,7 +63,7 @@ func (repo *influxRepository) ReadAll(chanID string, offset, limit uint64, query
|
||||
|
||||
total, err := repo.count(condition)
|
||||
if err != nil {
|
||||
return readers.MessagesPage{}, err
|
||||
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||
}
|
||||
|
||||
return readers.MessagesPage{
|
||||
|
@ -6,6 +6,7 @@ package mongodb
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/mainflux/mainflux/errors"
|
||||
"github.com/mainflux/mainflux/readers"
|
||||
"github.com/mainflux/mainflux/transformers/senml"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
@ -15,6 +16,8 @@ import (
|
||||
|
||||
const collection = "mainflux"
|
||||
|
||||
var errReadMessages = errors.New("faled to read messages from mongodb database")
|
||||
|
||||
var _ readers.MessageRepository = (*mongoRepository)(nil)
|
||||
|
||||
type mongoRepository struct {
|
||||
@ -54,7 +57,7 @@ func (repo mongoRepository) ReadAll(chanID string, offset, limit uint64, query m
|
||||
filter := fmtCondition(chanID, query)
|
||||
cursor, err := col.Find(context.Background(), filter, options.Find().SetSort(sortMap).SetLimit(int64(limit)).SetSkip(int64(offset)))
|
||||
if err != nil {
|
||||
return readers.MessagesPage{}, err
|
||||
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||
}
|
||||
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()) {
|
||||
var m message
|
||||
if err := cursor.Decode(&m); err != nil {
|
||||
return readers.MessagesPage{}, err
|
||||
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return readers.MessagesPage{}, err
|
||||
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||
}
|
||||
if total < 0 {
|
||||
return readers.MessagesPage{}, nil
|
||||
|
@ -4,17 +4,17 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/jmoiron/sqlx" // required for DB access
|
||||
"github.com/mainflux/mainflux/errors"
|
||||
"github.com/mainflux/mainflux/readers"
|
||||
"github.com/mainflux/mainflux/transformers/senml"
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
@ -46,7 +46,7 @@ func (tr postgresRepository) ReadAll(chanID string, offset, limit uint64, query
|
||||
|
||||
rows, err := tr.db.NamedQuery(q, params)
|
||||
if err != nil {
|
||||
return readers.MessagesPage{}, err
|
||||
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
@ -58,7 +58,7 @@ func (tr postgresRepository) ReadAll(chanID string, offset, limit uint64, query
|
||||
for rows.Next() {
|
||||
dbm := dbMessage{Channel: chanID}
|
||||
if err := rows.StructScan(&dbm); err != nil {
|
||||
return readers.MessagesPage{}, err
|
||||
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||
}
|
||||
|
||||
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 {
|
||||
return readers.MessagesPage{}, err
|
||||
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
|
||||
}
|
||||
|
||||
return page, nil
|
||||
|
@ -5,10 +5,16 @@ package senml
|
||||
|
||||
import (
|
||||
"github.com/mainflux/mainflux/broker"
|
||||
"github.com/mainflux/mainflux/errors"
|
||||
"github.com/mainflux/mainflux/transformers"
|
||||
"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{
|
||||
JSON: senml.JSON,
|
||||
CBOR: senml.CBOR,
|
||||
@ -29,12 +35,12 @@ func (n transformer) Transform(msg broker.Message) (interface{}, error) {
|
||||
|
||||
raw, err := senml.Decode(msg.Payload, format)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(errDecode, err)
|
||||
}
|
||||
|
||||
normalized, err := senml.Normalize(raw)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(errNormalize, err)
|
||||
}
|
||||
|
||||
msgs := make([]Message, len(normalized.Records))
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/mainflux/mainflux/broker"
|
||||
"github.com/mainflux/mainflux/errors"
|
||||
"github.com/mainflux/mainflux/transformers/senml"
|
||||
mfsenml "github.com/mainflux/senml"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@ -102,6 +103,6 @@ func TestTransform(t *testing.T) {
|
||||
for _, tc := range cases {
|
||||
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.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 (
|
||||
"github.com/gocql/gocql"
|
||||
"github.com/mainflux/mainflux/errors"
|
||||
"github.com/mainflux/mainflux/transformers/senml"
|
||||
"github.com/mainflux/mainflux/writers"
|
||||
)
|
||||
|
||||
var errSaveMessage = errors.New("faled to save message to cassandra database")
|
||||
|
||||
var _ writers.MessageRepository = (*cassandraRepository)(nil)
|
||||
|
||||
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.BoolValue, msg.DataValue, msg.Sum, msg.Time, msg.UpdateTime).Exec()
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(errSaveMessage, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/mainflux/mainflux/errors"
|
||||
"github.com/mainflux/mainflux/transformers/senml"
|
||||
"github.com/mainflux/mainflux/writers"
|
||||
|
||||
@ -16,6 +17,8 @@ import (
|
||||
|
||||
const pointName = "messages"
|
||||
|
||||
var errSaveMessage = errors.New("faled to save message to influxdb database")
|
||||
|
||||
var _ writers.MessageRepository = (*influxRepo)(nil)
|
||||
|
||||
type influxRepo struct {
|
||||
@ -39,7 +42,7 @@ func New(client influxdata.Client, database string) writers.MessageRepository {
|
||||
func (repo *influxRepo) Save(messages ...senml.Message) error {
|
||||
pts, err := influxdata.NewBatchPoints(repo.cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(errSaveMessage, err)
|
||||
}
|
||||
|
||||
for _, msg := range messages {
|
||||
@ -50,12 +53,14 @@ func (repo *influxRepo) Save(messages ...senml.Message) error {
|
||||
|
||||
pt, err := influxdata.NewPoint(pointName, tgs, flds, t)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(errSaveMessage, err)
|
||||
}
|
||||
pts.AddPoint(pt)
|
||||
}
|
||||
|
||||
return repo.client.Write(pts)
|
||||
if err := repo.client.Write(pts); err != nil {
|
||||
return errors.Wrap(errSaveMessage, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (repo *influxRepo) tagsOf(msg *senml.Message) tags {
|
||||
|
@ -8,12 +8,15 @@ import (
|
||||
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
|
||||
"github.com/mainflux/mainflux/errors"
|
||||
"github.com/mainflux/mainflux/transformers/senml"
|
||||
"github.com/mainflux/mainflux/writers"
|
||||
)
|
||||
|
||||
const collectionName string = "mainflux"
|
||||
|
||||
var errSaveMessage = errors.New("faled to save message to mongodb database")
|
||||
|
||||
var _ writers.MessageRepository = (*mongoRepo)(nil)
|
||||
|
||||
type mongoRepo struct {
|
||||
@ -73,5 +76,8 @@ func (repo *mongoRepo) Save(messages ...senml.Message) error {
|
||||
}
|
||||
|
||||
_, 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 (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/gofrs/uuid"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/lib/pq" // required for DB access
|
||||
"github.com/mainflux/mainflux/errors"
|
||||
"github.com/mainflux/mainflux/transformers/senml"
|
||||
"github.com/mainflux/mainflux/writers"
|
||||
)
|
||||
|
||||
const errInvalid = "invalid_text_representation"
|
||||
|
||||
// ErrInvalidMessage indicates that service received message that
|
||||
// doesn't fit required format.
|
||||
var ErrInvalidMessage = errors.New("invalid message representation")
|
||||
var (
|
||||
// ErrInvalidMessage indicates that service received message that
|
||||
// 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)
|
||||
|
||||
@ -42,13 +44,13 @@ func (pr postgresRepo) Save(messages ...senml.Message) error {
|
||||
|
||||
tx, err := pr.db.BeginTxx(context.Background(), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(errSaveMessage, err)
|
||||
}
|
||||
|
||||
for _, msg := range messages {
|
||||
dbth, err := toDBMessage(msg)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(errSaveMessage, err)
|
||||
}
|
||||
|
||||
if _, err := tx.NamedExec(q, dbth); err != nil {
|
||||
@ -56,15 +58,17 @@ func (pr postgresRepo) Save(messages ...senml.Message) error {
|
||||
if ok {
|
||||
switch pqErr.Code.Name() {
|
||||
case errInvalid:
|
||||
return ErrInvalidMessage
|
||||
return errors.Wrap(errSaveMessage, ErrInvalidMessage)
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
return errors.Wrap(errSaveMessage, err)
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
if err := tx.Commit(); err != nil {
|
||||
return errors.Wrap(errSaveMessage, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type dbMessage struct {
|
||||
|
Loading…
x
Reference in New Issue
Block a user