From dab6dc38cda7516b1aef27423d4f0cb92a1bb0b3 Mon Sep 17 00:00:00 2001 From: Mattia Mazzucato Date: Fri, 14 Jul 2023 17:25:45 +0200 Subject: [PATCH] Fix appengine send-data for binaryblob Handle the sending of binaryblob and binaryblob arrays. Data which are modeled as binaryblob are received as strings from the command line. Then, cast the payload to bytes prior to posting it to appengine. Signed-off-by: Mattia Mazzucato --- CHANGELOG.md | 3 +++ cmd/appengine/device.go | 46 ++++++++++++++++++++++++++++++++++++++--- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 49 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 719aeda..a5af2bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `realm-management interfaces {install,upgrade}` commands are run synchronously. - Use Go 1.20 for releases. +### Fixed +- `appengine send-data`: fix the encoding of binaryblob and binaryblobarray data. + ## [22.11.02] - 23/05/2023 ### Changed - `appengine device`: print a parametric command rather than a partial one with diff --git a/cmd/appengine/device.go b/cmd/appengine/device.go index c2fd347..ad19ead 100644 --- a/cmd/appengine/device.go +++ b/cmd/appengine/device.go @@ -1094,14 +1094,54 @@ func devicesSendDataF(command *cobra.Command, args []string) error { // correctly, we should convert to int every payload for which an integer conversion does not lose // in precision for k, v := range aggrPayload { + // since we're dealing with object aggregation, we need to reconstruct + // the full path to get the mapping and its type + fullPath := fmt.Sprintf("%s/%s", interfacePath, k) + mapping, err := interfaces.InterfaceMappingFromPath(iface, fullPath) + if err != nil { + return err + } + + // now we have a mapping type + payloadType = mapping.Type + switch val := v.(type) { case float64: if val == math.Trunc(val) { aggrPayload[k] = int(val) } + case string: + // in case the type is binaryblob, we want the value as []byte + if payloadType == interfaces.BinaryBlob { + decoded, err := base64.StdEncoding.DecodeString(string(val)) + if err != nil { + fmt.Fprintln(os.Stderr, "Input string is not base64 encoded.", err) + os.Exit(1) + } + aggrPayload[k] = decoded + } + case []interface{}: + // in case the type is binaryblobarray, we want the values as [][]byte + if payloadType == interfaces.BinaryBlobArray { + acc := [][]byte{} + for _, item := range val { + theString, ok := item.(string) + if !ok { + fmt.Fprintf(os.Stderr, "Invalid item while handling endpoint %s\n", mapping.Endpoint) + os.Exit(1) + } + decoded, err := base64.StdEncoding.DecodeString(theString) + if err != nil { + fmt.Fprintln(os.Stderr, "Input string is not base64 encoded.") + os.Exit(1) + } + + acc = append(acc, decoded) + } + aggrPayload[k] = acc + } } } - parsedPayloadData = aggrPayload } @@ -1284,8 +1324,8 @@ func parseSendDataPayload(payload string, mappingType interfaces.AstarteMappingT return nil, err } case interfaces.BinaryBlob: - // We have to verify base64 decoding works - if _, err := base64.StdEncoding.DecodeString(payload); err != nil { + // if we're dealing with binaryblobs, we want to return a []byte + if ret, err = base64.StdEncoding.DecodeString(payload); err != nil { return nil, err } case interfaces.DateTime: diff --git a/go.mod b/go.mod index ac45f3b..e87647a 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( code.cloudfoundry.org/bytefmt v0.0.0-20211005130812-5bb3c17173e5 github.com/Masterminds/semver/v3 v3.1.1 github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de - github.com/astarte-platform/astarte-go v0.91.0 + github.com/astarte-platform/astarte-go v0.91.1-0.20230718084224-d5bbb47f5179 github.com/go-openapi/strfmt v0.21.1 // indirect github.com/google/go-cmp v0.5.8 github.com/google/go-github/v30 v30.1.0 diff --git a/go.sum b/go.sum index 44c3422..4cdb80b 100644 --- a/go.sum +++ b/go.sum @@ -93,8 +93,8 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGLmAjMPwCCCo7Jf0W6f9slllCkkv7vyc1yOSg= github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/astarte-platform/astarte-go v0.91.0 h1:VEsTKfyEDxFzKOQLcgS9HHPiiC0p5eMkj+luSiQ3AwE= -github.com/astarte-platform/astarte-go v0.91.0/go.mod h1:6e/IkwjAS7fXdCerA/xr/Fcv6OseNRhDFytuhCGfjvM= +github.com/astarte-platform/astarte-go v0.91.1-0.20230718084224-d5bbb47f5179 h1:/RJX27SPJ7XmfGAp1RhNSFtuMYjBKyqTk/LDZpbdLUQ= +github.com/astarte-platform/astarte-go v0.91.1-0.20230718084224-d5bbb47f5179/go.mod h1:XZUDeZxSGG9Z1bQJm/x5B58S7Azhu2mAdVaZV+XrEK0= github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=