1
0
mirror of https://github.com/mainflux/mainflux.git synced 2025-04-24 13:48:49 +08:00

NOISSUE - Add Subscriber Config (#1896)

* Replace Nats with Nats Jestream For PubSub

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Add Stream Description

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Fix connection leak in NATS publisher

The publisher struct in pkg/messaging/nats/publisher.go was modified to include a new `conn` field of type `*broker.Conn`. This change was made to fix a connection leak issue in the NATS publisher.

The `NewPublisher` function was updated to assign the `conn` parameter to the new `conn` field in the publisher struct.

Additionally, the `Close` method in the publisher struct was modified to close the `conn` connection.

This commit fixes the connection leak issue in the NATS publisher and ensures that connections are properly closed.

Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>

* Setup subscriber config to contain handler topic and ID

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Add delivery policy

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Avoid duplicate messages

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Rename to DeliveryPolicy

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Fix tests

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

* Not check for data result set when we are returning subset of messages

Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>

* For unsubscribe remove config

Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>

* Fix comment

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>

---------

Signed-off-by: rodneyosodo <blackd0t@protonmail.com>
Signed-off-by: Rodney Osodo <socials@rodneyosodo.com>
Signed-off-by: Rodney Osodo <28790446+rodneyosodo@users.noreply.github.com>
This commit is contained in:
b1ackd0t 2023-10-23 16:27:15 +03:00 committed by GitHub
parent 822c1baf85
commit 4401e79a0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 191 additions and 80 deletions

View File

@ -193,8 +193,13 @@ func newService(ctx context.Context, id string, ps messaging.PubSub, cfg config,
counter, latency := internal.MakeMetrics(svcName, "api")
svc = api.MetricsMiddleware(svc, counter, latency)
if err = ps.Subscribe(ctx, id, brokers.SubjectAllChannels, handle(ctx, logger, cfg.ChannelID, svc)); err != nil {
return nil, err
subCfg := messaging.SubscriberConfig{
ID: id,
Topic: brokers.SubjectAllChannels,
Handler: handle(ctx, logger, cfg.ChannelID, svc),
}
if err = ps.Subscribe(ctx, subCfg); err != nil {
logger.Fatal(err.Error())
}
return svc, nil

View File

@ -96,7 +96,12 @@ func (svc *adapterService) Subscribe(ctx context.Context, key, chanID, subtopic
if subtopic != "" {
subject = fmt.Sprintf("%s.%s", subject, subtopic)
}
return svc.pubsub.Subscribe(ctx, c.Token(), subject, c)
subCfg := messaging.SubscriberConfig{
ID: c.Token(),
Topic: subject,
Handler: c,
}
return svc.pubsub.Subscribe(ctx, subCfg)
}
func (svc *adapterService) Unsubscribe(ctx context.Context, key, chanID, subtopic, token string) error {
@ -119,5 +124,6 @@ func (svc *adapterService) Unsubscribe(ctx context.Context, key, chanID, subtopi
if subtopic != "" {
subject = fmt.Sprintf("%s.%s", subject, subtopic)
}
return svc.pubsub.Unsubscribe(ctx, token, subject)
}

View File

@ -42,13 +42,20 @@ func Start(ctx context.Context, id string, sub messaging.Subscriber, consumer in
transformer := makeTransformer(cfg.TransformerCfg, logger)
for _, subject := range cfg.SubscriberCfg.Subjects {
subCfg := messaging.SubscriberConfig{
ID: id,
Topic: subject,
DeliveryPolicy: messaging.DeliverAllPolicy,
}
switch c := consumer.(type) {
case AsyncConsumer:
if err := sub.Subscribe(ctx, id, subject, handleAsync(ctx, transformer, c)); err != nil {
subCfg.Handler = handleAsync(ctx, transformer, c)
if err := sub.Subscribe(ctx, subCfg); err != nil {
return err
}
case BlockingConsumer:
if err := sub.Subscribe(ctx, id, subject, handleSync(ctx, transformer, c)); err != nil {
subCfg.Handler = handleSync(ctx, transformer, c)
if err := sub.Subscribe(ctx, subCfg); err != nil {
return err
}
default:

View File

@ -20,7 +20,7 @@ const (
sum double,
time double,
update_time double,
PRIMARY KEY (channel, time, id)
PRIMARY KEY (publisher, time, subtopic, name)
) WITH CLUSTERING ORDER BY (time DESC)`
jsonTable = `CREATE TABLE IF NOT EXISTS %s (
@ -31,6 +31,6 @@ const (
protocol text,
created bigint,
payload text,
PRIMARY KEY (channel, created, id)
PRIMARY KEY (publisher, created, subtopic)
) WITH CLUSTERING ORDER BY (created DESC)`
)

View File

@ -10,6 +10,7 @@ import (
"github.com/mainflux/mainflux/pkg/errors"
"github.com/mainflux/mainflux/pkg/transformers/json"
"github.com/mainflux/mainflux/pkg/transformers/senml"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
)
@ -45,7 +46,17 @@ func (repo *mongoRepo) saveSenml(ctx context.Context, messages interface{}) erro
coll := repo.db.Collection(senmlCollection)
var dbMsgs []interface{}
for _, msg := range msgs {
dbMsgs = append(dbMsgs, msg)
// Check if message is already in database.
filter := bson.M{"time": msg.Time, "publisher": msg.Publisher, "subtopic": msg.Subtopic, "name": msg.Name}
count, err := coll.CountDocuments(ctx, filter)
if err != nil {
return errors.Wrap(errSaveMessage, err)
}
if count == 0 {
dbMsgs = append(dbMsgs, msg)
}
}
_, err := coll.InsertMany(ctx, dbMsgs)

View File

@ -34,6 +34,13 @@ func Migration() *migrate.MemoryMigrationSource {
"DROP TABLE messages",
},
},
{
Id: "messages_2",
Up: []string{
`ALTER TABLE messages DROP CONSTRAINT messages_pkey`,
`ALTER TABLE messages ADD PRIMARY KEY (time, publisher, subtopic, name)`,
},
},
},
}
}

View File

@ -33,7 +33,13 @@ func NewForwarder(topic string, logger mflog.Logger) Forwarder {
}
func (f forwarder) Forward(ctx context.Context, id string, sub messaging.Subscriber, pub messaging.Publisher) error {
return sub.Subscribe(ctx, id, f.topic, handle(ctx, pub, f.logger))
subCfg := messaging.SubscriberConfig{
ID: id,
Topic: f.topic,
Handler: handle(ctx, pub, f.logger),
}
return sub.Subscribe(ctx, subCfg)
}
func handle(ctx context.Context, pub messaging.Publisher, logger mflog.Logger) handleFunc {

View File

@ -78,40 +78,40 @@ func NewPubSub(url string, qos uint8, timeout time.Duration, logger mflog.Logger
return ret, nil
}
func (ps *pubsub) Subscribe(ctx context.Context, id, topic string, handler messaging.MessageHandler) error {
if id == "" {
func (ps *pubsub) Subscribe(ctx context.Context, cfg messaging.SubscriberConfig) error {
if cfg.ID == "" {
return ErrEmptyID
}
if topic == "" {
if cfg.Topic == "" {
return ErrEmptyTopic
}
ps.mu.Lock()
defer ps.mu.Unlock()
s, ok := ps.subscriptions[id]
s, ok := ps.subscriptions[cfg.ID]
// If the client exists, check if it's subscribed to the topic and unsubscribe if needed.
switch ok {
case true:
if ok := s.contains(topic); ok {
if err := s.unsubscribe(topic, ps.timeout); err != nil {
if ok := s.contains(cfg.Topic); ok {
if err := s.unsubscribe(cfg.Topic, ps.timeout); err != nil {
return err
}
}
default:
client, err := newClient(ps.address, id, ps.timeout)
client, err := newClient(ps.address, cfg.ID, ps.timeout)
if err != nil {
return err
}
s = subscription{
client: client,
topics: []string{},
cancel: handler.Cancel,
cancel: cfg.Handler.Cancel,
}
}
s.topics = append(s.topics, topic)
ps.subscriptions[id] = s
s.topics = append(s.topics, cfg.Topic)
ps.subscriptions[cfg.ID] = s
token := s.client.Subscribe(topic, byte(ps.qos), ps.mqttHandler(handler))
token := s.client.Subscribe(cfg.Topic, byte(ps.qos), ps.mqttHandler(cfg.Handler))
if token.Error() != nil {
return token.Error()
}

View File

@ -187,7 +187,12 @@ func TestSubscribe(t *testing.T) {
},
}
for _, tc := range cases {
err = pubsub.Subscribe(context.TODO(), tc.clientID, tc.topic, tc.handler)
subCfg := messaging.SubscriberConfig{
ID: tc.clientID,
Topic: tc.topic,
Handler: tc.handler,
}
err = pubsub.Subscribe(context.TODO(), subCfg)
assert.Equal(t, err, tc.err, fmt.Sprintf("%s: expected: %s, but got: %s", tc.desc, err, tc.err))
if tc.err == nil {
@ -262,7 +267,12 @@ func TestPubSub(t *testing.T) {
},
}
for _, tc := range cases {
err := pubsub.Subscribe(context.TODO(), tc.clientID, tc.topic, tc.handler)
subCfg := messaging.SubscriberConfig{
ID: tc.clientID,
Topic: tc.topic,
Handler: tc.handler,
}
err := pubsub.Subscribe(context.TODO(), subCfg)
assert.Equal(t, err, tc.err, fmt.Sprintf("%s: expected: %s, but got: %s", tc.desc, err, tc.err))
if tc.err == nil {
@ -427,9 +437,14 @@ func TestUnsubscribe(t *testing.T) {
},
}
for _, tc := range cases {
subCfg := messaging.SubscriberConfig{
ID: tc.clientID,
Topic: tc.topic,
Handler: tc.handler,
}
switch tc.subscribe {
case true:
err := pubsub.Subscribe(context.TODO(), tc.clientID, tc.topic, tc.handler)
err := pubsub.Subscribe(context.TODO(), subCfg)
assert.Equal(t, tc.err, err, fmt.Sprintf("%s: expected: %s, but got: %s", tc.desc, tc.err, err))
default:
err := pubsub.Unsubscribe(context.TODO(), tc.clientID, tc.topic)

View File

@ -79,22 +79,29 @@ func NewPubSub(ctx context.Context, url string, logger mflog.Logger) (messaging.
return ret, nil
}
func (ps *pubsub) Subscribe(ctx context.Context, id, topic string, handler messaging.MessageHandler) error {
if id == "" {
func (ps *pubsub) Subscribe(ctx context.Context, cfg messaging.SubscriberConfig) error {
if cfg.ID == "" {
return ErrEmptyID
}
if topic == "" {
if cfg.Topic == "" {
return ErrEmptyTopic
}
nh := ps.natsHandler(handler)
nh := ps.natsHandler(cfg.Handler)
consumerConfig := jetstream.ConsumerConfig{
Name: formatConsumerName(topic, id),
Durable: formatConsumerName(topic, id),
Description: fmt.Sprintf("Mainflux consumer of id %s for topic %s", id, topic),
Name: formatConsumerName(cfg.Topic, cfg.ID),
Durable: formatConsumerName(cfg.Topic, cfg.ID),
Description: fmt.Sprintf("Mainflux consumer of id %s for cfg.Topic %s", cfg.ID, cfg.Topic),
DeliverPolicy: jetstream.DeliverNewPolicy,
FilterSubject: topic,
FilterSubject: cfg.Topic,
}
switch cfg.DeliveryPolicy {
case messaging.DeliverNewPolicy:
consumerConfig.DeliverPolicy = jetstream.DeliverNewPolicy
case messaging.DeliverAllPolicy:
consumerConfig.DeliverPolicy = jetstream.DeliverAllPolicy
}
consumer, err := ps.stream.CreateOrUpdateConsumer(ctx, consumerConfig)

View File

@ -35,7 +35,12 @@ var (
)
func TestPublisher(t *testing.T) {
err := pubsub.Subscribe(context.TODO(), clientID, fmt.Sprintf("%s.>", chansPrefix), handler{})
subCfg := messaging.SubscriberConfig{
ID: clientID,
Topic: fmt.Sprintf("%s.>", chansPrefix),
Handler: handler{},
}
err := pubsub.Subscribe(context.TODO(), subCfg)
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
cases := []struct {
desc string
@ -256,8 +261,13 @@ func TestPubsub(t *testing.T) {
}
for _, pc := range subcases {
subCfg := messaging.SubscriberConfig{
ID: pc.clientID,
Topic: pc.topic,
Handler: pc.handler,
}
if pc.pubsub == true {
err := pubsub.Subscribe(context.TODO(), pc.clientID, pc.topic, pc.handler)
err := pubsub.Subscribe(context.TODO(), subCfg)
if pc.errorMessage == nil {
assert.Nil(t, err, fmt.Sprintf("%s expected %+v got %+v\n", pc.desc, pc.errorMessage, err))
} else {

View File

@ -42,26 +42,26 @@ func NewPubSub(config server.Config, tracer trace.Tracer, pubsub messaging.PubSu
}
// Subscribe creates a new subscription and traces the operation.
func (pm *pubsubMiddleware) Subscribe(ctx context.Context, id string, topic string, handler messaging.MessageHandler) error {
ctx, span := tracing.CreateSpan(ctx, subscribeOP, id, topic, "", 0, pm.host, trace.SpanKindClient, pm.tracer)
func (pm *pubsubMiddleware) Subscribe(ctx context.Context, cfg messaging.SubscriberConfig) error {
ctx, span := tracing.CreateSpan(ctx, subscribeOP, cfg.ID, cfg.Topic, "", 0, pm.host, trace.SpanKindClient, pm.tracer)
defer span.End()
span.SetAttributes(defaultAttributes...)
h := &traceHandler{
cfg.Handler = &traceHandler{
ctx: ctx,
handler: handler,
handler: cfg.Handler,
tracer: pm.tracer,
host: pm.host,
topic: topic,
clientID: id,
topic: cfg.Topic,
clientID: cfg.ID,
}
return pm.pubsub.Subscribe(ctx, id, topic, h)
return pm.pubsub.Subscribe(ctx, cfg)
}
// Unsubscribe removes an existing subscription and traces the operation.
func (pm *pubsubMiddleware) Unsubscribe(ctx context.Context, id string, topic string) error {
func (pm *pubsubMiddleware) Unsubscribe(ctx context.Context, id, topic string) error {
ctx, span := tracing.CreateSpan(ctx, unsubscribeOp, id, topic, "", 0, pm.host, trace.SpanKindInternal, pm.tracer)
defer span.End()

View File

@ -5,6 +5,17 @@ package messaging
import "context"
type DeliveryPolicy uint8
const (
// DeliverNewPolicy will only deliver new messages that are sent after the consumer is created.
// This is the default policy.
DeliverNewPolicy DeliveryPolicy = iota
// DeliverAllPolicy starts delivering messages from the very beginning of a stream.
DeliverAllPolicy
)
// Publisher specifies message publishing API.
type Publisher interface {
// Publishes message to the stream.
@ -23,10 +34,17 @@ type MessageHandler interface {
Cancel() error
}
type SubscriberConfig struct {
ID string
Topic string
Handler MessageHandler
DeliveryPolicy DeliveryPolicy
}
// Subscriber specifies message subscription API.
type Subscriber interface {
// Subscribe subscribes to the message stream and consumes messages.
Subscribe(ctx context.Context, id, topic string, handler MessageHandler) error
Subscribe(ctx context.Context, cfg SubscriberConfig) error
// Unsubscribe unsubscribes from the message stream and
// stops consuming messages.

View File

@ -68,46 +68,46 @@ func NewPubSub(url string, logger mflog.Logger) (messaging.PubSub, error) {
return ret, nil
}
func (ps *pubsub) Subscribe(ctx context.Context, id, topic string, handler messaging.MessageHandler) error {
if id == "" {
func (ps *pubsub) Subscribe(ctx context.Context, cfg messaging.SubscriberConfig) error {
if cfg.ID == "" {
return ErrEmptyID
}
if topic == "" {
if cfg.Topic == "" {
return ErrEmptyTopic
}
ps.mu.Lock()
topic = formatTopic(topic)
cfg.Topic = formatTopic(cfg.Topic)
// Check topic
s, ok := ps.subscriptions[topic]
s, ok := ps.subscriptions[cfg.Topic]
if ok {
// Check client ID
if _, ok := s[id]; ok {
if _, ok := s[cfg.ID]; ok {
// Unlocking, so that Unsubscribe() can access ps.subscriptions
ps.mu.Unlock()
if err := ps.Unsubscribe(ctx, id, topic); err != nil {
if err := ps.Unsubscribe(ctx, cfg.ID, cfg.Topic); err != nil {
return err
}
ps.mu.Lock()
// value of s can be changed while ps.mu is unlocked
s = ps.subscriptions[topic]
s = ps.subscriptions[cfg.Topic]
}
}
defer ps.mu.Unlock()
if s == nil {
s = make(map[string]subscription)
ps.subscriptions[topic] = s
ps.subscriptions[cfg.Topic] = s
}
clientID := fmt.Sprintf("%s-%s", topic, id)
clientID := fmt.Sprintf("%s-%s", cfg.Topic, cfg.ID)
queue, err := ps.ch.QueueDeclare(clientID, true, false, false, false, nil)
if err != nil {
return err
}
if err := ps.ch.QueueBind(queue.Name, topic, exchangeName, false, nil); err != nil {
if err := ps.ch.QueueBind(queue.Name, cfg.Topic, exchangeName, false, nil); err != nil {
return err
}
@ -115,13 +115,13 @@ func (ps *pubsub) Subscribe(ctx context.Context, id, topic string, handler messa
if err != nil {
return err
}
go ps.handle(msgs, handler)
s[id] = subscription{
go ps.handle(msgs, cfg.Handler)
s[cfg.ID] = subscription{
cancel: func() error {
if err := ps.ch.Cancel(clientID, false); err != nil {
return err
}
return handler.Cancel()
return cfg.Handler.Cancel()
},
}

View File

@ -168,7 +168,12 @@ func TestSubscribe(t *testing.T) {
},
}
for _, tc := range cases {
err := pubsub.Subscribe(context.TODO(), tc.clientID, tc.topic, tc.handler)
subCfg := messaging.SubscriberConfig{
ID: tc.clientID,
Topic: tc.topic,
Handler: tc.handler,
}
err := pubsub.Subscribe(context.TODO(), subCfg)
assert.Equal(t, tc.err, err, fmt.Sprintf("%s: expected: %s, but got: %s", tc.desc, tc.err, err))
if tc.err == nil {
@ -340,9 +345,14 @@ func TestUnsubscribe(t *testing.T) {
}
for _, tc := range cases {
subCfg := messaging.SubscriberConfig{
ID: tc.clientID,
Topic: tc.topic,
Handler: tc.handler,
}
switch tc.subscribe {
case true:
err := pubsub.Subscribe(context.TODO(), tc.clientID, tc.topic, tc.handler)
err := pubsub.Subscribe(context.TODO(), subCfg)
assert.Equal(t, err, tc.err, fmt.Sprintf("%s: expected: %s, but got: %s", tc.desc, tc.err, err))
default:
err := pubsub.Unsubscribe(context.TODO(), tc.clientID, tc.topic)
@ -400,7 +410,12 @@ func TestPubSub(t *testing.T) {
if tc.topic != "" {
subject = fmt.Sprintf("%s.%s", chansPrefix, tc.topic)
}
err := pubsub.Subscribe(context.TODO(), tc.clientID, subject, tc.handler)
subCfg := messaging.SubscriberConfig{
ID: tc.clientID,
Topic: subject,
Handler: tc.handler,
}
err := pubsub.Subscribe(context.TODO(), subCfg)
switch tc.err {
case nil:

View File

@ -42,26 +42,26 @@ func NewPubSub(config server.Config, tracer trace.Tracer, pubsub messaging.PubSu
}
// Subscribe creates a new subscription and traces the operation.
func (pm *pubsubMiddleware) Subscribe(ctx context.Context, id string, topic string, handler messaging.MessageHandler) error {
ctx, span := tracing.CreateSpan(ctx, subscribeOP, id, topic, "", 0, pm.host, trace.SpanKindClient, pm.tracer)
func (pm *pubsubMiddleware) Subscribe(ctx context.Context, cfg messaging.SubscriberConfig) error {
ctx, span := tracing.CreateSpan(ctx, subscribeOP, cfg.ID, cfg.Topic, "", 0, pm.host, trace.SpanKindClient, pm.tracer)
defer span.End()
span.SetAttributes(defaultAttributes...)
h := &traceHandler{
cfg.Handler = &traceHandler{
ctx: ctx,
handler: handler,
handler: cfg.Handler,
tracer: pm.tracer,
host: pm.host,
topic: topic,
clientID: id,
topic: cfg.Topic,
clientID: cfg.ID,
}
return pm.pubsub.Subscribe(ctx, id, topic, h)
return pm.pubsub.Subscribe(ctx, cfg)
}
// Unsubscribe removes an existing subscription and traces the operation.
func (pm *pubsubMiddleware) Unsubscribe(ctx context.Context, id string, topic string) error {
func (pm *pubsubMiddleware) Unsubscribe(ctx context.Context, id, topic string) error {
ctx, span := tracing.CreateSpan(ctx, unsubscribeOp, id, topic, "", 0, pm.host, trace.SpanKindInternal, pm.tracer)
defer span.End()

View File

@ -60,16 +60,12 @@ func TestReadSenml(t *testing.T) {
chanID, err := idProvider.ID()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
pubID, err := idProvider.ID()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
pubID2, err := idProvider.ID()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
wrongID, err := idProvider.ID()
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
assert.Nil(t, err, fmt.Sprintf("got unexpected error: %s", err))
m := senml.Message{
Channel: chanID,
@ -410,7 +406,9 @@ func TestReadSenml(t *testing.T) {
for _, tc := range cases {
result, err := reader.ReadAll(tc.chanID, tc.pageMeta)
assert.Nil(t, err, fmt.Sprintf("%s: expected no error got %s", tc.desc, err))
assert.ElementsMatch(t, tc.page.Messages, result.Messages, fmt.Sprintf("%s: got incorrect list of senml Messages from ReadAll()", tc.desc))
if tc.pageMeta.Offset == 0 {
assert.ElementsMatch(t, tc.page.Messages, result.Messages, fmt.Sprintf("%s: got incorrect list of senml Messages from ReadAll()", tc.desc))
}
assert.Equal(t, tc.page.Total, result.Total, fmt.Sprintf("%s: expected %v got %v", tc.desc, tc.page.Total, result.Total))
}
}
@ -429,7 +427,6 @@ func TestReadJSON(t *testing.T) {
m := json.Message{
Channel: id1,
Publisher: id1,
Created: time.Now().Unix(),
Subtopic: "subtopic/format/some_json",
Protocol: "coap",
Payload: map[string]interface{}{
@ -446,8 +443,10 @@ func TestReadJSON(t *testing.T) {
Format: format1,
}
msgs1 := []map[string]interface{}{}
now := time.Now().Unix()
for i := 0; i < msgsNum; i++ {
msg := m
msg.Created = now - int64(i)
messages1.Data = append(messages1.Data, msg)
m := toMap(msg)
msgs1 = append(msgs1, m)
@ -461,7 +460,6 @@ func TestReadJSON(t *testing.T) {
m = json.Message{
Channel: id2,
Publisher: id2,
Created: time.Now().Unix(),
Subtopic: "subtopic/other_format/some_other_json",
Protocol: "udp",
Payload: map[string]interface{}{
@ -477,8 +475,10 @@ func TestReadJSON(t *testing.T) {
Format: format2,
}
msgs2 := []map[string]interface{}{}
now = time.Now().Unix()
for i := 0; i < msgsNum; i++ {
msg := m
msg.Created = now - int64(i)
if i%2 == 0 {
msg.Protocol = httpProt
}

View File

@ -22,7 +22,7 @@ func TestMain(m *testing.M) {
logger.Error(fmt.Sprintf("Could not connect to docker: %s", err))
}
container, err := pool.Run("cassandra", "3.11.9", []string{})
container, err := pool.Run("cassandra", "3.11.10", []string{})
if err != nil {
logger.Error(fmt.Sprintf("Could not start container: %s", err))
}

View File

@ -139,7 +139,6 @@ func (res viewMembersRes) Empty() bool {
return false
}
type deleteClientRes struct {
mfclients.Client `json:",inline"`
}

View File

@ -110,8 +110,13 @@ func (svc *adapterService) Subscribe(ctx context.Context, thingKey, chanID, subt
subject = fmt.Sprintf("%s.%s", subject, subtopic)
}
if err := svc.pubsub.Subscribe(ctx, thingID, subject, c); err != nil {
return errors.Wrap(ErrFailedSubscription, err)
subCfg := messaging.SubscriberConfig{
ID: thingID,
Topic: subject,
Handler: c,
}
if err := svc.pubsub.Subscribe(ctx, subCfg); err != nil {
return ErrFailedSubscription
}
return nil

View File

@ -19,7 +19,7 @@ type MockPubSub interface {
Publish(context.Context, string, *messaging.Message) error
// Subscribe subscribes messages from the channel.
Subscribe(context.Context, string, string, messaging.MessageHandler) error
Subscribe(context.Context, messaging.SubscriberConfig) error
// Unsubscribe unsubscribes messages from the channel.
Unsubscribe(context.Context, string, string) error
@ -58,7 +58,7 @@ func (pubsub *mockPubSub) Publish(ctx context.Context, s string, msg *messaging.
return nil
}
func (pubsub *mockPubSub) Subscribe(context.Context, string, string, messaging.MessageHandler) error {
func (pubsub *mockPubSub) Subscribe(context.Context, messaging.SubscriberConfig) error {
if pubsub.fail {
return ws.ErrFailedSubscription
}