From c94440235261b2c97d0fc0eb834e8abf86eb811e Mon Sep 17 00:00:00 2001 From: Denis Arh Date: Fri, 10 Jan 2020 10:00:35 +0100 Subject: [PATCH] Implement constraint checking for messaging events --- messaging/service/event/channel.go | 30 +++++++++----- messaging/service/event/channel_member.go | 24 +++++++----- .../service/event/channel_member_test.go | 27 +++++++++++++ messaging/service/event/command.go | 24 +++++++----- messaging/service/event/command_test.go | 30 ++++++++++++++ messaging/service/event/constraint.go | 9 ----- messaging/service/event/message.go | 26 ++++++++----- messaging/service/event/message_test.go | 28 +++++++++++++ messaging/service/event/messaging.go | 16 ++++---- messaging/service/event/messaging_test.go | 39 +++++++++++++++++++ 10 files changed, 200 insertions(+), 53 deletions(-) create mode 100644 messaging/service/event/channel_member_test.go create mode 100644 messaging/service/event/command_test.go delete mode 100644 messaging/service/event/constraint.go create mode 100644 messaging/service/event/message_test.go create mode 100644 messaging/service/event/messaging_test.go diff --git a/messaging/service/event/channel.go b/messaging/service/event/channel.go index 70bf2ebe5..96e6d779e 100644 --- a/messaging/service/event/channel.go +++ b/messaging/service/event/channel.go @@ -1,15 +1,27 @@ package event -import "github.com/cortezaproject/corteza-server/pkg/eventbus" +import ( + "github.com/cortezaproject/corteza-server/messaging/types" + "github.com/cortezaproject/corteza-server/pkg/eventbus" +) // Match returns false if given conditions do not match event & resource internals func (res channelBase) Match(c eventbus.ConstraintMatcher) bool { - // By default we match no mather what kind of constraints we receive - // - // Function will be called multiple times - once for every trigger constraint - // All should match (return true): - // constraint#1 AND constraint#2 AND constraint#3 ... - // - // When there are multiple values, Match() can decide how to treat them (OR, AND...) - return true + return channelMatch(res.channel, c, false) +} + +// Handles channel matchers +// +// This *match() fn uses a 3rd param to allow matcher chaining (see commands, channels) +func channelMatch(r *types.Channel, c eventbus.ConstraintMatcher, def bool) bool { + switch c.Name() { + case "channel", "channel.name": + return r != nil && c.Match(r.Name) + case "channel.topic": + return r != nil && c.Match(r.Topic) + case "channel.type": + return r != nil && c.Match(r.Type.String()) + } + + return def } diff --git a/messaging/service/event/channel_member.go b/messaging/service/event/channel_member.go index abe0349e2..0f016a277 100644 --- a/messaging/service/event/channel_member.go +++ b/messaging/service/event/channel_member.go @@ -1,15 +1,21 @@ package event -import "github.com/cortezaproject/corteza-server/pkg/eventbus" +import ( + "github.com/cortezaproject/corteza-server/messaging/types" + "github.com/cortezaproject/corteza-server/pkg/eventbus" +) // Match returns false if given conditions do not match event & resource internals func (res channelMemberBase) Match(c eventbus.ConstraintMatcher) bool { - // By default we match no mather what kind of constraints we receive - // - // Function will be called multiple times - once for every trigger constraint - // All should match (return true): - // constraint#1 AND constraint#2 AND constraint#3 ... - // - // When there are multiple values, Match() can decide how to treat them (OR, AND...) - return true + return channelMatch(res.channel, c, channelMemberMatch(res.member, c)) +} + +// Handles channel member matchers +func channelMemberMatch(r *types.ChannelMember, c eventbus.ConstraintMatcher) bool { + switch c.Name() { + case "channel-member.type": + return c.Match(string(r.Type)) + } + + return false } diff --git a/messaging/service/event/channel_member_test.go b/messaging/service/event/channel_member_test.go new file mode 100644 index 000000000..9de8954b5 --- /dev/null +++ b/messaging/service/event/channel_member_test.go @@ -0,0 +1,27 @@ +package event + +import ( + "github.com/cortezaproject/corteza-server/messaging/types" + "github.com/cortezaproject/corteza-server/pkg/eventbus" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestChannelMemberMatching(t *testing.T) { + var ( + a = assert.New(t) + res = &channelMemberBase{ + channel: &types.Channel{Name: "ChanChan"}, + member: &types.ChannelMember{Type: types.ChannelMembershipTypeOwner}, + } + + cOwn = eventbus.MustMakeConstraint("channel-member.type", "eq", "owner") + cChn = eventbus.MustMakeConstraint("channel", "eq", "ChanChan") + ) + + a.True(channelMemberMatch(res.member, cOwn)) + + a.True(res.Match(cOwn)) + a.True(res.Match(cChn)) +} diff --git a/messaging/service/event/command.go b/messaging/service/event/command.go index 2a68a645a..ecc1b40a8 100644 --- a/messaging/service/event/command.go +++ b/messaging/service/event/command.go @@ -1,15 +1,21 @@ package event -import "github.com/cortezaproject/corteza-server/pkg/eventbus" +import ( + "github.com/cortezaproject/corteza-server/messaging/types" + "github.com/cortezaproject/corteza-server/pkg/eventbus" +) // Match returns false if given conditions do not match event & resource internals func (res commandBase) Match(c eventbus.ConstraintMatcher) bool { - // By default we match no mather what kind of constraints we receive - // - // Function will be called multiple times - once for every trigger constraint - // All should match (return true): - // constraint#1 AND constraint#2 AND constraint#3 ... - // - // When there are multiple values, Match() can decide how to treat them (OR, AND...) - return true + return channelMatch(res.channel, c, commandMatch(res.command, c)) +} + +// Handles command matchers +func commandMatch(r *types.Command, c eventbus.ConstraintMatcher) bool { + switch c.Name() { + case "command", "command.name": + return r != nil && c.Match(r.Name) + } + + return false } diff --git a/messaging/service/event/command_test.go b/messaging/service/event/command_test.go new file mode 100644 index 000000000..f3a628fec --- /dev/null +++ b/messaging/service/event/command_test.go @@ -0,0 +1,30 @@ +package event + +import ( + "github.com/cortezaproject/corteza-server/messaging/types" + "github.com/cortezaproject/corteza-server/pkg/eventbus" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCommandMatching(t *testing.T) { + var ( + a = assert.New(t) + res = &commandBase{ + channel: &types.Channel{Name: "ChanChan"}, + command: &types.Command{Name: "fooCommand"}, + } + + cFoo = eventbus.MustMakeConstraint("command", "eq", "fooCommand") + cBar = eventbus.MustMakeConstraint("command", "eq", "barCommand") + cChn = eventbus.MustMakeConstraint("channel", "eq", "ChanChan") + ) + + a.True(commandMatch(res.command, cFoo)) + a.False(commandMatch(res.command, cBar)) + + a.True(res.Match(cFoo)) + a.False(res.Match(cBar)) + a.True(res.Match(cChn)) +} diff --git a/messaging/service/event/constraint.go b/messaging/service/event/constraint.go deleted file mode 100644 index 84fc6cd96..000000000 --- a/messaging/service/event/constraint.go +++ /dev/null @@ -1,9 +0,0 @@ -package event - -type ( - constraint interface { - Name() string - Values() []string - Match(value string) bool - } -) diff --git a/messaging/service/event/message.go b/messaging/service/event/message.go index e0ad33b8c..f1cba384f 100644 --- a/messaging/service/event/message.go +++ b/messaging/service/event/message.go @@ -1,15 +1,23 @@ package event -import "github.com/cortezaproject/corteza-server/pkg/eventbus" +import ( + "github.com/cortezaproject/corteza-server/messaging/types" + "github.com/cortezaproject/corteza-server/pkg/eventbus" +) // Match returns false if given conditions do not match event & resource internals func (res messageBase) Match(c eventbus.ConstraintMatcher) bool { - // By default we match no mather what kind of constraints we receive - // - // Function will be called multiple times - once for every trigger constraint - // All should match (return true): - // constraint#1 AND constraint#2 AND constraint#3 ... - // - // When there are multiple values, Match() can decide how to treat them (OR, AND...) - return true + return channelMatch(res.channel, c, messageMatch(res.message, c)) +} + +// Handles message matchers +func messageMatch(r *types.Message, c eventbus.ConstraintMatcher) bool { + switch c.Name() { + case "message": + return c != nil && c.Match(r.Message) + case "message.type": + return c != nil && c.Match(string(r.Type)) + } + + return false } diff --git a/messaging/service/event/message_test.go b/messaging/service/event/message_test.go new file mode 100644 index 000000000..7ef8d9f61 --- /dev/null +++ b/messaging/service/event/message_test.go @@ -0,0 +1,28 @@ +package event + +import ( + "github.com/cortezaproject/corteza-server/messaging/types" + "github.com/cortezaproject/corteza-server/pkg/eventbus" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestMessageMatching(t *testing.T) { + var ( + a = assert.New(t) + res = &messageBase{ + channel: &types.Channel{Name: "ChanChan"}, + message: &types.Message{Message: "foo bar", Type: types.MessageTypeIlleism}, + } + + cMsg = eventbus.MustMakeConstraint("message", "like", "foo*") + cTyp = eventbus.MustMakeConstraint("message.type", "eq", "illeism") + cChn = eventbus.MustMakeConstraint("channel", "eq", "ChanChan") + ) + + a.True(messageMatch(res.message, cMsg)) + + a.True(res.Match(cMsg)) + a.True(res.Match(cTyp)) + a.True(res.Match(cChn)) +} diff --git a/messaging/service/event/messaging.go b/messaging/service/event/messaging.go index 3120f81da..c54e16d56 100644 --- a/messaging/service/event/messaging.go +++ b/messaging/service/event/messaging.go @@ -7,22 +7,22 @@ import ( // Match returns false if given conditions do not match event & resource internals func (res messagingOnInterval) Match(c eventbus.ConstraintMatcher) bool { + // @todo this could be flippled + // instead of passing around raw values as strings, + // constraint values could/should be preparsed when creating constraint return scheduler.OnInterval(c.Values()...) } // Match returns false if given conditions do not match event & resource internals func (res messagingOnTimestamp) Match(c eventbus.ConstraintMatcher) bool { + // @todo this could be flippled + // instead of passing around raw values as strings, + // constraint values could/should be preparsed when creating constraint return scheduler.OnTimestamp(c.Values()...) } // Match returns false if given conditions do not match event & resource internals func (res messagingBase) Match(c eventbus.ConstraintMatcher) bool { - // By default we match no mather what kind of constraints we receive - // - // Function will be called multiple times - once for every trigger constraint - // All should match (return true): - // constraint#1 AND constraint#2 AND constraint#3 ... - // - // When there are multiple values, Match() can decide how to treat them (OR, AND...) - return true + // No constraints are supported for messaging. + return false } diff --git a/messaging/service/event/messaging_test.go b/messaging/service/event/messaging_test.go new file mode 100644 index 000000000..64c772ec8 --- /dev/null +++ b/messaging/service/event/messaging_test.go @@ -0,0 +1,39 @@ +package event + +import ( + "github.com/cortezaproject/corteza-server/pkg/eventbus" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestMessagingOnIntervalMatching(t *testing.T) { + var ( + res = &messagingOnInterval{} + cInt = eventbus.MustMakeConstraint("", "", "* * * * *") + ) + + // Just make sure it runs + // not bothering with precise test setup (scheduler's tests cover all that + res.Match(cInt) +} + +func TestMessagingOnTimestampMatching(t *testing.T) { + var ( + a = assert.New(t) + res = &messagingOnInterval{} + + cTStamp = eventbus.MustMakeConstraint("", "", "2000-01-01T00:00:00Z") // Y2k! + ) + + a.False(res.Match(cTStamp), "Year 2000?! How did we get here? Anyhow, happy New year!") +} + +func TestMessagingMatching(t *testing.T) { + var ( + a = assert.New(t) + res = &messagingBase{} + ) + + a.False(res.Match(eventbus.MustMakeConstraint("foo", "", "bar"))) +}