Skip to content

fix: Endpoint configuration should also accept expressions #225

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

Merged
Merged
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
36 changes: 30 additions & 6 deletions model/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,9 @@ func (u *LiteralUri) GetValue() interface{} {
}

type EndpointConfiguration struct {
URI URITemplate `json:"uri" validate:"required"`
Authentication *ReferenceableAuthenticationPolicy `json:"authentication,omitempty"`
RuntimeExpression *RuntimeExpression `json:"-"`
URI URITemplate `json:"uri" validate:"required"`
Authentication *ReferenceableAuthenticationPolicy `json:"authentication,omitempty"`
}

// UnmarshalJSON implements custom unmarshalling for EndpointConfiguration.
Expand All @@ -116,12 +117,35 @@ func (e *EndpointConfiguration) UnmarshalJSON(data []byte) error {

// Unmarshal the URI field into the appropriate URITemplate implementation
uri, err := UnmarshalURITemplate(temp.URI)
if err != nil {
return fmt.Errorf("invalid URI in EndpointConfiguration: %w", err)
if err == nil {
e.URI = uri
return nil
}

var runtimeExpr RuntimeExpression
if err := json.Unmarshal(temp.URI, &runtimeExpr); err == nil && runtimeExpr.IsValid() {
e.RuntimeExpression = &runtimeExpr
return nil
}
e.URI = uri

return nil
return errors.New("failed to unmarshal EndpointConfiguration: data does not match any known schema")
}

// MarshalJSON implements custom marshalling for Endpoint.
func (e *EndpointConfiguration) MarshalJSON() ([]byte, error) {
m := make(map[string]interface{})
if e.Authentication != nil {
m["authentication"] = e.Authentication
}

if e.RuntimeExpression != nil {
m["uri"] = e.RuntimeExpression
} else if e.URI != nil {
m["uri"] = e.URI
}

// Return an empty JSON object when no fields are set
return json.Marshal(m)
}

type Endpoint struct {
Expand Down
42 changes: 42 additions & 0 deletions model/endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,48 @@ func TestEndpoint_UnmarshalJSON(t *testing.T) {
assert.Equal(t, "admin", endpoint.EndpointConfig.Authentication.AuthenticationPolicy.Basic.Password, "Authentication Password should match")
})

t.Run("Valid EndpointConfiguration with reference", func(t *testing.T) {
input := `{
"uri": "http://example.com/{id}",
"authentication": {
"oauth2": { "use": "secret" }
}
}`

var endpoint Endpoint
err := json.Unmarshal([]byte(input), &endpoint)

assert.NoError(t, err, "Unmarshal should not return an error")
assert.NotNil(t, endpoint.EndpointConfig, "EndpointConfig should be set")
assert.NotNil(t, endpoint.EndpointConfig.URI, "EndpointConfig URI should be set")
assert.Nil(t, endpoint.EndpointConfig.RuntimeExpression, "EndpointConfig Expression should not be set")
assert.Equal(t, "secret", endpoint.EndpointConfig.Authentication.AuthenticationPolicy.OAuth2.Use, "Authentication secret should match")
b, err := json.Marshal(&endpoint)
assert.NoError(t, err, "Marshal should not return an error")
assert.JSONEq(t, input, string(b), "Output JSON should match")
})

t.Run("Valid EndpointConfiguration with reference and expression", func(t *testing.T) {
input := `{
"uri": "${example}",
"authentication": {
"oauth2": { "use": "secret" }
}
}`

var endpoint Endpoint
err := json.Unmarshal([]byte(input), &endpoint)

assert.NoError(t, err, "Unmarshal should not return an error")
assert.NotNil(t, endpoint.EndpointConfig, "EndpointConfig should be set")
assert.Nil(t, endpoint.EndpointConfig.URI, "EndpointConfig URI should not be set")
assert.NotNil(t, endpoint.EndpointConfig.RuntimeExpression, "EndpointConfig Expression should be set")
assert.Equal(t, "secret", endpoint.EndpointConfig.Authentication.AuthenticationPolicy.OAuth2.Use, "Authentication secret should match")
b, err := json.Marshal(&endpoint)
assert.NoError(t, err, "Marshal should not return an error")
assert.JSONEq(t, input, string(b), "Output JSON should match")
})

t.Run("Invalid JSON Structure", func(t *testing.T) {
input := `{"invalid": "data"}`
var endpoint Endpoint
Expand Down
Loading