diff --git a/README.md b/README.md index 11809690..b538007f 100644 --- a/README.md +++ b/README.md @@ -321,13 +321,14 @@ external-endpoints: To push the status of an external endpoint, the request would have to look like this: ``` -POST /api/v1/endpoints/{key}/external?success={success}&error={error} +POST /api/v1/endpoints/{key}/external?success={success}&error={error}&duration={duration} ``` Where: - `{key}` has the pattern `_` in which both variables have ` `, `/`, `_`, `,`, `.` and `#` replaced by `-`. - Using the example configuration above, the key would be `core_ext-ep-test`. - `{success}` is a boolean (`true` or `false`) value indicating whether the health check was successful or not. -- `{error}`: a string describing the reason for a failed health check. If {success} is false, this should contain the error message; if the check is successful, it can be omitted or left empty. +- `{error}` (optional): a string describing the reason for a failed health check. If {success} is false, this should contain the error message; if the check is successful. +- `{duration}` (optional): the time that the request took as a duration string (e.g. 10s). You must also pass the token as a `Bearer` token in the `Authorization` header. diff --git a/api/external_endpoint.go b/api/external_endpoint.go index c6492933..18c08802 100644 --- a/api/external_endpoint.go +++ b/api/external_endpoint.go @@ -46,6 +46,14 @@ func CreateExternalEndpointResult(cfg *config.Config) fiber.Handler { Success: c.QueryBool("success"), Errors: []string{}, } + if len(c.Query("duration")) > 0 { + parsedDuration, err := time.ParseDuration(c.Query("duration")) + if err != nil { + logr.Errorf("[api.CreateExternalEndpointResult] Invalid duration from string=%s with error: %s", c.Query("duration"), err.Error()) + return c.Status(400).SendString("invalid duration: " + err.Error()) + } + result.Duration = parsedDuration + } if !result.Success && c.Query("error") != "" { result.Errors = append(result.Errors, c.Query("error")) } diff --git a/api/external_endpoint_test.go b/api/external_endpoint_test.go index d63ab6c0..9f1bd3a7 100644 --- a/api/external_endpoint_test.go +++ b/api/external_endpoint_test.go @@ -70,6 +70,12 @@ func TestCreateExternalEndpointResult(t *testing.T) { AuthorizationHeaderBearerToken: "Bearer token", ExpectedCode: 400, }, + { + Name: "bad-duration-value", + Path: "/api/v1/endpoints/g_n/external?success=true&duration=invalid", + AuthorizationHeaderBearerToken: "Bearer token", + ExpectedCode: 400, + }, { Name: "good-token-success-true", Path: "/api/v1/endpoints/g_n/external?success=true", @@ -82,6 +88,12 @@ func TestCreateExternalEndpointResult(t *testing.T) { AuthorizationHeaderBearerToken: "Bearer token", ExpectedCode: 200, }, + { + Name: "good-duration-success-true", + Path: "/api/v1/endpoints/g_n/external?success=true&duration=10s", + AuthorizationHeaderBearerToken: "Bearer token", + ExpectedCode: 200, + }, { Name: "good-token-success-false", Path: "/api/v1/endpoints/g_n/external?success=false", @@ -118,7 +130,7 @@ func TestCreateExternalEndpointResult(t *testing.T) { }) } t.Run("verify-end-results", func(t *testing.T) { - endpointStatus, err := store.Get().GetEndpointStatus("g", "n", paging.NewEndpointStatusParams().WithResults(1, 10)) + endpointStatus, err := store.Get().GetEndpointStatus("g", "n", paging.NewEndpointStatusParams().WithResults(1, 11)) if err != nil { t.Errorf("failed to get endpoint status: %s", err.Error()) return @@ -126,8 +138,8 @@ func TestCreateExternalEndpointResult(t *testing.T) { if endpointStatus.Key != "g_n" { t.Errorf("expected key to be g_n but got %s", endpointStatus.Key) } - if len(endpointStatus.Results) != 5 { - t.Errorf("expected 3 results but got %d", len(endpointStatus.Results)) + if len(endpointStatus.Results) != 6 { + t.Errorf("expected 6 results but got %d", len(endpointStatus.Results)) } if !endpointStatus.Results[0].Success { t.Errorf("expected first result to be successful") @@ -138,8 +150,8 @@ func TestCreateExternalEndpointResult(t *testing.T) { if len(endpointStatus.Results[1].Errors) > 0 { t.Errorf("expected second result to have no errors") } - if endpointStatus.Results[2].Success { - t.Errorf("expected third result to be unsuccessful") + if endpointStatus.Results[2].Duration == 0 || endpointStatus.Results[2].Duration.Seconds() != 10 { + t.Errorf("expected third result to have a duration of 10 seconds") } if endpointStatus.Results[3].Success { t.Errorf("expected fourth result to be unsuccessful") @@ -147,8 +159,11 @@ func TestCreateExternalEndpointResult(t *testing.T) { if endpointStatus.Results[4].Success { t.Errorf("expected fifth result to be unsuccessful") } - if len(endpointStatus.Results[4].Errors) == 0 || endpointStatus.Results[4].Errors[0] != "failed" { - t.Errorf("expected fifth result to have errors: failed") + if endpointStatus.Results[5].Success { + t.Errorf("expected sixth result to be unsuccessful") + } + if len(endpointStatus.Results[5].Errors) == 0 || endpointStatus.Results[5].Errors[0] != "failed" { + t.Errorf("expected sixth result to have errors: failed") } externalEndpointFromConfig := cfg.GetExternalEndpointByKey("g_n") if externalEndpointFromConfig.NumberOfFailuresInARow != 3 {