From 6459cb97ae7b7380fc19be4c44a6f599c7f1db0a Mon Sep 17 00:00:00 2001 From: weichou Date: Tue, 2 Mar 2021 20:40:18 +0800 Subject: [PATCH] fix: Check empty value when converting Model to DTO 1. Check the empty value when convert Model to DTO - FromProvisionWatcherModelToUpdateDTO - FromDeviceModelToUpdateDTO - FromDeviceServiceModelToUpdateDTO 2. API client lib handle the 404 StatusNotFound response 3. Modify BinaryReading validate annotation Fix #528 Signed-off-by: weichou --- v2/clients/http/utils/common.go | 4 +++ v2/dtos/device.go | 61 ++++++++++++++++++++++---------- v2/dtos/device_test.go | 33 +++++++++++++++++ v2/dtos/deviceservice.go | 21 +++++++---- v2/dtos/deviceservice_test.go | 26 ++++++++++++++ v2/dtos/provisionwatcher.go | 29 ++++++++++----- v2/dtos/provisionwatcher_test.go | 30 ++++++++++++++++ v2/dtos/reading.go | 2 +- 8 files changed, 173 insertions(+), 33 deletions(-) create mode 100644 v2/dtos/device_test.go create mode 100644 v2/dtos/deviceservice_test.go create mode 100644 v2/dtos/provisionwatcher_test.go diff --git a/v2/clients/http/utils/common.go b/v2/clients/http/utils/common.go index 7bcdb996..11dcf16f 100644 --- a/v2/clients/http/utils/common.go +++ b/v2/clients/http/utils/common.go @@ -150,6 +150,10 @@ func sendRequest(ctx context.Context, req *http.Request) ([]byte, errors.EdgeX) } // Handle error response + if resp.StatusCode == http.StatusNotFound { + msg := fmt.Sprintf("request failed, status code: %d, err: %s", resp.StatusCode, string(bodyBytes)) + return nil, errors.NewCommonEdgeX(errors.KindMapping(resp.StatusCode), msg, nil) + } var res common.BaseResponse if err := json.Unmarshal(bodyBytes, &res); err != nil { return nil, errors.NewCommonEdgeXWrapper(err) diff --git a/v2/dtos/device.go b/v2/dtos/device.go index 49c13977..f7dd3043 100644 --- a/v2/dtos/device.go +++ b/v2/dtos/device.go @@ -92,23 +92,48 @@ func FromDeviceModelToDTO(d models.Device) Device { // FromDeviceModelToUpdateDTO transforms the Device Model to the UpdateDevice DTO func FromDeviceModelToUpdateDTO(d models.Device) UpdateDevice { - adminState := string(d.AdminState) - operatingState := string(d.OperatingState) - return UpdateDevice{ - Versionable: common.NewVersionable(), - Id: &d.Id, - Name: &d.Name, - Description: &d.Description, - AdminState: &adminState, - OperatingState: &operatingState, - LastConnected: &d.LastConnected, - LastReported: &d.LastReported, - ServiceName: &d.ServiceName, - ProfileName: &d.ProfileName, - Labels: d.Labels, - Location: d.Location, - AutoEvents: FromAutoEventModelsToDTOs(d.AutoEvents), - Protocols: FromProtocolModelsToDTOs(d.Protocols), - Notify: &d.Notify, + dto := UpdateDevice{ + Versionable: common.NewVersionable(), + Labels: d.Labels, + Notify: &d.Notify, } + if d.Id != "" { + dto.Id = &d.Id + } + if d.Name != "" { + dto.Name = &d.Name + } + if d.Description != "" { + dto.Description = &d.Description + } + if d.AdminState != "" { + adminState := string(d.AdminState) + dto.AdminState = &adminState + } + if d.OperatingState != "" { + operatingState := string(d.OperatingState) + dto.OperatingState = &operatingState + } + if d.LastConnected != 0 { + dto.LastConnected = &d.LastConnected + } + if d.LastReported != 0 { + dto.LastReported = &d.LastReported + } + if d.ServiceName != "" { + dto.ServiceName = &d.ServiceName + } + if d.ProfileName != "" { + dto.ProfileName = &d.ProfileName + } + if d.Location != nil { + dto.Location = d.Location + } + if d.AutoEvents != nil { + dto.AutoEvents = FromAutoEventModelsToDTOs(d.AutoEvents) + } + if d.Protocols != nil { + dto.Protocols = FromProtocolModelsToDTOs(d.Protocols) + } + return dto } diff --git a/v2/dtos/device_test.go b/v2/dtos/device_test.go new file mode 100644 index 00000000..fd2dd630 --- /dev/null +++ b/v2/dtos/device_test.go @@ -0,0 +1,33 @@ +// +// Copyright (C) 2021 IOTech Ltd +// +// SPDX-License-Identifier: Apache-2.0 + +package dtos + +import ( + "testing" + + "github.com/edgexfoundry/go-mod-core-contracts/v2/v2" + "github.com/edgexfoundry/go-mod-core-contracts/v2/v2/models" + + "github.com/stretchr/testify/assert" +) + +func TestFromDeviceModelToUpdateDTO(t *testing.T) { + model := models.Device{} + dto := FromDeviceModelToUpdateDTO(model) + assert.Equal(t, v2.ApiVersion, dto.ApiVersion) + assert.Nil(t, dto.Id) + assert.Nil(t, dto.Name) + assert.Nil(t, dto.Description) + assert.Nil(t, dto.AdminState) + assert.Nil(t, dto.OperatingState) + assert.Nil(t, dto.LastConnected) + assert.Nil(t, dto.LastReported) + assert.Nil(t, dto.ServiceName) + assert.Nil(t, dto.ProfileName) + assert.Nil(t, dto.Location) + assert.Nil(t, dto.AutoEvents) + assert.Nil(t, dto.Protocols) +} diff --git a/v2/dtos/deviceservice.go b/v2/dtos/deviceservice.go index af6217b4..b13739bf 100644 --- a/v2/dtos/deviceservice.go +++ b/v2/dtos/deviceservice.go @@ -68,13 +68,22 @@ func FromDeviceServiceModelToDTO(ds models.DeviceService) DeviceService { // FromDeviceServiceModelToUpdateDTO transforms the DeviceService Model to the UpdateDeviceService DTO func FromDeviceServiceModelToUpdateDTO(ds models.DeviceService) UpdateDeviceService { - adminState := string(ds.AdminState) - return UpdateDeviceService{ + dto := UpdateDeviceService{ Versionable: common.NewVersionable(), - Id: &ds.Id, - Name: &ds.Name, - BaseAddress: &ds.BaseAddress, Labels: ds.Labels, - AdminState: &adminState, } + if ds.Id != "" { + dto.Id = &ds.Id + } + if ds.Name != "" { + dto.Name = &ds.Name + } + if ds.BaseAddress != "" { + dto.BaseAddress = &ds.BaseAddress + } + if ds.AdminState != "" { + adminState := string(ds.AdminState) + dto.AdminState = &adminState + } + return dto } diff --git a/v2/dtos/deviceservice_test.go b/v2/dtos/deviceservice_test.go new file mode 100644 index 00000000..902ea0c3 --- /dev/null +++ b/v2/dtos/deviceservice_test.go @@ -0,0 +1,26 @@ +// +// Copyright (C) 2021 IOTech Ltd +// +// SPDX-License-Identifier: Apache-2.0 + +package dtos + +import ( + "testing" + + "github.com/edgexfoundry/go-mod-core-contracts/v2/v2" + "github.com/edgexfoundry/go-mod-core-contracts/v2/v2/models" + + "github.com/stretchr/testify/assert" +) + +func TestFromDeviceServiceModelToUpdateDTO(t *testing.T) { + model := models.DeviceService{} + dto := FromDeviceServiceModelToUpdateDTO(model) + assert.Equal(t, v2.ApiVersion, dto.ApiVersion) + assert.Nil(t, dto.Id) + assert.Nil(t, dto.Name) + assert.Nil(t, dto.Labels) + assert.Nil(t, dto.BaseAddress) + assert.Nil(t, dto.AdminState) +} diff --git a/v2/dtos/provisionwatcher.go b/v2/dtos/provisionwatcher.go index 2d6bed1e..8852e258 100644 --- a/v2/dtos/provisionwatcher.go +++ b/v2/dtos/provisionwatcher.go @@ -74,17 +74,30 @@ func FromProvisionWatcherModelToDTO(pw models.ProvisionWatcher) ProvisionWatcher // FromProvisionWatcherModelToUpdateDTO transforms the ProvisionWatcher Model to the UpdateProvisionWatcher DTO func FromProvisionWatcherModelToUpdateDTO(pw models.ProvisionWatcher) UpdateProvisionWatcher { - adminState := string(pw.AdminState) - return UpdateProvisionWatcher{ + dto := UpdateProvisionWatcher{ Versionable: common.NewVersionable(), - Id: &pw.Id, - Name: &pw.Name, Labels: pw.Labels, Identifiers: pw.Identifiers, BlockingIdentifiers: pw.BlockingIdentifiers, - ProfileName: &pw.ProfileName, - ServiceName: &pw.ServiceName, - AdminState: &adminState, - AutoEvents: FromAutoEventModelsToDTOs(pw.AutoEvents), } + if pw.Id != "" { + dto.Id = &pw.Id + } + if pw.Name != "" { + dto.Name = &pw.Name + } + if pw.ProfileName != "" { + dto.ProfileName = &pw.ProfileName + } + if pw.ServiceName != "" { + dto.ServiceName = &pw.ServiceName + } + if pw.AdminState != "" { + adminState := string(pw.AdminState) + dto.AdminState = &adminState + } + if pw.AutoEvents != nil { + dto.AutoEvents = FromAutoEventModelsToDTOs(pw.AutoEvents) + } + return dto } diff --git a/v2/dtos/provisionwatcher_test.go b/v2/dtos/provisionwatcher_test.go new file mode 100644 index 00000000..ec9558a5 --- /dev/null +++ b/v2/dtos/provisionwatcher_test.go @@ -0,0 +1,30 @@ +// +// Copyright (C) 2021 IOTech Ltd +// +// SPDX-License-Identifier: Apache-2.0 + +package dtos + +import ( + "testing" + + "github.com/edgexfoundry/go-mod-core-contracts/v2/v2" + "github.com/edgexfoundry/go-mod-core-contracts/v2/v2/models" + + "github.com/stretchr/testify/assert" +) + +func TestFromProvisionWatcherModelToUpdateDTO(t *testing.T) { + model := models.ProvisionWatcher{} + dto := FromProvisionWatcherModelToUpdateDTO(model) + assert.Equal(t, v2.ApiVersion, dto.ApiVersion) + assert.Nil(t, dto.Id) + assert.Nil(t, dto.Name) + assert.Nil(t, dto.Labels) + assert.Nil(t, dto.Identifiers) + assert.Nil(t, dto.BlockingIdentifiers) + assert.Nil(t, dto.ProfileName) + assert.Nil(t, dto.ServiceName) + assert.Nil(t, dto.AdminState) + assert.Nil(t, dto.AutoEvents) +} diff --git a/v2/dtos/reading.go b/v2/dtos/reading.go index bdfc8d09..3592f618 100644 --- a/v2/dtos/reading.go +++ b/v2/dtos/reading.go @@ -42,7 +42,7 @@ type SimpleReading struct { // BinaryReading and its properties are defined in the APIv2 specification: // https://app.swaggerhub.com/apis-docs/EdgeXFoundry1/core-data/2.x#/BinaryReading type BinaryReading struct { - BinaryValue []byte `json:"binaryValue" validate:"gt=0,dive,required"` + BinaryValue []byte `json:"binaryValue" validate:"gt=0,required"` MediaType string `json:"mediaType" validate:"required"` }