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

feat: Add new FilterBySourceName function #731

Merged
merged 2 commits into from
Mar 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions app-service-template/functions/sample_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
2 changes: 1 addition & 1 deletion app-service-template/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand Down
18 changes: 18 additions & 0 deletions appsdk/configurable.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
const (
ProfileNames = "profilenames"
DeviceNames = "devicenames"
SourceNames = "sourcenames"
ResourceNames = "resourcenames"
FilterOut = "filterout"
EncryptionKey = "key"
Expand Down Expand Up @@ -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)
lenny-goodell marked this conversation as resolved.
Show resolved Hide resolved
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
Expand Down
30 changes: 30 additions & 0 deletions appsdk/configurable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion internal/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 4 additions & 2 deletions internal/runtime/runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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"

Expand Down Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion internal/trigger/messagebus/messaging_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 6 additions & 6 deletions pkg/transforms/conversion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func TestTransformToXML(t *testing.T) {
eventIn := dtos.Event{
DeviceName: deviceName1,
}
expectedResult := `<Event><ApiVersion></ApiVersion><Id></Id><DeviceName>device1</DeviceName><ProfileName></ProfileName><Created>0</Created><Origin>0</Origin></Event>`
expectedResult := `<Event><ApiVersion></ApiVersion><Id></Id><DeviceName>device1</DeviceName><ProfileName></ProfileName><SourceName></SourceName><Created>0</Created><Origin>0</Origin></Event>`
conv := NewConversion()

continuePipeline, result := conv.TransformToXML(context, eventIn)
Expand Down Expand Up @@ -60,7 +60,7 @@ func TestTransformToXMLMultipleParametersValid(t *testing.T) {
eventIn := dtos.Event{
DeviceName: deviceName1,
}
expectedResult := `<Event><ApiVersion></ApiVersion><Id></Id><DeviceName>device1</DeviceName><ProfileName></ProfileName><Created>0</Created><Origin>0</Origin></Event>`
expectedResult := `<Event><ApiVersion></ApiVersion><Id></Id><DeviceName>device1</DeviceName><ProfileName></ProfileName><SourceName></SourceName><Created>0</Created><Origin>0</Origin></Event>`
conv := NewConversion()
continuePipeline, result := conv.TransformToXML(context, eventIn, "", "", "")
require.NotNil(t, result)
Expand All @@ -76,7 +76,7 @@ func TestTransformToXMLMultipleParametersTwoEvents(t *testing.T) {
eventIn2 := dtos.Event{
DeviceName: deviceName2,
}
expectedResult := `<Event><ApiVersion></ApiVersion><Id></Id><DeviceName>device2</DeviceName><ProfileName></ProfileName><Created>0</Created><Origin>0</Origin></Event>`
expectedResult := `<Event><ApiVersion></ApiVersion><Id></Id><DeviceName>device2</DeviceName><ProfileName></ProfileName><SourceName></SourceName><Created>0</Created><Origin>0</Origin></Event>`
conv := NewConversion()
continuePipeline, result := conv.TransformToXML(context, eventIn2, eventIn1, "", "")

Expand All @@ -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)

Expand Down Expand Up @@ -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)
Expand All @@ -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, "", "")

Expand Down
Loading