Skip to content

Commit 011edd0

Browse files
committed
refactor(entities/source): refactor source object
1 parent 63d6912 commit 011edd0

File tree

20 files changed

+252
-135
lines changed

20 files changed

+252
-135
lines changed

admin/api/sources.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ func (api *API) CreateSource(w http.ResponseWriter, r *http.Request) {
4040
return
4141
}
4242

43+
if source.Type == "http" {
44+
if source.Config.HTTP.Path == "" {
45+
source.Config.HTTP.Path = "/" + utils.UUIDShort()
46+
}
47+
}
48+
4349
source.WorkspaceId = ucontext.GetWorkspaceID(r.Context())
4450
err := api.db.SourcesWS.Insert(r.Context(), &source)
4551
api.assert(err)

db/entities/source.go

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,33 @@ func (m CustomResponse) Value() (driver.Value, error) {
1919
return json.Marshal(m)
2020
}
2121

22+
type SourceConfig struct {
23+
HTTP HttpSourceConfig `json:"http"`
24+
}
25+
26+
func (m *SourceConfig) Scan(src interface{}) error {
27+
return json.Unmarshal(src.([]byte), m)
28+
}
29+
30+
func (m SourceConfig) Value() (driver.Value, error) {
31+
return json.Marshal(m)
32+
}
33+
34+
type HttpSourceConfig struct {
35+
Path string `json:"path"`
36+
Methods Strings `json:"methods"`
37+
Response *CustomResponse `json:"response"`
38+
}
39+
2240
type Source struct {
23-
ID string `json:"id" db:"id"`
24-
Name *string `json:"name" db:"name"`
25-
Enabled bool `json:"enabled" db:"enabled"`
26-
Path string `json:"path" db:"path"`
27-
Methods Strings `json:"methods" db:"methods"`
28-
Async bool `json:"async" db:"async"`
29-
Response *CustomResponse `json:"response" db:"response"`
30-
Metadata Metadata `json:"metadata" db:"metadata"`
31-
RateLimit *RateLimit `json:"rate_limit" yaml:"rate_limit" db:"rate_limit"`
41+
ID string `json:"id" db:"id"`
42+
Name *string `json:"name" db:"name"`
43+
Enabled bool `json:"enabled" db:"enabled"`
44+
Type string `json:"type" db:"type"`
45+
Config SourceConfig `json:"config" db:"config"`
46+
Async bool `json:"async" db:"async"`
47+
Metadata Metadata `json:"metadata" db:"metadata"`
48+
RateLimit *RateLimit `json:"rate_limit" yaml:"rate_limit" db:"rate_limit"`
3249

3350
BaseModel `yaml:"-"`
3451
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
ALTER TABLE IF EXISTS ONLY "sources" ADD COLUMN IF NOT EXISTS "path" TEXT;
2+
ALTER TABLE IF EXISTS ONLY "sources" ADD COLUMN IF NOT EXISTS "methods" TEXT[];
3+
ALTER TABLE IF EXISTS ONLY "sources" ADD COLUMN IF NOT EXISTS "response" JSONB;
4+
5+
UPDATE sources SET
6+
"path" = (config->'http'->>'path'),
7+
"methods" = ARRAY(SELECT jsonb_array_elements_text(config->'http'->'methods')),
8+
"response" = (config->'http'->'response');
9+
10+
ALTER TABLE IF EXISTS ONLY "sources" DROP COLUMN IF EXISTS "type";
11+
ALTER TABLE IF EXISTS ONLY "sources" DROP COLUMN IF EXISTS "config";
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
ALTER TABLE IF EXISTS ONLY "sources" ADD COLUMN IF NOT EXISTS "type" varchar(20);
2+
ALTER TABLE IF EXISTS ONLY "sources" ADD COLUMN IF NOT EXISTS "config" JSONB NOT NULL DEFAULT '{}'::jsonb;
3+
4+
UPDATE sources SET "type" = 'http', "config" = jsonb_build_object('http', jsonb_build_object('methods', methods, 'path', path, 'response', response));
5+
6+
ALTER TABLE IF EXISTS ONLY "sources" DROP COLUMN IF EXISTS "path";
7+
ALTER TABLE IF EXISTS ONLY "sources" DROP COLUMN IF EXISTS "methods";
8+
ALTER TABLE IF EXISTS ONLY "sources" DROP COLUMN IF EXISTS "response";

examples/function/webhookx-function-sample.yml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,15 @@ endpoints:
1414

1515
sources:
1616
- name: github-source
17-
path: /github
18-
methods: [ "POST" ]
19-
response:
20-
code: 200
21-
content_type: application/json
22-
body: '{"message": "OK"}'
17+
type: http
18+
config:
19+
http:
20+
path: /github
21+
methods: [ "POST" ]
22+
response:
23+
code: 200
24+
content_type: application/json
25+
body: '{"message": "OK"}'
2326
plugins:
2427
- name: function
2528
config:

openapi.yml

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -877,33 +877,21 @@ components:
877877
enabled:
878878
type: boolean
879879
default: true
880-
path:
880+
type:
881881
type: string
882-
methods:
883-
type: array
884-
items:
885-
type: string
886-
enum: [ GET, POST, PUT, DELETE, PATCH ]
887-
minItems: 1
882+
enum: [ "http" ]
883+
default: http
884+
config:
885+
type: object
886+
properties:
887+
http:
888+
$ref: "#/components/schemas/HTTPSourceConfig"
889+
required:
890+
- http
888891
async:
889892
type: boolean
890893
description: "Whether to ingest events asynchronously through the queue"
891894
default: false
892-
response:
893-
type: object
894-
nullable: true
895-
properties:
896-
code:
897-
type: integer
898-
minimum: 200
899-
maximum: 599
900-
content_type:
901-
type: string
902-
body:
903-
type: string
904-
required:
905-
- code
906-
- content_type
907895
metadata:
908896
$ref: "#/components/schemas/Metadata"
909897
rate_limit:
@@ -915,8 +903,7 @@ components:
915903
type: integer
916904
readOnly: true
917905
required:
918-
- path
919-
- methods
906+
- config
920907

921908
Plugin:
922909
type: object
@@ -1049,3 +1036,33 @@ components:
10491036
type: string
10501037
format: jsonschema
10511038
maxLength: 1048576
1039+
1040+
HTTPSourceConfig:
1041+
type: object
1042+
default:
1043+
methods: [ "POST" ]
1044+
properties:
1045+
path:
1046+
type: string
1047+
methods:
1048+
type: array
1049+
items:
1050+
type: string
1051+
enum: [ GET, POST, PUT, DELETE, PATCH ]
1052+
minItems: 1
1053+
default: [ "POST" ]
1054+
response:
1055+
type: object
1056+
nullable: true
1057+
properties:
1058+
code:
1059+
type: integer
1060+
minimum: 200
1061+
maximum: 599
1062+
content_type:
1063+
type: string
1064+
body:
1065+
type: string
1066+
required:
1067+
- code
1068+
- content_type

proxy/gateway.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,8 @@ func (gw *Gateway) buildRouter(version string) {
169169
routes := make([]*router.Route, 0)
170170
for _, source := range sources {
171171
route := router.Route{
172-
Paths: []string{source.Path},
173-
Methods: source.Methods,
172+
Paths: []string{source.Config.HTTP.Path},
173+
Methods: source.Config.HTTP.Methods,
174174
Handler: source,
175175
}
176176
routes = append(routes, &route)
@@ -204,7 +204,7 @@ func (gw *Gateway) handle(w http.ResponseWriter, r *http.Request) bool {
204204
span.SetAttributes(attribute.String("source.name", utils.PointerValue(source.Name)))
205205
span.SetAttributes(attribute.String("source.workspace_id", source.WorkspaceId))
206206
span.SetAttributes(attribute.Bool("source.async", source.Async))
207-
span.SetAttributes(semconv.HTTPRoute(source.Path))
207+
span.SetAttributes(semconv.HTTPRoute(source.Config.HTTP.Path))
208208
defer span.End()
209209
ctx = tracingCtx
210210
}
@@ -306,9 +306,9 @@ func (gw *Gateway) handle(w http.ResponseWriter, r *http.Request) bool {
306306
headers[constants.HeaderEventId] = event.ID
307307
}
308308

309-
if source.Response != nil {
310-
headers["Content-Type"] = source.Response.ContentType
311-
exit(w, source.Response.Code, source.Response.Body, headers)
309+
if source.Config.HTTP.Response != nil {
310+
headers["Content-Type"] = source.Config.HTTP.Response.ContentType
311+
exit(w, source.Config.HTTP.Response.Code, source.Config.HTTP.Response.Body, headers)
312312
return true
313313
}
314314

test/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,26 @@ make deps
1212
```shell
1313
make test-integration
1414
```
15+
16+
17+
# How-To
18+
19+
#### How to run specific tests?
20+
21+
`FIt`, `FContext`.
22+
23+
```
24+
Context("some specs you're debugging", func() {
25+
It("might be failing", func() { ... })
26+
FIt("might also be failing", func() { ... })
27+
})
28+
29+
```
30+
31+
```
32+
ginkgo
33+
```
34+
35+
This will run only test "might also be failing", skip the rest.
36+
37+
See https://onsi.github.io/ginkgo/#focused-specs.

test/admin/sources_test.go

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,7 @@ var _ = Describe("/sources", Ordered, func() {
3838
Context("POST", func() {
3939
It("creates a source", func() {
4040
resp, err := adminClient.R().
41-
SetBody(map[string]interface{}{
42-
"path": "/v1",
43-
"methods": []string{"POST"},
44-
}).
41+
SetBody(`{ "type": "http", "config": { "http": { "path": "" } }}`).
4542
SetResult(entities.Source{}).
4643
Post("/workspaces/default/sources")
4744
assert.Nil(GinkgoT(), err)
@@ -51,10 +48,10 @@ var _ = Describe("/sources", Ordered, func() {
5148
result := resp.Result().(*entities.Source)
5249
assert.NotNil(GinkgoT(), result.ID)
5350
assert.Equal(GinkgoT(), true, result.Enabled)
54-
assert.Equal(GinkgoT(), "/v1", result.Path)
55-
assert.EqualValues(GinkgoT(), []string{"POST"}, result.Methods)
51+
assert.True(GinkgoT(), len(result.Config.HTTP.Path) > 0) // auto generate path
52+
assert.EqualValues(GinkgoT(), []string{"POST"}, result.Config.HTTP.Methods)
5653
assert.Equal(GinkgoT(), false, result.Async)
57-
assert.True(GinkgoT(), nil == result.Response)
54+
assert.True(GinkgoT(), nil == result.Config.HTTP.Response)
5855

5956
e, err := db.Sources.Get(context.TODO(), result.ID)
6057
assert.Nil(GinkgoT(), err)
@@ -70,7 +67,7 @@ var _ = Describe("/sources", Ordered, func() {
7067
assert.Nil(GinkgoT(), err)
7168
assert.Equal(GinkgoT(), 400, resp.StatusCode())
7269
assert.Equal(GinkgoT(),
73-
`{"message":"Request Validation","error":{"message":"request validation","fields":{"methods":"required field missing","path":"required field missing"}}}`,
70+
`{"message":"Request Validation","error":{"message":"request validation","fields":{"config":"required field missing"}}}`,
7471
string(resp.Body()))
7572
})
7673
})
@@ -166,14 +163,19 @@ var _ = Describe("/sources", Ordered, func() {
166163
It("updates by id", func() {
167164
resp, err := adminClient.R().
168165
SetBody(map[string]interface{}{
169-
"path": "/v1",
170-
"methods": []string{"GET", "POST", "PUT", "DELETE"},
171-
"async": true,
172-
"response": map[string]interface{}{
173-
"code": 200,
174-
"content_type": "text/plain",
175-
"body": "OK",
166+
"type": "http",
167+
"config": map[string]interface{}{
168+
"http": map[string]interface{}{
169+
"path": "/v1",
170+
"methods": []string{"GET", "POST", "PUT", "DELETE"},
171+
"response": map[string]interface{}{
172+
"code": 200,
173+
"content_type": "text/plain",
174+
"body": "OK",
175+
},
176+
},
176177
},
178+
"async": true,
177179
}).
178180
SetResult(entities.Source{}).
179181
Put("/workspaces/default/sources/" + entity.ID)
@@ -183,14 +185,14 @@ var _ = Describe("/sources", Ordered, func() {
183185
result := resp.Result().(*entities.Source)
184186

185187
assert.Equal(GinkgoT(), entity.ID, result.ID)
186-
assert.Equal(GinkgoT(), "/v1", result.Path)
187-
assert.EqualValues(GinkgoT(), []string{"GET", "POST", "PUT", "DELETE"}, result.Methods)
188+
assert.Equal(GinkgoT(), "/v1", result.Config.HTTP.Path)
189+
assert.EqualValues(GinkgoT(), []string{"GET", "POST", "PUT", "DELETE"}, result.Config.HTTP.Methods)
188190
assert.Equal(GinkgoT(), true, result.Async)
189191
assert.EqualValues(GinkgoT(), &entities.CustomResponse{
190192
Code: 200,
191193
ContentType: "text/plain",
192194
Body: "OK",
193-
}, result.Response)
195+
}, result.Config.HTTP.Response)
194196
})
195197
})
196198

test/cmd/admin_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,11 @@ var _ = Describe("admin", Ordered, func() {
8787
assert.NoError(GinkgoT(), err)
8888
assert.Equal(GinkgoT(), "default-source", *source.Name)
8989
assert.Equal(GinkgoT(), true, source.Enabled)
90-
assert.Equal(GinkgoT(), "/", source.Path)
91-
assert.Equal(GinkgoT(), []string{"POST"}, []string(source.Methods))
92-
assert.Equal(GinkgoT(), 200, source.Response.Code)
93-
assert.Equal(GinkgoT(), "application/json", source.Response.ContentType)
94-
assert.Equal(GinkgoT(), `{"message": "OK"}`, source.Response.Body)
90+
assert.Equal(GinkgoT(), "/", source.Config.HTTP.Path)
91+
assert.Equal(GinkgoT(), []string{"POST"}, []string(source.Config.HTTP.Methods))
92+
assert.Equal(GinkgoT(), 200, source.Config.HTTP.Response.Code)
93+
assert.Equal(GinkgoT(), "application/json", source.Config.HTTP.Response.ContentType)
94+
assert.Equal(GinkgoT(), `{"message": "OK"}`, source.Config.HTTP.Response.Body)
9595

9696
plugins, err := db.Plugins.ListEndpointPlugin(context.TODO(), endpoint.ID)
9797
assert.NoError(GinkgoT(), err)

0 commit comments

Comments
 (0)