Skip to content

Commit

Permalink
Check type assertions and added GetStatusCode (#122)
Browse files Browse the repository at this point in the history
* Check type assertions and added GetStatusCode

* Use `GetStatusCode` in stream dashboard
  • Loading branch information
heidmotron authored Feb 8, 2023
1 parent 387c18e commit e98e687
Show file tree
Hide file tree
Showing 19 changed files with 201 additions and 29 deletions.
2 changes: 1 addition & 1 deletion .go-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.70.13
1.70.14
9 changes: 9 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Headers map[string]string

type APIResponseCarrier interface {
GetHTTPResponse() *http.Response
GetStatusCode() int
}

// APIClientError contains the HTTP Response(for inspection of the error code) as well as the error message
Expand All @@ -43,6 +44,14 @@ func (a APIClientError) GetHTTPResponse() *http.Response {
return a.Response
}

func (a APIClientError) GetStatusCode() int {
if a.Response == nil {
return -1 // not a known http status code
}

return a.Response.StatusCode
}

// Envelope represents a generic response from the API
type Envelope struct {
Data json.RawMessage `json:"data"`
Expand Down
4 changes: 2 additions & 2 deletions client/destinations.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ func (c *Client) GetDestination(ctx context.Context, projectName string, destina
func (c *Client) DeleteDestination(ctx context.Context, project string, destinationID string) error {
err := c.CallAPI(ctx, "DELETE", fmt.Sprintf("projects/%v/destinations/%v", project, destinationID), nil, nil)
if err != nil {
apiClientError := err.(APIResponseCarrier)
if apiClientError.GetHTTPResponse().StatusCode != http.StatusNoContent {
apiClientError, ok := err.(APIResponseCarrier)
if !ok || apiClientError.GetStatusCode() != http.StatusNoContent {
return err
}
}
Expand Down
45 changes: 45 additions & 0 deletions client/destinations_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package client

import (
"context"
"net/http"
"net/http/httptest"
"testing"

"github.com/stretchr/testify/assert"
)

func Test_DeleteDestionation_when_connection_is_closed(t *testing.T) {
var server *httptest.Server
server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "/public/v0.2/blars/projects/tacoman/destinations/hi", r.URL.Path)

server.CloseClientConnections()
}))
defer server.Close()

t.Setenv("LIGHTSTEP_API_BASE_URL", server.URL)
c := NewClient("api", "blars", "staging")
err := c.DeleteDestination(context.Background(), "tacoman", "hi")

assert.NotNil(t, err)

apiErr, ok := err.(APIClientError)

assert.True(t, ok)
assert.Equal(t, -1, apiErr.GetStatusCode())
}

func Test_DeleteDestination_when_connection_has_wrong_content_length(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Length", "1") // set content length to 1 so reading body fails
}))
defer server.Close()

t.Setenv("LIGHTSTEP_API_BASE_URL", server.URL)
c := NewClient("api", "blars", "staging")
err := c.DeleteDestination(context.Background(), "tacoman", "hi")

assert.NotNil(t, err)
assert.Equal(t, "unexpected EOF", err.Error())
}
4 changes: 2 additions & 2 deletions client/metric_conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ func (c *Client) DeleteMetricCondition(ctx context.Context, projectName string,

err := c.CallAPI(ctx, "DELETE", url, nil, nil)
if err != nil {
apiClientError := err.(APIResponseCarrier)
if apiClientError.GetHTTPResponse().StatusCode != http.StatusNoContent {
apiClientError, ok := err.(APIResponseCarrier)
if !ok || apiClientError.GetStatusCode() != http.StatusNoContent {
return err
}
}
Expand Down
45 changes: 45 additions & 0 deletions client/metric_conditions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package client

import (
"context"
"net/http"
"net/http/httptest"
"testing"

"github.com/stretchr/testify/assert"
)

func Test_DeleteMetricCondition_when_connection_is_closed(t *testing.T) {
var server *httptest.Server
server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "/public/v0.2/blars/projects/tacoman/metric_alerts/hi", r.URL.Path)

server.CloseClientConnections()
}))
defer server.Close()

t.Setenv("LIGHTSTEP_API_BASE_URL", server.URL)
c := NewClient("api", "blars", "staging")
err := c.DeleteMetricCondition(context.Background(), "tacoman", "hi")

assert.NotNil(t, err)

apiErr, ok := err.(APIClientError)

assert.True(t, ok)
assert.Equal(t, -1, apiErr.GetStatusCode())
}

func Test_DeleteMetricCondition_when_connection_has_wrong_content_length(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Length", "1") // set content length to 1 so reading body fails
}))
defer server.Close()

t.Setenv("LIGHTSTEP_API_BASE_URL", server.URL)
c := NewClient("api", "blars", "staging")
err := c.DeleteMetricCondition(context.Background(), "tacoman", "hi")

assert.NotNil(t, err)
assert.Equal(t, "unexpected EOF", err.Error())
}
4 changes: 2 additions & 2 deletions client/metric_dashboards.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ func (c *Client) DeleteUnifiedDashboard(ctx context.Context, projectName string,

err := c.CallAPI(ctx, "DELETE", url, nil, nil)
if err != nil {
apiClientError := err.(APIResponseCarrier)
if apiClientError.GetHTTPResponse().StatusCode != http.StatusNoContent {
apiClientError, ok := err.(APIResponseCarrier)
if !ok || apiClientError.GetStatusCode() != http.StatusNoContent {
return err
}
}
Expand Down
38 changes: 38 additions & 0 deletions client/metric_dashboards_test.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package client

import (
"context"
"net/http"
"net/http/httptest"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -34,3 +38,37 @@ func Test_getUnifiedDashboardURL(t *testing.T) {
require.Equal(t, c.expected, result)
}
}

func Test_DeleteMetricDashboard_when_connection_is_closed(t *testing.T) {
var server *httptest.Server
server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "/public/v0.2/blars/projects/tacoman/metric_dashboards/hi", r.URL.Path)

server.CloseClientConnections()
}))
defer server.Close()

t.Setenv("LIGHTSTEP_API_BASE_URL", server.URL)
c := NewClient("api", "blars", "staging")
err := c.DeleteUnifiedDashboard(context.Background(), "tacoman", "hi")
assert.NotNil(t, err)

apiErr, ok := err.(APIClientError)

assert.True(t, ok)
assert.Equal(t, -1, apiErr.GetStatusCode())
}

func Test_DeleteMetricDashboard_when_connection_has_wrong_content_length(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Length", "1") // set content length to 1 so reading body fails
}))
defer server.Close()

t.Setenv("LIGHTSTEP_API_BASE_URL", server.URL)
c := NewClient("api", "blars", "staging")
err := c.DeleteUnifiedDashboard(context.Background(), "tacoman", "hi")

assert.NotNil(t, err)
assert.Equal(t, "unexpected EOF", err.Error())
}
4 changes: 2 additions & 2 deletions client/stream_alerting_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ func (c *Client) GetAlertingRule(ctx context.Context, projectName string, alerti
func (c *Client) DeleteAlertingRule(ctx context.Context, projectName string, alertingRuleID string) error {
err := c.CallAPI(ctx, "DELETE", fmt.Sprintf("projects/%v/alerting_rules/%v", projectName, alertingRuleID), nil, nil)
if err != nil {
apiClientError := err.(APIResponseCarrier)
if apiClientError.GetHTTPResponse().StatusCode != http.StatusNoContent {
apiClientError, ok := err.(APIResponseCarrier)
if !ok || apiClientError.GetStatusCode() != http.StatusNoContent {
return err
}
}
Expand Down
4 changes: 2 additions & 2 deletions client/stream_conditions.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ func (c *Client) GetStreamCondition(ctx context.Context, projectName string, con
func (c *Client) DeleteStreamCondition(ctx context.Context, projectName string, conditionID string) error {
err := c.CallAPI(ctx, "DELETE", fmt.Sprintf("projects/%v/conditions/%v", projectName, conditionID), nil, nil)
if err != nil {
apiClientError := err.(APIResponseCarrier)
if apiClientError.GetHTTPResponse().StatusCode != http.StatusNoContent {
apiClientError, ok := err.(APIResponseCarrier)
if !ok || apiClientError.GetStatusCode() != http.StatusNoContent {
return err
}
}
Expand Down
4 changes: 2 additions & 2 deletions client/stream_dashboards.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ func (c *Client) GetDashboard(ctx context.Context, projectName string, dashboard
func (c *Client) DeleteDashboard(ctx context.Context, projectName string, dashboardID string) error {
err := c.CallAPI(ctx, "DELETE", fmt.Sprintf("projects/%v/dashboards/%v", projectName, dashboardID), nil, nil)
if err != nil {
apiClientError := err.(APIResponseCarrier)
if apiClientError.GetHTTPResponse().StatusCode != http.StatusNoContent {
apiClientError, ok := err.(APIResponseCarrier)
if !ok || apiClientError.GetStatusCode() != http.StatusNoContent {
return err
}
}
Expand Down
4 changes: 2 additions & 2 deletions client/streams.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,8 @@ func (c *Client) UpdateStream(ctx context.Context, projectName string,
func (c *Client) DeleteStream(ctx context.Context, projectName string, StreamID string) error {
err := c.CallAPI(ctx, "DELETE", fmt.Sprintf("projects/%v/streams/%v", projectName, StreamID), nil, nil)
if err != nil {
apiClientError := err.(APIResponseCarrier)
if apiClientError.GetHTTPResponse().StatusCode != http.StatusNoContent {
apiClientError, ok := err.(APIResponseCarrier)
if !ok || apiClientError.GetStatusCode() != http.StatusNoContent {
return err
}
}
Expand Down
8 changes: 6 additions & 2 deletions lightstep/data_source_stream.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,12 @@ func dataSourceLightstepStreamRead(ctx context.Context, d *schema.ResourceData,
c := m.(*client.Client)
s, err := c.GetStream(ctx, d.Get("project_name").(string), d.Get("stream_id").(string))
if err != nil {
apiErr := err.(client.APIResponseCarrier)
if apiErr.GetHTTPResponse().StatusCode == http.StatusNotFound {
apiErr, ok := err.(client.APIResponseCarrier)
if !ok {
return diag.FromErr(fmt.Errorf("failed to get stream: %v", err))
}

if apiErr.GetStatusCode() == http.StatusNotFound {
d.SetId("")
return diag.FromErr(fmt.Errorf("stream not found: %v", apiErr))
}
Expand Down
12 changes: 9 additions & 3 deletions lightstep/resource_alerting_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,18 @@ func resourceAlertingRuleRead(ctx context.Context, d *schema.ResourceData, m int
c := m.(*client.Client)
rule, err := c.GetAlertingRule(ctx, d.Get("project_name").(string), d.Id())
if err != nil {
apiErr := err.(client.APIResponseCarrier)
if apiErr.GetHTTPResponse().StatusCode == http.StatusNotFound {
apiErr, ok := err.(client.APIResponseCarrier)

if !ok {
return diag.FromErr(fmt.Errorf("failed to get alerting rule: %v", err))
}

if apiErr.GetStatusCode() == http.StatusNotFound {
d.SetId("")
return diags
}
return diag.FromErr(fmt.Errorf("failed to get alerting rule: %v", apiErr))

return diag.FromErr(fmt.Errorf("failed to get alerting rule: %v", err))
}

if err := setResourceDataFromAlertingRule(d, *rule); err != nil {
Expand Down
9 changes: 7 additions & 2 deletions lightstep/resource_metric_condition.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,11 +333,16 @@ func resourceMetricConditionRead(ctx context.Context, d *schema.ResourceData, m
c := m.(*client.Client)
cond, err := c.GetMetricCondition(ctx, d.Get("project_name").(string), d.Id())
if err != nil {
apiErr := err.(client.APIResponseCarrier)
if apiErr.GetHTTPResponse().StatusCode == http.StatusNotFound {
apiErr, ok := err.(client.APIResponseCarrier)
if !ok {
return diag.FromErr(fmt.Errorf("failed to get metric condition: %v", err))
}

if apiErr.GetStatusCode() == http.StatusNotFound {
d.SetId("")
return diags
}

return diag.FromErr(fmt.Errorf("failed to get metric condition: %v", apiErr))
}

Expand Down
9 changes: 7 additions & 2 deletions lightstep/resource_metric_dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,16 @@ func (p *resourceUnifiedDashboardImp) resourceUnifiedDashboardRead(ctx context.C

dashboard, err := c.GetUnifiedDashboard(ctx, d.Get("project_name").(string), d.Id(), convertToQueryString)
if err != nil {
apiErr := err.(client.APIResponseCarrier)
if apiErr.GetHTTPResponse() != nil && apiErr.GetHTTPResponse().StatusCode == http.StatusNotFound {
apiErr, ok := err.(client.APIResponseCarrier)
if !ok {
return diag.FromErr(fmt.Errorf("failed to get dashboard: %v", err))
}

if apiErr.GetStatusCode() == http.StatusNotFound {
d.SetId("")
return diags
}

return diag.FromErr(fmt.Errorf("failed to get dashboard: %v", apiErr))
}

Expand Down
9 changes: 7 additions & 2 deletions lightstep/resource_slack_destination.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,16 @@ func resourceSlackDestinationRead(ctx context.Context, d *schema.ResourceData, m
c := m.(*client.Client)
dest, err := c.GetDestination(ctx, d.Get("project_name").(string), d.Id())
if err != nil {
apiErr := err.(client.APIResponseCarrier)
if apiErr.GetHTTPResponse().StatusCode == http.StatusNotFound {
apiErr, ok := err.(client.APIResponseCarrier)
if !ok {
return diag.FromErr(fmt.Errorf("failed to get slack destination: %v", err))
}

if apiErr.GetStatusCode() == http.StatusNotFound {
d.SetId("")
return diags
}

return diag.FromErr(fmt.Errorf("failed to get slack destination: %v", apiErr))
}

Expand Down
7 changes: 6 additions & 1 deletion lightstep/resource_stream_condition.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,16 @@ func resourceStreamConditionRead(ctx context.Context, d *schema.ResourceData, m
c := m.(*client.Client)
condition, err := c.GetStreamCondition(ctx, d.Get("project_name").(string), d.Id())
if err != nil {
apiErr := err.(client.APIResponseCarrier)
apiErr, ok := err.(client.APIResponseCarrier)
if !ok {
return diag.FromErr(fmt.Errorf("failed to get stream condition: %v", err))
}

if apiErr.GetHTTPResponse().StatusCode == http.StatusNotFound {
d.SetId("")
return diags
}

return diag.FromErr(fmt.Errorf("failed to get stream condition: %v", apiErr))
}

Expand Down
9 changes: 7 additions & 2 deletions lightstep/resource_stream_dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,16 @@ func resourceStreamDashboardRead(ctx context.Context, d *schema.ResourceData, m

dashboard, err := c.GetDashboard(ctx, projectName, resourceId)
if err != nil {
apiErr := err.(client.APIResponseCarrier)
if apiErr.GetHTTPResponse().StatusCode == http.StatusNotFound {
apiErr, ok := err.(client.APIResponseCarrier)
if !ok {
return diag.FromErr(fmt.Errorf("failed to get stream dashboard for [project: %v; resource_id: %v]: %v", projectName, resourceId, err))
}

if apiErr.GetStatusCode() == http.StatusNotFound {
d.SetId("")
return diags
}

return diag.FromErr(fmt.Errorf("failed to get stream dashboard for [project: %v; resource_id: %v]: %v", projectName, resourceId, apiErr))
}

Expand Down

0 comments on commit e98e687

Please sign in to comment.