Skip to content

Commit

Permalink
refactor(v2): refactor V2 API to use new errors mechanism for go-mo-c…
Browse files Browse the repository at this point in the history
…ore-contracts

closes #487

Signed-off-by: lenny <[email protected]>
  • Loading branch information
lenny committed Sep 16, 2020
1 parent 6f19a0c commit b2857ff
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 22 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
40 changes: 26 additions & 14 deletions internal/v2/controller/http/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand All @@ -119,24 +120,35 @@ 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
}

response := common.NewBaseResponseNoMessage(secretRequest.RequestID, http.StatusCreated)
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,
Expand Down Expand Up @@ -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, "/") {
Expand Down
5 changes: 3 additions & 2 deletions internal/v2/dtos/requests/secrets.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand Down Expand Up @@ -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
}
17 changes: 12 additions & 5 deletions internal/v2/dtos/requests/secrets_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
})
}
}
Expand All @@ -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 {
Expand All @@ -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.")

})
}
}

0 comments on commit b2857ff

Please sign in to comment.