Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MF-1264 - Add support for JSON readers #1295

Merged
merged 19 commits into from
Dec 30, 2020
Merged

Conversation

dborovcanin
Copy link
Collaborator

@dborovcanin dborovcanin commented Nov 30, 2020

Signed-off-by: dusanb94 dusan.borovcanin@mainflux.com

What does this do?

This pull request updates the Mainflux Readers interface to match recently added support for storing arbitrary JSON data.

Which issue(s) does this PR fix/relate to?

Resolves #1264.

List any changes that modify/break current functionality

There are no breaking changes.

Have you included tests for your changes?

No. Existing tests are fixed, but new tests for reading data in a format other than SenML need to be added.

Did you document any new/modified functionality?

No. The existing documentation is sufficient at the moment.

@codecov-io
Copy link

codecov-io commented Nov 30, 2020

Codecov Report

Merging #1295 (ac754e5) into master (47217cb) will decrease coverage by 1.15%.
The diff coverage is 44.55%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1295      +/-   ##
==========================================
- Coverage   60.97%   59.81%   -1.16%     
==========================================
  Files         110      113       +3     
  Lines        8581     8797     +216     
==========================================
+ Hits         5232     5262      +30     
- Misses       2904     3078     +174     
- Partials      445      457      +12     
Impacted Files Coverage Δ
readers/api/responses.go 100.00% <ø> (ø)
writers/cassandra/init.go 66.66% <ø> (ø)
writers/postgres/messages.go 16.34% <13.58%> (-36.49%) ⬇️
writers/cassandra/messages.go 34.14% <21.87%> (-49.19%) ⬇️
writers/influxdb/messages.go 43.24% <30.76%> (-25.99%) ⬇️
readers/cassandra/messages.go 57.33% <34.88%> (-28.72%) ⬇️
readers/postgres/messages.go 58.82% <40.00%> (-31.01%) ⬇️
writers/mongodb/messages.go 43.47% <47.36%> (-26.90%) ⬇️
readers/mongodb/messages.go 69.56% <52.94%> (-15.35%) ⬇️
writers/influxdb/tags.go 55.55% <55.55%> (ø)
... and 8 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 47217cb...ac754e5. Read the comment docs.

@dborovcanin dborovcanin changed the base branch from json to master December 28, 2020 17:52
@dborovcanin dborovcanin changed the title NOISSUE - Fix Readers to match Writers interface MF-1264 - Add support for JSON readers Dec 28, 2020
@dborovcanin dborovcanin marked this pull request as ready for review December 28, 2020 23:45
@dborovcanin dborovcanin requested a review from a team as a code owner December 28, 2020 23:45
drasko
drasko previously approved these changes Dec 29, 2020
Copy link
Contributor

@drasko drasko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

if err := cursor.Decode(&m); err != nil {
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
messages := []interface{}{}
// var m interface{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove the comment please

var m message
if err := cursor.Decode(&m); err != nil {
return readers.MessagesPage{}, errors.Wrap(errReadMessages, err)
messages := []interface{}{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use var messages []interface{} here?


assert.Equal(t, tc.page.Total, result.Total, fmt.Sprintf("%s: expected %d got %d", desc, tc.page.Total, result.Total))
}
}

func fromSenml(in []senml.Message) []interface{} {
ret := []interface{}{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

var ret []interface{} ?

@@ -54,7 +54,7 @@ services:
networks:
- docker_mainflux-base-net
volumes:
- ./subjects.toml:/config/subjects.toml
- ./config.toml:/config.toml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this path ok?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, because the path is changed from /config to the root (/).

manuio
manuio previously requested changes Dec 29, 2020
pkg/transformers/json/transformer.go Show resolved Hide resolved
@@ -114,3 +137,33 @@ func buildCountQuery(chanID string, names []string) string {

return fmt.Sprintf(cql, condCQL)
}

func parseFlat(flat interface{}) interface{} {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this function is duplicated for each reader. Should we maybe export it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'll probably put it in the transformers/json as a utility function.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe transformers/pkg as shared package? Its oft to have multiple pkg and internal (not just in root).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I put it in pkg/tranformers/json. It's a utility function used by JSON transformer and readers, so I guess it's OK to leave it there.

if len(subs) == 0 {
return nil, errors.Wrap(ErrTransform, errUnknownFormat)
}
format := subs[len(subs)-1]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if len == 1?

Copy link
Collaborator Author

@dborovcanin dborovcanin Dec 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will take the first element of the subtopics slice.


func flatten(prefix string, m, m1 map[string]interface{}) (map[string]interface{}, error) {
for k, v := range m1 {
if k == "publisher" || k == "protocol" || k == "channel" || k == "subtopic" || strings.Contains(k, sep) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we make appropriate constants for this?

@@ -3,7 +3,9 @@

package transformers

import "github.com/mainflux/mainflux/pkg/messaging"
import (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

single import

WHERE %s ORDER BY time DESC
LIMIT :limit OFFSET :offset;`, fmtCondition(chanID, query))
LIMIT :limit OFFSET :offset;`, format, fmtCondition(chanID, query))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idedntation doesnt seem right here

switch format {
case defTable:
for rows.Next() {
msg := dbMessage{Message: senml.Message{Channel: chanID}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you sure this works? Channel doesnt get overwritten?

@@ -3,9 +3,12 @@

package cassandra

import "github.com/gocql/gocql"
import (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

single import

name, unit, value, string_value, bool_value, data_value, sum,
time, update_time)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
name, unit, value, string_value, bool_value, data_value, sum,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

identation

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're using spaces, it's probably just an issue with the preview.

q := influxdata.Query{
Command: cmd,
Database: repo.database,
}

ret := []senml.Message{}
ret := []interface{}{}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we create custom type on domain level, like in transformers and use it like []MsgPaylod ? With probably better naming :)

pkg/transformers/json/example_test.go Show resolved Hide resolved
pkg/transformers/json/example_test.go Show resolved Hide resolved
const (
countCol = "count_protocol"
format = "format"
defMeasurement = "messages"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a bit unclear (at least from the naming itself) what defMeasurement represents, maybe leave a short comment here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's basically the measurement / table / collection for SenML messages. It's called messages for the sake of backward compatibility.

assert.Nil(t, err, fmt.Sprintf("%s: expected no error got %s", desc, err))
assert.ElementsMatch(t, tc.page.Messages, result.Messages, fmt.Sprintf("%s: expected %v got %v", desc, tc.page.Messages, result.Messages))
assert.Equal(t, tc.page.Total, result.Total, fmt.Sprintf("%s: expected %v got %v", desc, tc.page.Total, result.Total))
}
}

func fromSenml(in []senml.Message) []interface{} {
ret := []interface{}{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe var ret []interface{} here as well? I am not bothered with this one neither, but if I remember well we aligned to a previous definition before. Please compare and align to the code in other Mainflux services.

"github.com/mainflux/mainflux/pkg/transformers/senml"
"github.com/mainflux/mainflux/readers"
)

const errInvalid = "invalid_text_representation"

const (
format = "format"
defTable = "messages"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, maybe small comment for a code reader.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although here is really looks like you are using def for default, and maybe comment is not necessary.

@@ -168,3 +168,11 @@ func TestMessageReadAll(t *testing.T) {
assert.Equal(t, tc.page.Total, result.Total, fmt.Sprintf("%s: expected %v got %v", desc, tc.page.Total, result.Total))
}
}

func fromSenml(in []senml.Message) []interface{} {
ret := []interface{}{}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here - variable definition.

drasko
drasko previously approved these changes Dec 29, 2020
Copy link
Contributor

@drasko drasko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

manuio and others added 18 commits December 30, 2020 12:45
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>

// Messages represents a list of JSON messages.
type Messages struct {
Messages []Message
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit eye-catchy Messages.Messages, maybe Messages.List or Messages.Data or something like that. Detail.

Signed-off-by: dusanb94 <dusan.borovcanin@mainflux.com>
@drasko drasko dismissed manuio’s stale review December 30, 2020 14:42

Change was done.

@drasko drasko merged commit e326494 into absmach:master Dec 30, 2020
@dborovcanin dborovcanin deleted the json branch July 21, 2021 14:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add support for JSON readers
6 participants