From 3ee2f0baa2d3a3d98ce4974c8435d92977f8a164 Mon Sep 17 00:00:00 2001 From: Lenny Goodell <44779287+lenny-intel@users.noreply.github.com> Date: Thu, 4 Mar 2021 15:29:33 -0700 Subject: [PATCH] feat: Add new FilterBySourceName function (#731) * refactor: Remove V1 API code and swagger Also reworked V2 code to remove `v2` in paths closes #720 BREAKING CHANGE: V1 API's no longer supported Signed-off-by: lenny --- app-service-template/functions/sample_test.go | 5 +- app-service-template/go.mod | 2 +- appsdk/configurable.go | 18 ++ appsdk/configurable_test.go | 30 ++++ go.mod | 4 +- internal/runtime/runtime.go | 3 +- internal/runtime/runtime_test.go | 6 +- internal/trigger/messagebus/messaging_test.go | 2 +- pkg/transforms/conversion_test.go | 12 +- pkg/transforms/filter.go | 161 +++++++++--------- pkg/transforms/filter_test.go | 82 +++++++-- 11 files changed, 218 insertions(+), 107 deletions(-) diff --git a/app-service-template/functions/sample_test.go b/app-service-template/functions/sample_test.go index 3469303e1..3c91250fd 100644 --- a/app-service-template/functions/sample_test.go +++ b/app-service-template/functions/sample_test.go @@ -72,11 +72,12 @@ func TestSample_OutputXML(t *testing.T) { } func createTestEvent(t *testing.T) dtos.Event { - deviceName := "MyDevice" profileName := "MyProfile" + deviceName := "MyDevice" + sourceName := "MySource" resourceName := "MyResource" - event := dtos.NewEvent(profileName, deviceName) + event := dtos.NewEvent(profileName, deviceName, sourceName) err := event.AddSimpleReading(resourceName, v2.ValueTypeInt32, int32(1234)) require.NoError(t, err) diff --git a/app-service-template/go.mod b/app-service-template/go.mod index ae24e82d6..7d26e7b8d 100644 --- a/app-service-template/go.mod +++ b/app-service-template/go.mod @@ -6,7 +6,7 @@ go 1.15 require ( github.com/edgexfoundry/app-functions-sdk-go/v2 v2.0.0-dev.14 - github.com/edgexfoundry/go-mod-core-contracts/v2 v2.0.0-dev.35 + github.com/edgexfoundry/go-mod-core-contracts/v2 v2.0.0-dev.42 github.com/google/uuid v1.2.0 github.com/stretchr/testify v1.7.0 ) diff --git a/appsdk/configurable.go b/appsdk/configurable.go index 5aa58da01..a5d69b54d 100644 --- a/appsdk/configurable.go +++ b/appsdk/configurable.go @@ -29,6 +29,7 @@ import ( const ( ProfileNames = "profilenames" DeviceNames = "devicenames" + SourceNames = "sourcenames" ResourceNames = "resourcenames" FilterOut = "filterout" EncryptionKey = "key" @@ -120,6 +121,23 @@ func (dynamic AppFunctionsSDKConfigurable) FilterByDeviceName(parameters map[str return transform.FilterByDeviceName } +// FilterBySourceName - Specify the source names (resources and/or commands) of interest to filter for data coming from certain sensors. +// The Filter by Source Name transform looks at the Event in the message and looks at the source names of interest list, +// provided by this function, and filters out those messages whose Event is for source names not in the +// source names of interest. +// This function will return an error and stop the pipeline if a non-edgex +// event is received or if no data is received. +// For example, data generated by a motor does not get passed to functions only interested in data from a thermostat. +// This function is a configuration function and returns a function pointer. +func (dynamic AppFunctionsSDKConfigurable) FilterBySourceName(parameters map[string]string) appcontext.AppFunction { + transform, ok := dynamic.processFilterParameters("FilterBySourceName", parameters, SourceNames) + if !ok { + return nil + } + + return transform.FilterBySourceName +} + // FilterByResourceName - Specify the resource name of interest to filter for data from certain types of IoT objects, // such as temperatures, motion, and so forth, that may come from an array of sensors or devices. The Filter by resource name assesses // the data in each Event and Reading, and removes readings that have a resource name that is not in the list of diff --git a/appsdk/configurable_test.go b/appsdk/configurable_test.go index 5fe445647..32d1d7ba5 100644 --- a/appsdk/configurable_test.go +++ b/appsdk/configurable_test.go @@ -83,6 +83,36 @@ func TestFilterByDeviceName(t *testing.T) { } } +func TestFilterBySourceName(t *testing.T) { + configurable := AppFunctionsSDKConfigurable{ + Sdk: &AppFunctionsSDK{ + LoggingClient: lc, + }, + } + + tests := []struct { + name string + params map[string]string + expectNil bool + }{ + {"Non Existent Parameters", map[string]string{"": ""}, true}, + {"Empty Parameters", map[string]string{SourceNames: ""}, false}, + {"Valid Parameters", map[string]string{SourceNames: "R1, C2, R4"}, false}, + {"Empty FilterOut Parameters", map[string]string{SourceNames: "R1, C2, R4", FilterOut: ""}, true}, + {"Valid FilterOut Parameters", map[string]string{SourceNames: "R1, C2, R4", FilterOut: "true"}, false}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + trx := configurable.FilterBySourceName(tt.params) + if tt.expectNil { + assert.Nil(t, trx, "return result from FilterBySourceName should be nil") + } else { + assert.NotNil(t, trx, "return result from FilterBySourceName should not be nil") + } + }) + } +} + func TestFilterByResourceName(t *testing.T) { configurable := AppFunctionsSDKConfigurable{ Sdk: &AppFunctionsSDK{ diff --git a/go.mod b/go.mod index 8182eb244..ec9542a01 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,8 @@ require ( bitbucket.org/bertimus9/systemstat v0.0.0-20180207000608-0eeff89b0690 github.com/diegoholiveira/jsonlogic v1.0.1-0.20200220175622-ab7989be08b9 github.com/eclipse/paho.mqtt.golang v1.2.0 - github.com/edgexfoundry/go-mod-bootstrap/v2 v2.0.0-dev.13 - github.com/edgexfoundry/go-mod-core-contracts/v2 v2.0.0-dev.35 + github.com/edgexfoundry/go-mod-bootstrap/v2 v2.0.0-dev.14 + github.com/edgexfoundry/go-mod-core-contracts/v2 v2.0.0-dev.42 github.com/edgexfoundry/go-mod-messaging/v2 v2.0.0-dev.3 github.com/edgexfoundry/go-mod-registry/v2 v2.0.0-dev.3 github.com/fxamacker/cbor/v2 v2.2.0 diff --git a/internal/runtime/runtime.go b/internal/runtime/runtime.go index e1db9acfa..8f874bd9b 100644 --- a/internal/runtime/runtime.go +++ b/internal/runtime/runtime.go @@ -288,8 +288,9 @@ func (gr *GolangRuntime) unmarshalV1EventToV2Event(envelope types.MessageEnvelop v2Event := dtos.Event{ Versionable: commonDTO.NewVersionable(), Id: v1Event.ID, - DeviceName: v1Event.Device, ProfileName: "Unknown", + DeviceName: v1Event.Device, + SourceName: "Unknown", Created: v1Event.Created, Origin: v1Event.Origin, Tags: v1Event.Tags, diff --git a/internal/runtime/runtime_test.go b/internal/runtime/runtime_test.go index 5db4f088a..8a8f8d18e 100644 --- a/internal/runtime/runtime_test.go +++ b/internal/runtime/runtime_test.go @@ -49,7 +49,7 @@ var testAddEventRequest = createAddEventRequest() var testV2Event = testAddEventRequest.Event func createAddEventRequest() requests.AddEventRequest { - event := dtos.NewEvent("Thermostat", "FamilyRoomThermostat") + event := dtos.NewEvent("Thermostat", "FamilyRoomThermostat", "Temperature") event.AddSimpleReading("Temperature", v2.ValueTypeInt64, int64(72)) request := requests.NewAddEventRequest(event) return request @@ -252,7 +252,7 @@ func TestProcessMessageThreeCustomTransformsOneFail(t *testing.T) { func TestProcessMessageTransformError(t *testing.T) { // Error expected from FilterByDeviceName - expectedError := "type received is not an Event" + expectedError := "FilterByDeviceName: type received is not an Event" expectedErrorCode := http.StatusUnprocessableEntity // Send a RegistryInfo to the pipeline, instead of an Event @@ -544,6 +544,7 @@ func TestGolangRuntime_processEventPayload(t *testing.T) { expectedV2Event := testV2Event expectedV2EventFromV1Event := testV2Event expectedV2EventFromV1Event.ProfileName = "Unknown" + expectedV2EventFromV1Event.SourceName = "Unknown" expectedV2EventFromV1Event.Readings = []dtos.BaseReading{testV2Event.Readings[0]} expectedV2EventFromV1Event.Readings[0].ProfileName = "Unknown" @@ -592,6 +593,7 @@ func TestGolangRuntime_unmarshalV1EventToV2Event(t *testing.T) { expectedEvent := testV2Event expectedEvent.ProfileName = "Unknown" + expectedEvent.SourceName = "Unknown" expectedEvent.Readings[0].ProfileName = "Unknown" tests := []struct { diff --git a/internal/trigger/messagebus/messaging_test.go b/internal/trigger/messagebus/messaging_test.go index 685d8904d..a99472c43 100644 --- a/internal/trigger/messagebus/messaging_test.go +++ b/internal/trigger/messagebus/messaging_test.go @@ -50,7 +50,7 @@ var addEventRequest = createTestEventRequest() var expectedEvent = addEventRequest.Event func createTestEventRequest() requests.AddEventRequest { - event := dtos.NewEvent("thermostat", "LivingRoomThermostat") + event := dtos.NewEvent("thermostat", "LivingRoomThermostat", "temperature") _ = event.AddSimpleReading("temperature", v2.ValueTypeInt64, int64(38)) request := requests.NewAddEventRequest(event) return request diff --git a/pkg/transforms/conversion_test.go b/pkg/transforms/conversion_test.go index 3c6196402..1a89a42d1 100644 --- a/pkg/transforms/conversion_test.go +++ b/pkg/transforms/conversion_test.go @@ -30,7 +30,7 @@ func TestTransformToXML(t *testing.T) { eventIn := dtos.Event{ DeviceName: deviceName1, } - expectedResult := `device100` + expectedResult := `device100` conv := NewConversion() continuePipeline, result := conv.TransformToXML(context, eventIn) @@ -60,7 +60,7 @@ func TestTransformToXMLMultipleParametersValid(t *testing.T) { eventIn := dtos.Event{ DeviceName: deviceName1, } - expectedResult := `device100` + expectedResult := `device100` conv := NewConversion() continuePipeline, result := conv.TransformToXML(context, eventIn, "", "", "") require.NotNil(t, result) @@ -76,7 +76,7 @@ func TestTransformToXMLMultipleParametersTwoEvents(t *testing.T) { eventIn2 := dtos.Event{ DeviceName: deviceName2, } - expectedResult := `device200` + expectedResult := `device200` conv := NewConversion() continuePipeline, result := conv.TransformToXML(context, eventIn2, eventIn1, "", "") @@ -91,7 +91,7 @@ func TestTransformToJSON(t *testing.T) { eventIn := dtos.Event{ DeviceName: deviceName1, } - expectedResult := `{"apiVersion":"","id":"","deviceName":"device1","profileName":"","origin":0,"readings":null}` + expectedResult := `{"apiVersion":"","id":"","deviceName":"device1","profileName":"","sourceName":"","origin":0,"readings":null}` conv := NewConversion() continuePipeline, result := conv.TransformToJSON(context, eventIn) @@ -120,7 +120,7 @@ func TestTransformToJSONMultipleParametersValid(t *testing.T) { eventIn := dtos.Event{ DeviceName: deviceName1, } - expectedResult := `{"apiVersion":"","id":"","deviceName":"device1","profileName":"","origin":0,"readings":null}` + expectedResult := `{"apiVersion":"","id":"","deviceName":"device1","profileName":"","sourceName":"","origin":0,"readings":null}` conv := NewConversion() continuePipeline, result := conv.TransformToJSON(context, eventIn, "", "", "") assert.NotNil(t, result) @@ -137,7 +137,7 @@ func TestTransformToJSONMultipleParametersTwoEvents(t *testing.T) { eventIn2 := dtos.Event{ DeviceName: deviceName2, } - expectedResult := `{"apiVersion":"","id":"","deviceName":"device2","profileName":"","origin":0,"readings":null}` + expectedResult := `{"apiVersion":"","id":"","deviceName":"device2","profileName":"","sourceName":"","origin":0,"readings":null}` conv := NewConversion() continuePipeline, result := conv.TransformToJSON(context, eventIn2, eventIn1, "", "") diff --git a/pkg/transforms/filter.go b/pkg/transforms/filter.go index 35fac479b..330f7d4e4 100755 --- a/pkg/transforms/filter.go +++ b/pkg/transforms/filter.go @@ -17,7 +17,9 @@ package transforms import ( - "errors" + "fmt" + + "github.com/edgexfoundry/go-mod-core-contracts/v2/clients/logger" "github.com/edgexfoundry/app-functions-sdk-go/v2/appcontext" @@ -46,92 +48,52 @@ func NewFilterOut(filterValues []string) Filter { // If FilterOut is false, it filters out those Events not associated with the specified Device Profile listed in FilterValues. // If FilterOut is true, it out those Events that are associated with the specified Device Profile listed in FilterValues. func (f Filter) FilterByProfileName(edgexcontext *appcontext.Context, params ...interface{}) (continuePipeline bool, result interface{}) { - mode := "For" - if f.FilterOut { - mode = "Out" + event, err := f.setupForFiltering("FilterByProfileName", "ProfileName", edgexcontext.LoggingClient, params...) + if err != nil { + return false, err } - edgexcontext.LoggingClient.Debugf("Filtering %s by Device Profile. FilterValues are: '[%v]'", mode, f.FilterValues) - if len(params) < 1 { - return false, errors.New("no Event Received") + ok := f.doEventFilter("ProfileName", event.ProfileName, edgexcontext.LoggingClient) + if ok { + return true, *event } - event, ok := params[0].(dtos.Event) - if !ok { - return false, errors.New("type received is not an Event") - } - - // No names to filter for, so pass events thru rather than filtering them all out. - if len(f.FilterValues) == 0 { - return true, event - } - - for _, name := range f.FilterValues { - if event.ProfileName == name { - if f.FilterOut { - edgexcontext.LoggingClient.Debugf("Event not accepted for Profile=%s", event.ProfileName) - return false, nil - } else { - edgexcontext.LoggingClient.Debugf("Event accepted for Profile=%s", event.ProfileName) - return true, event - } - } - } + return false, nil - // Will only get here if Event's ProfileName didn't match any names in FilterValues - if f.FilterOut { - edgexcontext.LoggingClient.Debugf("Event accepted for Profile=", event.ProfileName) - return true, event - } else { - edgexcontext.LoggingClient.Debugf("Event not accepted for Profile=%s", event.ProfileName) - return false, nil - } } // FilterByDeviceName filters based on the specified Device Names, aka Instance of a Device. // If FilterOut is false, it filters out those Events not associated with the specified Device Names listed in FilterValues. // If FilterOut is true, it out those Events that are associated with the specified Device Names listed in FilterValues. func (f Filter) FilterByDeviceName(edgexcontext *appcontext.Context, params ...interface{}) (continuePipeline bool, result interface{}) { - mode := "For" - if f.FilterOut { - mode = "Out" + event, err := f.setupForFiltering("FilterByDeviceName", "DeviceName", edgexcontext.LoggingClient, params...) + if err != nil { + return false, err } - edgexcontext.LoggingClient.Debugf("Filtering %s by Device Name. FilterValues are: '[%v]'", mode, f.FilterValues) - if len(params) < 1 { - return false, errors.New("no Event Received") + ok := f.doEventFilter("DeviceName", event.DeviceName, edgexcontext.LoggingClient) + if ok { + return true, *event } - event, ok := params[0].(dtos.Event) - if !ok { - return false, errors.New("type received is not an Event") - } + return false, nil +} - // No names to filter for, so pass events thru rather than filtering them all out. - if len(f.FilterValues) == 0 { - return true, event +// FilterBySourceName filters based on the specified Source for the Event, aka resource or command name. +// If FilterOut is false, it filters out those Events not associated with the specified Source listed in FilterValues. +// If FilterOut is true, it out those Events that are associated with the specified Source listed in FilterValues. +func (f Filter) FilterBySourceName(edgexcontext *appcontext.Context, params ...interface{}) (continuePipeline bool, result interface{}) { + event, err := f.setupForFiltering("FilterBySourceName", "SourceName", edgexcontext.LoggingClient, params...) + if err != nil { + return false, err } - for _, name := range f.FilterValues { - if event.DeviceName == name { - if f.FilterOut { - edgexcontext.LoggingClient.Debugf("Event not accepted for Device=%s", event.DeviceName) - return false, nil - } else { - edgexcontext.LoggingClient.Debugf("Event accepted for Device=%s", event.DeviceName) - return true, event - } - } + ok := f.doEventFilter("SourceName", event.SourceName, edgexcontext.LoggingClient) + if ok { + return true, *event } - // Will only get here if Event's DeviceName didn't match any names in FilterValues - if f.FilterOut { - edgexcontext.LoggingClient.Debugf("Event accepted for Device=", event.DeviceName) - return true, event - } else { - edgexcontext.LoggingClient.Debugf("Event not accepted for Device=%s", event.DeviceName) - return false, nil - } + return false, nil } // FilterByResourceName filters based on the specified Reading resource names, aka Instance of a Device. @@ -139,24 +101,14 @@ func (f Filter) FilterByDeviceName(edgexcontext *appcontext.Context, params ...i // If FilterOut is true, it out those Event Readings that are associated with the specified Resource Names listed in FilterValues. // This function will return an error and stop the pipeline if a non-edgex event is received or if no data is received. func (f Filter) FilterByResourceName(edgexcontext *appcontext.Context, params ...interface{}) (continuePipeline bool, result interface{}) { - mode := "For" - if f.FilterOut { - mode = "Out" - } - edgexcontext.LoggingClient.Debugf("Filtering %s by Resource Name. FilterValues are: '[%v]'", mode, f.FilterValues) - - if len(params) < 1 { - return false, errors.New("no Event Received") - } - - existingEvent, ok := params[0].(dtos.Event) - if !ok { - return false, errors.New("type received is not an Event") + existingEvent, err := f.setupForFiltering("FilterByResourceName", "ResourceName", edgexcontext.LoggingClient, params...) + if err != nil { + return false, err } // No filter values, so pass all event and all readings thru, rather than filtering them all out. if len(f.FilterValues) == 0 { - return true, existingEvent + return true, *existingEvent } auxEvent := dtos.Event{ @@ -210,3 +162,50 @@ func (f Filter) FilterByResourceName(edgexcontext *appcontext.Context, params .. edgexcontext.LoggingClient.Debug("Event not accepted: 0 remaining readings") return false, nil } + +func (f Filter) setupForFiltering(funcName string, filterProperty string, lc logger.LoggingClient, params ...interface{}) (*dtos.Event, error) { + mode := "For" + if f.FilterOut { + mode = "Out" + } + lc.Debugf("Filtering %s by %s. FilterValues are: '[%v]'", mode, filterProperty, f.FilterValues) + + if len(params) < 1 { + return nil, fmt.Errorf("%s: no Event Received", funcName) + } + + event, ok := params[0].(dtos.Event) + if !ok { + return nil, fmt.Errorf("%s: type received is not an Event", funcName) + } + + return &event, nil +} + +func (f Filter) doEventFilter(filterProperty string, value string, lc logger.LoggingClient) bool { + // No names to filter for, so pass events thru rather than filtering them all out. + if len(f.FilterValues) == 0 { + return true + } + + for _, name := range f.FilterValues { + if value == name { + if f.FilterOut { + lc.Debugf("Event not accepted for %s=%s", filterProperty, value) + return false + } else { + lc.Debugf("Event accepted for %s=%s", filterProperty, value) + return true + } + } + } + + // Will only get here if Event's SourceName didn't match any names in FilterValues + if f.FilterOut { + lc.Debugf("Event accepted for %s=%s", filterProperty, value) + return true + } else { + lc.Debugf("Event not accepted for %s=%s", filterProperty, value) + return false + } +} diff --git a/pkg/transforms/filter_test.go b/pkg/transforms/filter_test.go index 1afed8fa7..a0270cd74 100644 --- a/pkg/transforms/filter_test.go +++ b/pkg/transforms/filter_test.go @@ -27,11 +27,14 @@ import ( ) const ( + profileName1 = "profile1" + profileName2 = "profile2" + deviceName1 = "device1" deviceName2 = "device2" - profileName1 = "profile1" - profileName2 = "profile2" + sourceName1 = "source1" + sourceName2 = "source2" resource1 = "resource1" resource2 = "resource2" @@ -39,7 +42,7 @@ const ( ) func TestFilter_FilterByProfileName(t *testing.T) { - profile1Event := dtos.NewEvent(profileName1, deviceName1) + profile1Event := dtos.NewEvent(profileName1, deviceName1, sourceName1) tests := []struct { Name string @@ -75,7 +78,7 @@ func TestFilter_FilterByProfileName(t *testing.T) { if test.EventIn == nil { continuePipeline, result := filter.FilterByProfileName(context) - assert.EqualError(t, result.(error), "no Event Received") + assert.EqualError(t, result.(error), "FilterByProfileName: no Event Received") assert.False(t, continuePipeline) } else { var continuePipeline bool @@ -96,7 +99,7 @@ func TestFilter_FilterByProfileName(t *testing.T) { } func TestFilter_FilterByDeviceName(t *testing.T) { - device1Event := dtos.NewEvent(profileName1, deviceName1) + device1Event := dtos.NewEvent(profileName1, deviceName1, sourceName1) tests := []struct { Name string @@ -132,7 +135,7 @@ func TestFilter_FilterByDeviceName(t *testing.T) { if test.EventIn == nil { continuePipeline, result := filter.FilterByDeviceName(context) - assert.EqualError(t, result.(error), "no Event Received") + assert.EqualError(t, result.(error), "FilterByDeviceName: no Event Received") assert.False(t, continuePipeline) } else { var continuePipeline bool @@ -152,24 +155,81 @@ func TestFilter_FilterByDeviceName(t *testing.T) { } } +func TestFilter_FilterBySourceName(t *testing.T) { + source1Event := dtos.NewEvent(profileName1, deviceName1, sourceName1) + + tests := []struct { + Name string + Filters []string + FilterOut bool + EventIn *dtos.Event + ExpectedNilResult bool + ExtraParam bool + }{ + {"filter for - no event", []string{sourceName1}, true, nil, true, false}, + {"filter for - no filter values", []string{}, false, &source1Event, false, false}, + {"filter for with extra params - found", []string{sourceName1}, false, &source1Event, false, true}, + {"filter for - found", []string{sourceName1}, false, &source1Event, false, false}, + {"filter for - not found", []string{sourceName2}, false, &source1Event, true, false}, + + {"filter out - no event", []string{sourceName1}, true, nil, true, false}, + {"filter out - no filter values", []string{}, true, &source1Event, false, false}, + {"filter out extra param - found", []string{sourceName1}, true, &source1Event, true, true}, + {"filter out - found", []string{sourceName1}, true, &source1Event, true, false}, + {"filter out - not found", []string{sourceName2}, true, &source1Event, false, false}, + } + + for _, test := range tests { + t.Run(test.Name, func(t *testing.T) { + var filter Filter + if test.FilterOut { + filter = NewFilterOut(test.Filters) + } else { + filter = NewFilterFor(test.Filters) + } + + expectedContinue := !test.ExpectedNilResult + + if test.EventIn == nil { + continuePipeline, result := filter.FilterBySourceName(context) + assert.EqualError(t, result.(error), "FilterBySourceName: no Event Received") + assert.False(t, continuePipeline) + } else { + var continuePipeline bool + var result interface{} + if test.ExtraParam { + continuePipeline, result = filter.FilterBySourceName(context, *test.EventIn, "application/event") + } else { + continuePipeline, result = filter.FilterBySourceName(context, *test.EventIn) + } + assert.Equal(t, expectedContinue, continuePipeline) + assert.Equal(t, test.ExpectedNilResult, result == nil) + if result != nil && test.EventIn != nil { + assert.Equal(t, *test.EventIn, result) + } + } + }) + } +} + func TestFilter_FilterByResourceName(t *testing.T) { // event with a reading for resource 1 - resource1Event := dtos.NewEvent(profileName1, deviceName1) + resource1Event := dtos.NewEvent(profileName1, deviceName1, sourceName1) err := resource1Event.AddSimpleReading(resource1, v2.ValueTypeInt32, int32(123)) require.NoError(t, err) // event with a reading for resource 2 - resource2Event := dtos.NewEvent(profileName1, deviceName1) + resource2Event := dtos.NewEvent(profileName1, deviceName1, sourceName1) err = resource2Event.AddSimpleReading(resource2, v2.ValueTypeInt32, int32(123)) require.NoError(t, err) // event with a reading for resource 3 - resource3Event := dtos.NewEvent(profileName1, deviceName1) + resource3Event := dtos.NewEvent(profileName1, deviceName1, sourceName1) err = resource3Event.AddSimpleReading(resource3, v2.ValueTypeInt32, int32(123)) require.NoError(t, err) // event with readings for resource 1 & 2 - twoResourceEvent := dtos.NewEvent(profileName1, deviceName1) + twoResourceEvent := dtos.NewEvent(profileName1, deviceName1, sourceName1) err = twoResourceEvent.AddSimpleReading(resource1, v2.ValueTypeInt32, int32(123)) require.NoError(t, err) err = twoResourceEvent.AddSimpleReading(resource2, v2.ValueTypeInt32, int32(123)) @@ -219,7 +279,7 @@ func TestFilter_FilterByResourceName(t *testing.T) { if test.EventIn == nil { continuePipeline, result := filter.FilterByResourceName(context) - assert.EqualError(t, result.(error), "no Event Received") + assert.EqualError(t, result.(error), "FilterByResourceName: no Event Received") assert.False(t, continuePipeline) } else { var continuePipeline bool