diff --git a/go.mod b/go.mod index 3d04a470f..02d2c76cb 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( 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 v0.0.37 - github.com/edgexfoundry/go-mod-core-contracts v0.1.77 + github.com/edgexfoundry/go-mod-core-contracts v0.1.80 github.com/edgexfoundry/go-mod-messaging v0.1.21 github.com/edgexfoundry/go-mod-registry v0.1.21 github.com/edgexfoundry/go-mod-secrets v0.0.19 diff --git a/internal/v2/controller/http/controller.go b/internal/v2/controller/http/controller.go index a08791191..d00602d7d 100644 --- a/internal/v2/controller/http/controller.go +++ b/internal/v2/controller/http/controller.go @@ -24,6 +24,7 @@ import ( "github.com/edgexfoundry/go-mod-core-contracts/clients" "github.com/edgexfoundry/go-mod-core-contracts/clients/logger" + "github.com/edgexfoundry/go-mod-core-contracts/errors" contractsV2 "github.com/edgexfoundry/go-mod-core-contracts/v2" "github.com/edgexfoundry/go-mod-core-contracts/v2/dtos/common" "github.com/gorilla/mux" @@ -94,15 +95,15 @@ func (v2c *V2HttpController) Config(writer http.ResponseWriter, request *http.Re // Metrics handles the request to the /metrics endpoint, memory and cpu utilization stats // It returns a response as specified by the V2 API swagger in openapi/v2 func (v2c *V2HttpController) Metrics(writer http.ResponseWriter, request *http.Request) { - telem := telemetry.NewSystemUsage() + t := telemetry.NewSystemUsage() metrics := common.Metrics{ - MemAlloc: telem.Memory.Alloc, - MemFrees: telem.Memory.Frees, - MemLiveObjects: telem.Memory.LiveObjects, - MemMallocs: telem.Memory.Mallocs, - MemSys: telem.Memory.Sys, - MemTotalAlloc: telem.Memory.TotalAlloc, - CpuBusyAvg: uint8(telem.CpuBusyAvg), + MemAlloc: t.Memory.Alloc, + MemFrees: t.Memory.Frees, + MemLiveObjects: t.Memory.LiveObjects, + MemMallocs: t.Memory.Mallocs, + MemSys: t.Memory.Sys, + MemTotalAlloc: t.Memory.TotalAlloc, + CpuBusyAvg: uint8(t.CpuBusyAvg), } response := common.NewMetricsResponse(metrics) @@ -119,17 +120,14 @@ func (v2c *V2HttpController) Secrets(writer http.ResponseWriter, request *http.R secretRequest := requests.SecretsRequest{} err := json.NewDecoder(request.Body).Decode(&secretRequest) if err != nil { - response := common.NewBaseResponse("unknown", err.Error(), http.StatusBadRequest) - v2c.sendResponse(writer, request, internal.ApiV2SecretsRoute, response, http.StatusBadRequest) + v2c.sendError(writer, request, errors.KindContractInvalid, "JSON decode failed", err, "") return } path, secrets := v2c.prepareSecrets(secretRequest) if err := v2c.secretProvider.StoreSecrets(path, secrets); err != nil { - msg := fmt.Sprintf("Storing secrets failed: %v", err) - response := common.NewBaseResponse(secretRequest.RequestID, msg, http.StatusInternalServerError) - v2c.sendResponse(writer, request, internal.ApiV2SecretsRoute, response, http.StatusInternalServerError) + v2c.sendError(writer, request, errors.KindServerError, "Storing secrets failed", err, secretRequest.RequestID) return } @@ -137,6 +135,20 @@ func (v2c *V2HttpController) Secrets(writer http.ResponseWriter, request *http.R v2c.sendResponse(writer, request, internal.ApiV2SecretsRoute, response, http.StatusCreated) } +func (v2c *V2HttpController) sendError( + writer http.ResponseWriter, + request *http.Request, + errKind errors.ErrKind, + message string, + err error, + requestID string) { + edgexErr := errors.NewCommonEdgeX(errKind, message, err) + v2c.lc.Error(edgexErr.Error()) + v2c.lc.Debug(edgexErr.DebugMessages()) + response := common.NewBaseResponse(requestID, edgexErr.Message(), edgexErr.Code()) + v2c.sendResponse(writer, request, internal.ApiV2SecretsRoute, response, edgexErr.Code()) +} + // sendResponse puts together the response packet for the V2 API func (v2c *V2HttpController) sendResponse( writer http.ResponseWriter, @@ -174,7 +186,7 @@ func (v2c *V2HttpController) prepareSecrets(request requests.SecretsRequest) (st path := strings.TrimSpace(request.Path) - // add '/' in the full URL path if it's not already at the end of the basepath or subpath + // add '/' in the full URL path if it's not already at the end of the base path or sub path if !strings.HasSuffix(v2c.config.SecretStoreExclusive.Path, "/") && !strings.HasPrefix(path, "/") { path = "/" + path } else if strings.HasSuffix(v2c.config.SecretStoreExclusive.Path, "/") && strings.HasPrefix(path, "/") { diff --git a/internal/v2/dtos/requests/secrets.go b/internal/v2/dtos/requests/secrets.go index 83d91912a..ca31b88a3 100644 --- a/internal/v2/dtos/requests/secrets.go +++ b/internal/v2/dtos/requests/secrets.go @@ -19,6 +19,7 @@ package requests import ( "encoding/json" + "github.com/edgexfoundry/go-mod-core-contracts/errors" v2 "github.com/edgexfoundry/go-mod-core-contracts/v2" "github.com/edgexfoundry/go-mod-core-contracts/v2/dtos/common" ) @@ -53,14 +54,14 @@ func (sr *SecretsRequest) UnmarshalJSON(b []byte) error { } if err := json.Unmarshal(b, &alias); err != nil { - return v2.NewErrContractInvalid("Failed to unmarshal request body as JSON.") + return errors.NewCommonEdgeX(errors.KindContractInvalid, "Failed to unmarshal SecretsRequest body as JSON.", err) } *sr = SecretsRequest(alias) // validate SecretsRequest DTO if err := sr.Validate(); err != nil { - return err + return errors.NewCommonEdgeX(errors.KindContractInvalid, "SecretsRequest validation failed.", err) } return nil } diff --git a/internal/v2/dtos/requests/secrets_test.go b/internal/v2/dtos/requests/secrets_test.go index 8363f1103..4dd0ff611 100644 --- a/internal/v2/dtos/requests/secrets_test.go +++ b/internal/v2/dtos/requests/secrets_test.go @@ -20,6 +20,7 @@ import ( "encoding/json" "testing" + "github.com/edgexfoundry/go-mod-core-contracts/errors" "github.com/edgexfoundry/go-mod-core-contracts/v2/dtos/common" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -76,7 +77,12 @@ func TestSecretsRequest_Validate(t *testing.T) { for _, testCase := range tests { t.Run(testCase.Name, func(t *testing.T) { err := testCase.Request.Validate() - assert.Equal(t, testCase.ErrorExpected, err != nil, "Unexpected addDeviceRequest validation result.", err) + if testCase.ErrorExpected { + require.Error(t, err) + return // Test complete + } + + require.NoError(t, err) }) } } @@ -89,10 +95,11 @@ func TestSecretsRequest_UnmarshalJSON(t *testing.T) { Expected SecretsRequest Data []byte ErrorExpected bool + ErrorKind errors.ErrKind }{ - {"unmarshal with success", validRequest, resultTestBytes, false}, - {"unmarshal invalid, empty data", SecretsRequest{}, []byte{}, true}, - {"unmarshal invalid, non-json data", SecretsRequest{}, []byte("Invalid SecretsRequest"), true}, + {"unmarshal with success", validRequest, resultTestBytes, false, ""}, + {"unmarshal invalid, empty data", SecretsRequest{}, []byte{}, true, errors.KindContractInvalid}, + {"unmarshal invalid, non-json data", SecretsRequest{}, []byte("Invalid SecretsRequest"), true, errors.KindContractInvalid}, } for _, testCase := range tests { @@ -101,12 +108,12 @@ func TestSecretsRequest_UnmarshalJSON(t *testing.T) { err := actual.UnmarshalJSON(testCase.Data) if testCase.ErrorExpected { require.Error(t, err) + require.Equal(t, testCase.ErrorKind, errors.Kind(err)) return // Test complete } require.NoError(t, err) assert.Equal(t, testCase.Expected, actual, "Unmarshal did not result in expected SecretsRequest.") - }) } }