Skip to content

Commit

Permalink
support xml content type (#32)
Browse files Browse the repository at this point in the history
  • Loading branch information
hgiasac authored Nov 24, 2024
1 parent cd7fa66 commit 95bf571
Show file tree
Hide file tree
Showing 48 changed files with 7,402 additions and 1,131 deletions.
4 changes: 4 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ linters-settings:
# Default: 5
min-complexity: 10

gocritic:
disabled-checks:
- appendAssign

issues:
exclude-files:
- ".*_test\\.go$"
23 changes: 14 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,18 @@ The connector can automatically transform OpenAPI 2.0 and 3.0 definitions to NDC

**Supported content types**

- `application/json`
- `application/x-www-form-urlencoded`
- `application/octet-stream`
- `multipart/form-data`
- `application/x-ndjson`
- `text/*`
- Upload file content types, e.g.`image/*` from `base64` arguments.
| Content Type | Supported |
| --------------------------------- | --------- |
| application/json ||
| application/xml ||
| application/x-www-form-urlencoded ||
| multipart/form-data ||
| application/octet-stream | ✅ (\*) |
| text/\* ||
| application/x-ndjson ||
| image/\* | ✅ (\*) |

\*: Upload file content types are converted to `base64` encoding.

## Quick start

Expand Down Expand Up @@ -83,9 +88,9 @@ HTTP connector supports both OpenAPI 2 and 3 specifications.
- `oas3`: OpenAPI 3.0/3.1.
- `oas2`: OpenAPI 2.0.

#### HTTP schema
#### HTTP Connector schema

Enum: `http`
Enum: `ndc`

HTTP schema is the native configuration schema which other specs will be converted to behind the scene. The schema extends the NDC Specification with HTTP configuration and can be converted from other specs by the [NDC HTTP schema CLI](./ndc-http-schema).

Expand Down
6 changes: 2 additions & 4 deletions connector/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type HTTPConnector struct {
capabilities *schema.RawCapabilitiesResponse
rawSchema *schema.RawSchemaResponse
schema *rest.NDCHttpSchema
client *internal.HTTPClient
client internal.Doer
}

// NewHTTPConnector creates a HTTP connector instance
Expand All @@ -29,7 +29,7 @@ func NewHTTPConnector(opts ...Option) *HTTPConnector {
}

return &HTTPConnector{
client: internal.NewHTTPClient(defaultOptions.client),
client: defaultOptions.client,
}
}

Expand Down Expand Up @@ -93,8 +93,6 @@ func (c *HTTPConnector) ParseConfiguration(ctx context.Context, configurationDir
// In addition, this function should register any
// connector-specific metrics with the metrics registry.
func (c *HTTPConnector) TryInitState(ctx context.Context, configuration *configuration.Configuration, metrics *connector.TelemetryState) (*State, error) {
c.client.SetTracer(metrics.Tracer)

return &State{
Tracer: metrics.Tracer,
}, nil
Expand Down
194 changes: 182 additions & 12 deletions connector/connector_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"fmt"
"io"
"log"
"log/slog"
"net/http"
"net/http/httptest"
"os"
Expand Down Expand Up @@ -99,7 +100,7 @@ func TestHTTPConnector_emptyServer(t *testing.T) {
func TestHTTPConnector_authentication(t *testing.T) {
apiKey := "random_api_key"
bearerToken := "random_bearer_token"
// slog.SetLogLoggerLevel(slog.LevelDebug)
slog.SetLogLoggerLevel(slog.LevelDebug)
server := createMockServer(t, apiKey, bearerToken)
defer server.Close()

Expand Down Expand Up @@ -166,6 +167,19 @@ func TestHTTPConnector_authentication(t *testing.T) {
"body": {
"name": "pet"
}
},
"fields": {
"type": "object",
"fields": {
"headers": {
"column": "headers",
"type": "column"
},
"response": {
"column": "response",
"type": "column"
}
}
}
}
],
Expand Down Expand Up @@ -287,19 +301,32 @@ func TestHTTPConnector_authentication(t *testing.T) {
},
"fields": {
"fields": {
"fields": {
"completed": {
"column": "completed",
"type": "column"
},
"status": {
"column": "status",
"type": "column"
}
"headers": {
"column": "headers",
"type": "column"
},
"type": "object"
"response": {
"column": "response",
"type": "column",
"fields": {
"type": "array",
"fields": {
"fields": {
"completed": {
"column": "completed",
"type": "column"
},
"status": {
"column": "status",
"type": "column"
}
},
"type": "object"
}
}
}
},
"type": "array"
"type": "object"
}
}
],
Expand All @@ -321,6 +348,137 @@ func TestHTTPConnector_authentication(t *testing.T) {
})
})

t.Run("encoding-xml", func(t *testing.T) {
reqBody := []byte(`{
"operations": [
{
"type": "procedure",
"name": "putPetXml",
"arguments": {
"body": {
"id": 10,
"name": "doggie",
"category": {
"id": 1,
"name": "Dogs"
},
"photoUrls": ["string"],
"tags": [
{
"id": 0,
"name": "string"
}
],
"status": "available"
}
},
"fields": {
"fields": {
"headers": {
"column": "headers",
"type": "column"
},
"response": {
"column": "response",
"fields": {
"fields": {
"category": {
"column": "category",
"fields": {
"fields": {
"id": {
"column": "id",
"type": "column"
},
"name": {
"column": "name",
"type": "column"
}
},
"type": "object"
},
"type": "column"
},
"field": {
"column": "field",
"type": "column"
},
"id": {
"column": "id",
"type": "column"
},
"name": {
"column": "name",
"type": "column"
},
"photoUrls": {
"column": "photoUrls",
"type": "column"
},
"status": {
"column": "status",
"type": "column"
},
"tags": {
"column": "tags",
"fields": {
"fields": {
"fields": {
"id": {
"column": "id",
"type": "column"
},
"name": {
"column": "name",
"type": "column"
}
},
"type": "object"
},
"type": "array"
},
"type": "column"
}
},
"type": "object"
},
"type": "column"
}
},
"type": "object"
}
}
],
"collection_relationships": {}
}`)

res, err := http.Post(fmt.Sprintf("%s/mutation", testServer.URL), "application/json", bytes.NewBuffer(reqBody))
assert.NilError(t, err)
assertHTTPResponse(t, res, http.StatusOK, schema.MutationResponse{
OperationResults: []schema.MutationOperationResults{
schema.NewProcedureResult(map[string]any{
"headers": map[string]any{"Content-Type": string("application/xml")},
"response": map[string]any{
"id": float64(10),
"name": "doggie",
"category": map[string]any{
"id": float64(1),
"name": "Dogs",
},
"field": nil,
"photoUrls": []any{"string"},
"tags": []any{
map[string]any{
"id": float64(0),
"name": "string",
},
},
"status": "available",
},
}).Encode(),
},
})
})
}

func TestHTTPConnector_distribution(t *testing.T) {
Expand Down Expand Up @@ -670,6 +828,18 @@ func createMockServer(t *testing.T, apiKey string, bearerToken string) *httptest
}
})

mux.HandleFunc("/pet/xml", func(w http.ResponseWriter, r *http.Request) {
switch r.Method {
case http.MethodPut:
w.Header().Add("Content-Type", "application/xml")
w.WriteHeader(http.StatusOK)

_, _ = w.Write([]byte("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<pet><category><id>1</id><name>Dogs</name></category><id>10</id><name>doggie</name><photoUrls><photoUrl>string</photoUrl></photoUrls><status>available</status><tags><tag><id>0</id><name>string</name></tag></tags></pet>"))
default:
w.WriteHeader(http.StatusMethodNotAllowed)
}
})

return httptest.NewServer(mux)
}

Expand Down
Loading

0 comments on commit 95bf571

Please sign in to comment.