Skip to content

chore: Update casc core library to prevent concurrent header reads and writes #1889

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.24.1

require (
github.com/anknown/ahocorasick v0.0.0-20190904063843-d75dbd5169c0
github.com/dynatrace/dynatrace-configuration-as-code-core v0.8.1-0.20250424104703-ba9c6e8f54a3
github.com/dynatrace/dynatrace-configuration-as-code-core v0.8.1-0.20250513141605-42a12bc493b4
github.com/go-logr/logr v1.4.2
github.com/go-logr/zapr v1.3.0
github.com/google/go-cmp v0.7.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx2
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dynatrace/dynatrace-configuration-as-code-core v0.8.1-0.20250424104703-ba9c6e8f54a3 h1:Tmx58EW3EMFltVW6kCwYfPO3RaK46FbFf2XqC+eOy1s=
github.com/dynatrace/dynatrace-configuration-as-code-core v0.8.1-0.20250424104703-ba9c6e8f54a3/go.mod h1:bOIcK+LsuiLcyqA8XifLSVyfD+zCLnhQJEfPCqnEy2I=
github.com/dynatrace/dynatrace-configuration-as-code-core v0.8.1-0.20250513141605-42a12bc493b4 h1:89lad2SLobZ8pK1F9ypJDUU+TlSaix4A43NMGQJKCZY=
github.com/dynatrace/dynatrace-configuration-as-code-core v0.8.1-0.20250513141605-42a12bc493b4/go.mod h1:3cRc4TbyVxH62R7GwIvvOgOoOQ4R2EnZa6wWjOD7jCQ=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
Expand Down
13 changes: 6 additions & 7 deletions pkg/client/clientset.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import (
"github.com/dynatrace/dynatrace-configuration-as-code-core/clients/buckets"
"github.com/dynatrace/dynatrace-configuration-as-code-core/clients/documents"
"github.com/dynatrace/dynatrace-configuration-as-code-core/clients/openpipeline"
"github.com/dynatrace/dynatrace-configuration-as-code-core/clients/segments"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/cmd/monaco/supportarchive"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/internal/environment"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/internal/log"
Expand Down Expand Up @@ -183,12 +182,12 @@ type OpenPipelineClient interface {
}

type SegmentClient interface {
List(ctx context.Context) (segments.Response, error)
GetAll(ctx context.Context) ([]segments.Response, error)
Delete(ctx context.Context, id string) (segments.Response, error)
Create(ctx context.Context, data []byte) (segments.Response, error)
Update(ctx context.Context, id string, data []byte) (segments.Response, error)
Get(ctx context.Context, id string) (segments.Response, error)
List(ctx context.Context) (libAPI.Response, error)
GetAll(ctx context.Context) ([]libAPI.Response, error)
Delete(ctx context.Context, id string) (libAPI.Response, error)
Create(ctx context.Context, data []byte) (libAPI.Response, error)
Update(ctx context.Context, id string, data []byte) (libAPI.Response, error)
Get(ctx context.Context, id string) (libAPI.Response, error)
}

type ServiceLevelObjectiveClient interface {
Expand Down
25 changes: 12 additions & 13 deletions pkg/client/dummy_clientset.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
"github.com/dynatrace/dynatrace-configuration-as-code-core/clients/buckets"
"github.com/dynatrace/dynatrace-configuration-as-code-core/clients/documents"
"github.com/dynatrace/dynatrace-configuration-as-code-core/clients/openpipeline"
"github.com/dynatrace/dynatrace-configuration-as-code-core/clients/segments"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/pkg/client/dtclient"
)

Expand Down Expand Up @@ -161,28 +160,28 @@ func (c *DummyOpenPipelineClient) Update(_ context.Context, _ string, _ []byte)

type DummySegmentClient struct{}

func (c *DummySegmentClient) List(_ context.Context) (segments.Response, error) {
return segments.Response{}, nil
func (c *DummySegmentClient) List(_ context.Context) (api.Response, error) {
return api.Response{}, nil
}

func (c *DummySegmentClient) GetAll(_ context.Context) ([]segments.Response, error) {
return []segments.Response{}, nil
func (c *DummySegmentClient) GetAll(_ context.Context) ([]api.Response, error) {
return []api.Response{}, nil
}

func (c *DummySegmentClient) Delete(_ context.Context, _ string) (segments.Response, error) {
return segments.Response{}, nil
func (c *DummySegmentClient) Delete(_ context.Context, _ string) (api.Response, error) {
return api.Response{}, nil
}

func (c *DummySegmentClient) Create(_ context.Context, _ []byte) (segments.Response, error) {
return segments.Response{Data: []byte(`{}`)}, nil
func (c *DummySegmentClient) Create(_ context.Context, _ []byte) (api.Response, error) {
return api.Response{Data: []byte(`{}`)}, nil
}

func (c *DummySegmentClient) Update(_ context.Context, _ string, _ []byte) (segments.Response, error) {
return segments.Response{}, nil
func (c *DummySegmentClient) Update(_ context.Context, _ string, _ []byte) (api.Response, error) {
return api.Response{}, nil
}

func (c *DummySegmentClient) Get(_ context.Context, _ string) (segments.Response, error) {
return segments.Response{}, nil
func (c *DummySegmentClient) Get(_ context.Context, _ string) (api.Response, error) {
return api.Response{}, nil
}

type DummyServiceLevelObjectClient struct{}
Expand Down
25 changes: 12 additions & 13 deletions pkg/client/test_clientset.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,34 +22,33 @@ import (

"github.com/dynatrace/dynatrace-configuration-as-code-core/api"
"github.com/dynatrace/dynatrace-configuration-as-code-core/clients/openpipeline"
"github.com/dynatrace/dynatrace-configuration-as-code-core/clients/segments"
)

// TestSegmentsClient is a fake client that returns an unimplemented error on every execution of any method.
type TestSegmentsClient struct{}

func (TestSegmentsClient) List(ctx context.Context) (segments.Response, error) {
return segments.Response{}, fmt.Errorf("unimplemented")
func (TestSegmentsClient) List(ctx context.Context) (api.Response, error) {
return api.Response{}, fmt.Errorf("unimplemented")
}

func (TestSegmentsClient) GetAll(ctx context.Context) ([]segments.Response, error) {
return []segments.Response{}, fmt.Errorf("unimplemented")
func (TestSegmentsClient) GetAll(ctx context.Context) ([]api.Response, error) {
return []api.Response{}, fmt.Errorf("unimplemented")
}

func (TestSegmentsClient) Delete(ctx context.Context, id string) (segments.Response, error) {
return segments.Response{}, fmt.Errorf("unimplemented")
func (TestSegmentsClient) Delete(ctx context.Context, id string) (api.Response, error) {
return api.Response{}, fmt.Errorf("unimplemented")
}

func (TestSegmentsClient) Update(ctx context.Context, id string, data []byte) (segments.Response, error) {
return segments.Response{}, fmt.Errorf("unimplemented")
func (TestSegmentsClient) Update(ctx context.Context, id string, data []byte) (api.Response, error) {
return api.Response{}, fmt.Errorf("unimplemented")
}

func (TestSegmentsClient) Create(ctx context.Context, data []byte) (segments.Response, error) {
return segments.Response{}, nil
func (TestSegmentsClient) Create(ctx context.Context, data []byte) (api.Response, error) {
return api.Response{}, nil
}

func (TestSegmentsClient) Get(ctx context.Context, id string) (segments.Response, error) {
return segments.Response{}, fmt.Errorf("unimplemented")
func (TestSegmentsClient) Get(ctx context.Context, id string) (api.Response, error) {
return api.Response{}, fmt.Errorf("unimplemented")
}

// TestServiceLevelObjectiveClient is a fake client that returns an unimplemented error on every execution of any method.
Expand Down
5 changes: 2 additions & 3 deletions pkg/delete/internal/segment/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"fmt"

"github.com/dynatrace/dynatrace-configuration-as-code-core/api"
"github.com/dynatrace/dynatrace-configuration-as-code-core/clients/segments"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/internal/idutils"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/internal/log"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/internal/log/field"
Expand All @@ -32,8 +31,8 @@ import (
)

type client interface {
List(ctx context.Context) (segments.Response, error)
Delete(ctx context.Context, id string) (segments.Response, error)
List(ctx context.Context) (api.Response, error)
Delete(ctx context.Context, id string) (api.Response, error)
}

func Delete(ctx context.Context, c client, dps []pointer.DeletePointer) error {
Expand Down
65 changes: 32 additions & 33 deletions pkg/delete/internal/segment/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,22 @@ import (
"github.com/stretchr/testify/assert"

libAPI "github.com/dynatrace/dynatrace-configuration-as-code-core/api"
libSegment "github.com/dynatrace/dynatrace-configuration-as-code-core/clients/segments"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/internal/idutils"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/pkg/delete/internal/segment"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/pkg/delete/pointer"
)

type stubClient struct {
called bool
delete func(id string) (libSegment.Response, error)
list func() (libSegment.Response, error)
delete func(id string) (libAPI.Response, error)
list func() (libAPI.Response, error)
}

func (s *stubClient) List(_ context.Context) (libSegment.Response, error) {
func (s *stubClient) List(_ context.Context) (libAPI.Response, error) {
return s.list()
}

func (s *stubClient) Delete(_ context.Context, id string) (libSegment.Response, error) {
func (s *stubClient) Delete(_ context.Context, id string) (libAPI.Response, error) {
s.called = true
return s.delete(id)
}
Expand All @@ -59,12 +58,12 @@ func TestDeleteByCoordinate(t *testing.T) {
externalID := idutils.GenerateExternalID(given.AsCoordinate())

c := stubClient{
list: func() (libSegment.Response, error) {
return libSegment.Response{Data: []byte(fmt.Sprintf(`[{"uid": "uid_1", "externalId":"%s"},{"uid": "uid_2", "externalId":"wrong"}]`, externalID))}, nil
list: func() (libAPI.Response, error) {
return libAPI.Response{Data: []byte(fmt.Sprintf(`[{"uid": "uid_1", "externalId":"%s"},{"uid": "uid_2", "externalId":"wrong"}]`, externalID))}, nil
},
delete: func(id string) (libSegment.Response, error) {
delete: func(id string) (libAPI.Response, error) {
assert.Equal(t, "uid_1", id)
return libSegment.Response{}, nil
return libAPI.Response{}, nil
},
}

Expand All @@ -81,8 +80,8 @@ func TestDeleteByCoordinate(t *testing.T) {
}

c := stubClient{
list: func() (libSegment.Response, error) {
return libSegment.Response{Data: []byte(`[{"uid": "uid_2", "externalId":"wrong"}]`)}, nil
list: func() (libAPI.Response, error) {
return libAPI.Response{Data: []byte(`[{"uid": "uid_2", "externalId":"wrong"}]`)}, nil
},
}

Expand All @@ -99,8 +98,8 @@ func TestDeleteByCoordinate(t *testing.T) {

externalID := idutils.GenerateExternalID(given.AsCoordinate())
c := stubClient{
list: func() (libSegment.Response, error) {
return libSegment.Response{Data: []byte(fmt.Sprintf(`[{"uid": "uid_1", "externalId":"%s"},{"uid": "uid_2", "externalId":"%s"}]`, externalID, externalID))}, nil
list: func() (libAPI.Response, error) {
return libAPI.Response{Data: []byte(fmt.Sprintf(`[{"uid": "uid_1", "externalId":"%s"},{"uid": "uid_2", "externalId":"%s"}]`, externalID, externalID))}, nil
},
}

Expand All @@ -117,8 +116,8 @@ func TestDeleteByCoordinate(t *testing.T) {
}

c := stubClient{
list: func() (libSegment.Response, error) {
return libSegment.Response{}, errors.New("some unpredictable error")
list: func() (libAPI.Response, error) {
return libAPI.Response{}, errors.New("some unpredictable error")
},
}

Expand All @@ -135,9 +134,9 @@ func TestDeleteByObjectId(t *testing.T) {
}

c := stubClient{
delete: func(id string) (libSegment.Response, error) {
delete: func(id string) (libAPI.Response, error) {
assert.Equal(t, given.OriginObjectId, id)
return libSegment.Response{}, nil
return libAPI.Response{}, nil
},
}

Expand All @@ -153,7 +152,7 @@ func TestDeleteByObjectId(t *testing.T) {
}

c := stubClient{
delete: func(id string) (libSegment.Response, error) {
delete: func(id string) (libAPI.Response, error) {
assert.Equal(t, given.OriginObjectId, id)
return libAPI.Response{}, libAPI.APIError{StatusCode: http.StatusNotFound}
},
Expand All @@ -171,8 +170,8 @@ func TestDeleteByObjectId(t *testing.T) {
}

c := stubClient{
delete: func(_ string) (libSegment.Response, error) {
return libSegment.Response{}, errors.New("some unpredictable error")
delete: func(_ string) (libAPI.Response, error) {
return libAPI.Response{}, errors.New("some unpredictable error")
},
}

Expand All @@ -188,7 +187,7 @@ func TestDeleteByObjectId(t *testing.T) {
}

c := stubClient{
delete: func(_ string) (libSegment.Response, error) {
delete: func(_ string) (libAPI.Response, error) {
return libAPI.Response{}, libAPI.APIError{StatusCode: http.StatusInternalServerError}
},
}
Expand All @@ -205,11 +204,11 @@ func TestDeleteByObjectId(t *testing.T) {
}

c := stubClient{
delete: func(uid string) (libSegment.Response, error) {
delete: func(uid string) (libAPI.Response, error) {
if uid == given.OriginObjectId {
return libSegment.Response{}, nil
return libAPI.Response{}, nil
}
return libSegment.Response{}, errors.New("some unpredictable error")
return libAPI.Response{}, errors.New("some unpredictable error")
},
}

Expand All @@ -221,12 +220,12 @@ func TestDeleteByObjectId(t *testing.T) {
func TestDeleteAll(t *testing.T) {
t.Run("simple case", func(t *testing.T) {
c := stubClient{
list: func() (libSegment.Response, error) {
return libSegment.Response{Data: []byte(`[{"uid": "uid_1"},{"uid": "uid_2"},{"uid": "uid_3"}]`)}, nil
list: func() (libAPI.Response, error) {
return libAPI.Response{Data: []byte(`[{"uid": "uid_1"},{"uid": "uid_2"},{"uid": "uid_3"}]`)}, nil
},
delete: func(uid string) (libSegment.Response, error) {
delete: func(uid string) (libAPI.Response, error) {
assert.Contains(t, []string{"uid_1", "uid_2", "uid_3"}, uid)
return libSegment.Response{StatusCode: http.StatusOK}, nil
return libAPI.Response{StatusCode: http.StatusOK}, nil
},
}

Expand All @@ -236,15 +235,15 @@ func TestDeleteAll(t *testing.T) {

t.Run("deletion continues even if error occurs during delete", func(t *testing.T) {
c := stubClient{
list: func() (libSegment.Response, error) {
return libSegment.Response{Data: []byte(`[{"uid": "uid_1"},{"uid": "uid_2"},{"uid": "uid_3"}]`)}, nil
list: func() (libAPI.Response, error) {
return libAPI.Response{Data: []byte(`[{"uid": "uid_1"},{"uid": "uid_2"},{"uid": "uid_3"}]`)}, nil
},
delete: func(uid string) (libSegment.Response, error) {
delete: func(uid string) (libAPI.Response, error) {
assert.Contains(t, []string{"uid_1", "uid_2", "uid_3"}, uid)
if uid == "uid_2" {
return libSegment.Response{}, errors.New("some unpredictable error")
return libAPI.Response{}, errors.New("some unpredictable error")
}
return libSegment.Response{StatusCode: http.StatusOK}, nil
return libAPI.Response{StatusCode: http.StatusOK}, nil
},
}

Expand Down
9 changes: 4 additions & 5 deletions pkg/deploy/internal/segment/segment.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
"github.com/go-logr/logr"

"github.com/dynatrace/dynatrace-configuration-as-code-core/api"
segment "github.com/dynatrace/dynatrace-configuration-as-code-core/clients/segments"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/internal/idutils"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/internal/log"
"github.com/dynatrace/dynatrace-configuration-as-code/v2/pkg/config"
Expand All @@ -35,9 +34,9 @@ import (
)

type deploySegmentClient interface {
Update(ctx context.Context, id string, data []byte) (segment.Response, error)
Create(ctx context.Context, data []byte) (segment.Response, error)
GetAll(ctx context.Context) ([]segment.Response, error)
Update(ctx context.Context, id string, data []byte) (api.Response, error)
Create(ctx context.Context, data []byte) (api.Response, error)
GetAll(ctx context.Context) ([]api.Response, error)
}
type jsonResponse struct {
UID string `json:"uid"`
Expand Down Expand Up @@ -133,7 +132,7 @@ func createResolveEntity(id string, properties parameter.Properties, c *config.C
}
}

func getJsonResponseFromSegmentsResponse(rawResponse segment.Response) (jsonResponse, error) {
func getJsonResponseFromSegmentsResponse(rawResponse api.Response) (jsonResponse, error) {
var response jsonResponse
err := json.Unmarshal(rawResponse.Data, &response)
if err != nil {
Expand Down
Loading
Loading