diff --git a/http-gateway/service/getResource.go b/http-gateway/service/getResource.go index e3e0eb2a4..9f8db8a07 100644 --- a/http-gateway/service/getResource.go +++ b/http-gateway/service/getResource.go @@ -78,7 +78,7 @@ func parseBoolQuery(str string) bool { return val } -func (requestHandler *RequestHandler) serveResourceRequest(r *http.Request, deviceID, resourceHref, twin, resourceInterface string) (*httptest.ResponseRecorder, error) { +func (requestHandler *RequestHandler) serveResourceRequest(r *http.Request, deviceID, resourceHref, twin, resourceInterface string) (*httptest.ResponseRecorder, bool, error) { resourceID := pb.ResourceIdFilter{ ResourceId: commands.NewResourceID(deviceID, resourceHref), Etag: getETags(r), @@ -87,9 +87,9 @@ func (requestHandler *RequestHandler) serveResourceRequest(r *http.Request, devi if (twin == "" || parseBoolQuery(twin)) && resourceInterface == "" { rec, err := requestHandler.getResourceFromTwin(r, &resourceID) if err != nil { - return nil, kitNetGrpc.ForwardErrorf(codes.InvalidArgument, errFmtFromTwin, &resourceID, err) + return nil, false, kitNetGrpc.ForwardErrorf(codes.InvalidArgument, errFmtFromTwin, &resourceID, err) } - return rec, nil + return rec, true, nil } query := r.URL.Query() @@ -103,7 +103,7 @@ func (requestHandler *RequestHandler) serveResourceRequest(r *http.Request, devi rec := httptest.NewRecorder() requestHandler.mux.ServeHTTP(rec, r) - return rec, nil + return rec, false, nil } func jsonGetValueOnPath(v interface{}, path ...string) (interface{}, error) { @@ -174,14 +174,18 @@ func (requestHandler *RequestHandler) getResource(w http.ResponseWriter, r *http twin := r.URL.Query().Get(uri.TwinQueryKey) onlyContent := r.URL.Query().Get(uri.OnlyContentQueryKey) resourceInterface := r.URL.Query().Get(uri.ResourceInterfaceQueryKey) - rec, err := requestHandler.serveResourceRequest(r, deviceID, resourceHref, twin, resourceInterface) + rec, fromTwin, err := requestHandler.serveResourceRequest(r, deviceID, resourceHref, twin, resourceInterface) if err != nil { serverMux.WriteError(w, err) return } allowEmptyContent := false if parseBoolQuery(onlyContent) { - allowEmptyContent = requestHandler.filterOnlyContent(rec, "result", "data", "content") + filterPath := []string{"result", "data", "content"} + if !fromTwin { + filterPath = []string{"data", "content"} + } + allowEmptyContent = requestHandler.filterOnlyContent(rec, filterPath...) } toSimpleResponse(w, rec, allowEmptyContent, func(w http.ResponseWriter, err error) { serverMux.WriteError(w, kitNetGrpc.ForwardErrorf(codes.InvalidArgument, "cannot get resource('%v/%v') from the device: %v", deviceID, resourceHref, err)) diff --git a/http-gateway/service/getResource_test.go b/http-gateway/service/getResource_test.go index 3cd1b3f65..cc2fa9006 100644 --- a/http-gateway/service/getResource_test.go +++ b/http-gateway/service/getResource_test.go @@ -247,6 +247,7 @@ func TestRequestHandlerGetResourceWithOnlyContent(t *testing.T) { type args struct { deviceID string resourceHref string + twin *bool } tests := []struct { name string @@ -255,7 +256,7 @@ func TestRequestHandlerGetResourceWithOnlyContent(t *testing.T) { wantCode int }{ { - name: "json: get from resource twin", + name: "json: get resource from twin", args: args{ deviceID: deviceID, resourceHref: test.TestResourceLightInstanceHref("1"), @@ -263,6 +264,16 @@ func TestRequestHandlerGetResourceWithOnlyContent(t *testing.T) { want: map[interface{}]interface{}{"name": "Light", "power": uint64(0x0), "state": false}, wantCode: http.StatusOK, }, + { + name: "json: get resource from device", + args: args{ + deviceID: deviceID, + resourceHref: test.TestResourceLightInstanceHref("1"), + twin: newBool(false), + }, + want: map[interface{}]interface{}{"name": "Light", "power": uint64(0x0), "state": false}, + wantCode: http.StatusOK, + }, { name: "json: not exists", args: args{ @@ -278,6 +289,9 @@ func TestRequestHandlerGetResourceWithOnlyContent(t *testing.T) { rb := httpgwTest.NewRequest(http.MethodGet, uri.AliasDeviceResource, nil).AuthToken(token) rb.DeviceId(tt.args.deviceID).ResourceHref(tt.args.resourceHref) rb.OnlyContent(true) + if tt.args.twin != nil { + rb.Twin(*tt.args.twin) + } resp := httpgwTest.HTTPDo(t, rb.Build()) defer func() { _ = resp.Body.Close() diff --git a/http-gateway/service/getThings.go b/http-gateway/service/getThings.go index 468248eac..56b09aee6 100644 --- a/http-gateway/service/getThings.go +++ b/http-gateway/service/getThings.go @@ -383,7 +383,7 @@ func (requestHandler *RequestHandler) thingDescriptionResponse(ctx context.Conte func (requestHandler *RequestHandler) getThing(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) deviceID := vars[uri.DeviceIDKey] - rec, err := requestHandler.serveResourceRequest(r, deviceID, bridgeResourcesTD.ResourceURI, "", "") + rec, _, err := requestHandler.serveResourceRequest(r, deviceID, bridgeResourcesTD.ResourceURI, "", "") if err != nil { serverMux.WriteError(w, err) return diff --git a/http-gateway/swagger.wot.yaml b/http-gateway/swagger.wot.yaml new file mode 100644 index 000000000..ca7386796 --- /dev/null +++ b/http-gateway/swagger.wot.yaml @@ -0,0 +1,970 @@ +openapi: 3.1.0 +info: + title: plgd HTTP Gateway + version: 2.7.19 +servers: + - url: "https://try.plgd.cloud" +paths: + "/api/v1/things": + get: + tags: + - "Web of Things" + summary: "Retrieve Hub Thing Description" + description: | + Retrieve the description of the PLGD hub, including links to all associated things. + responses: + 200: + description: "Thing description of the plgd hub." + content: + application/json: + schema: + $ref: "#/components/schemas/thing" +components: + schemas: + anyUri: + type: string + description: + type: string + descriptions: + type: object + additionalProperties: + type: string + title: + type: string + titles: + type: object + additionalProperties: + type: string + security: + oneOf: + - type: array + items: + type: string + minItems: 1 + - type: string + scopes: + oneOf: + - type: array + items: + type: string + - type: string + subprotocol: + type: string + examples: + - longpoll + - websub + - sse + thing-context-td-uri-v1: + type: string + const: https://www.w3.org/2019/wot/td/v1 + thing-context-td-uri-v1.1: + type: string + const: https://www.w3.org/2022/wot/td/v1.1 + thing-context-td-uri-temp: + type: string + const: http://www.w3.org/ns/td + thing-context: + anyOf: + - $comment: New context URI with other vocabularies after it but not the old one + type: array + items: + - $ref: '#/components/schemas/thing-context-td-uri-v1.1' + additionalItems: + anyOf: + - $ref: '#/components/schemas/anyUri' + - type: object + not: + $ref: '#/components/schemas/thing-context-td-uri-v1' + - $comment: Only the new context URI + $ref: '#/components/schemas/thing-context-td-uri-v1.1' + - $comment: >- + Old context URI, followed by the new one and possibly other + vocabularies. minItems and contains are required since prefixItems + does not say all items should be provided + type: array + prefixItems: + - $ref: '#/components/schemas/thing-context-td-uri-v1' + - $ref: '#/components/schemas/thing-context-td-uri-v1.1' + minItems: 2 + contains: + $ref: '#/components/schemas/thing-context-td-uri-v1.1' + additionalItems: + anyOf: + - $ref: '#/components/schemas/anyUri' + - type: object + - $comment: >- + Old context URI, followed by possibly other vocabularies. minItems and + contains are required since prefixItems does not say all items should + be provided + type: array + prefixItems: + - $ref: '#/components/schemas/thing-context-td-uri-v1' + minItems: 1 + contains: + $ref: '#/components/schemas/thing-context-td-uri-v1' + additionalItems: + anyOf: + - $ref: '#/components/schemas/anyUri' + - type: object + - $comment: Only the old context URI + $ref: '#/components/schemas/thing-context-td-uri-v1' + bcp47_string: + type: string + pattern: >- + ^(((([A-Za-z]{2,3}(-([A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4}|[A-Za-z]{5,8})(-([A-Za-z]{4}))?(-([A-Za-z]{2}|[0-9]{3}))?(-([A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*(-([0-9A-WY-Za-wy-z](-[A-Za-z0-9]{2,8})+))*(-(x(-[A-Za-z0-9]{1,8})+))?)|(x(-[A-Za-z0-9]{1,8})+)|((en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang)))$ + type_declaration: + oneOf: + - type: string + not: + const: tm:ThingModel + - type: array + items: + type: string + not: + const: tm:ThingModel + dataSchema-type: + type: string + enum: + - boolean + - integer + - number + - string + - object + - array + - 'null' + dataSchema: + type: object + properties: + '@type': + $ref: '#/components/schemas/type_declaration' + description: + $ref: '#/components/schemas/description' + title: + $ref: '#/components/schemas/title' + descriptions: + $ref: '#/components/schemas/descriptions' + titles: + $ref: '#/components/schemas/titles' + writeOnly: + type: boolean + readOnly: + type: boolean + oneOf: + type: array + items: + $ref: '#/components/schemas/dataSchema' + unit: + type: string + enum: + type: array + minItems: 1 + uniqueItems: true + format: + type: string + const: {} + default: {} + contentEncoding: + type: string + contentMediaType: + type: string + type: + $ref: '#/components/schemas/dataSchema-type' + items: + oneOf: + - $ref: '#/components/schemas/dataSchema' + - type: array + items: + $ref: '#/components/schemas/dataSchema' + maxItems: + type: integer + minimum: 0 + minItems: + type: integer + minimum: 0 + minimum: + type: number + maximum: + type: number + exclusiveMinimum: + type: number + exclusiveMaximum: + type: number + minLength: + type: integer + minimum: 0 + maxLength: + type: integer + minimum: 0 + multipleOf: + $ref: '#/components/schemas/multipleOfDefinition' + properties: + additionalProperties: + $ref: '#/components/schemas/dataSchema' + required: + type: array + items: + type: string + additionalResponsesDefinition: + type: array + items: + type: object + properties: + contentType: + type: string + schema: + type: string + success: + type: boolean + multipleOfDefinition: + type: + - integer + - number + exclusiveMinimum: 0 + expectedResponse: + type: object + properties: + contentType: + type: string + required: + - contentType + form_element_base: + type: object + properties: + op: + oneOf: + - type: string + - type: array + items: + type: string + href: + $ref: '#/components/schemas/anyUri' + contentType: + type: string + contentCoding: + type: string + subprotocol: + $ref: '#/components/schemas/subprotocol' + security: + $ref: '#/components/schemas/security' + scopes: + $ref: '#/components/schemas/scopes' + response: + $ref: '#/components/schemas/expectedResponse' + additionalResponses: + $ref: '#/components/schemas/additionalResponsesDefinition' + required: + - href + additionalProperties: true + form_element_property: + allOf: + - $ref: '#/components/schemas/form_element_base' + type: object + properties: + op: + oneOf: + - type: string + enum: + - readproperty + - writeproperty + - observeproperty + - unobserveproperty + - type: array + items: + type: string + enum: + - readproperty + - writeproperty + - observeproperty + - unobserveproperty + minItems: 1 + additionalProperties: true + form_element_action: + allOf: + - $ref: '#/components/schemas/form_element_base' + type: object + properties: + op: + oneOf: + - type: string + enum: + - invokeaction + - queryaction + - cancelaction + - type: array + items: + type: string + enum: + - invokeaction + - queryaction + - cancelaction + minItems: 1 + additionalProperties: true + form_element_event: + allOf: + - $ref: '#/components/schemas/form_element_base' + type: object + properties: + op: + oneOf: + - type: string + enum: + - subscribeevent + - unsubscribeevent + - type: array + items: + type: string + enum: + - subscribeevent + - unsubscribeevent + minItems: 1 + additionalProperties: true + form_element_root: + allOf: + - $ref: '#/components/schemas/form_element_base' + type: object + properties: + op: + oneOf: + - type: string + enum: + - readallproperties + - writeallproperties + - readmultipleproperties + - writemultipleproperties + - observeallproperties + - unobserveallproperties + - queryallactions + - subscribeallevents + - unsubscribeallevents + - type: array + items: + type: string + enum: + - readallproperties + - writeallproperties + - readmultipleproperties + - writemultipleproperties + - observeallproperties + - unobserveallproperties + - queryallactions + - subscribeallevents + - unsubscribeallevents + minItems: 1 + additionalProperties: true + required: + - op + form: + $comment: >- + This is NOT for validation purposes but for automatic generation of TS + types. For more info, please see: + https://github.com/w3c/wot-thing-description/pull/1319#issuecomment-994950057 + oneOf: + - $ref: '#/components/schemas/form_element_property' + - $ref: '#/components/schemas/form_element_action' + - $ref: '#/components/schemas/form_element_event' + - $ref: '#/components/schemas/form_element_root' + property_element: + type: object + properties: + '@type': + $ref: '#/components/schemas/type_declaration' + description: + $ref: '#/components/schemas/description' + descriptions: + $ref: '#/components/schemas/descriptions' + title: + $ref: '#/components/schemas/title' + titles: + $ref: '#/components/schemas/titles' + forms: + type: array + minItems: 1 + items: + $ref: '#/components/schemas/form_element_property' + uriVariables: + type: object + additionalProperties: + $ref: '#/components/schemas/dataSchema' + observable: + type: boolean + writeOnly: + type: boolean + readOnly: + type: boolean + oneOf: + type: array + items: + $ref: '#/components/schemas/dataSchema' + unit: + type: string + enum: + type: array + minItems: 1 + uniqueItems: true + format: + type: string + const: {} + default: {} + type: + $ref: '#/components/schemas/dataSchema-type' + items: + oneOf: + - $ref: '#/components/schemas/dataSchema' + - type: array + items: + $ref: '#/components/schemas/dataSchema' + maxItems: + type: integer + minimum: 0 + minItems: + type: integer + minimum: 0 + minimum: + type: number + maximum: + type: number + exclusiveMinimum: + type: number + exclusiveMaximum: + type: number + minLength: + type: integer + minimum: 0 + maxLength: + type: integer + minimum: 0 + multipleOf: + $ref: '#/components/schemas/multipleOfDefinition' + properties: + additionalProperties: + $ref: '#/components/schemas/dataSchema' + required: + type: array + items: + type: string + required: + - forms + additionalProperties: true + action_element: + type: object + properties: + '@type': + $ref: '#/components/schemas/type_declaration' + description: + $ref: '#/components/schemas/description' + descriptions: + $ref: '#/components/schemas/descriptions' + title: + $ref: '#/components/schemas/title' + titles: + $ref: '#/components/schemas/titles' + forms: + type: array + minItems: 1 + items: + $ref: '#/components/schemas/form_element_action' + uriVariables: + type: object + additionalProperties: + $ref: '#/components/schemas/dataSchema' + input: + $ref: '#/components/schemas/dataSchema' + output: + $ref: '#/components/schemas/dataSchema' + safe: + type: boolean + idempotent: + type: boolean + synchronous: + type: boolean + required: + - forms + additionalProperties: true + event_element: + type: object + properties: + '@type': + $ref: '#/components/schemas/type_declaration' + description: + $ref: '#/components/schemas/description' + descriptions: + $ref: '#/components/schemas/descriptions' + title: + $ref: '#/components/schemas/title' + titles: + $ref: '#/components/schemas/titles' + forms: + type: array + minItems: 1 + items: + $ref: '#/components/schemas/form_element_event' + uriVariables: + type: object + additionalProperties: + $ref: '#/components/schemas/dataSchema' + subscription: + $ref: '#/components/schemas/dataSchema' + data: + $ref: '#/components/schemas/dataSchema' + dataResponse: + $ref: '#/components/schemas/dataSchema' + cancellation: + $ref: '#/components/schemas/dataSchema' + required: + - forms + additionalProperties: true + base_link_element: + type: object + properties: + href: + $ref: '#/components/schemas/anyUri' + type: + type: string + rel: + type: string + anchor: + $ref: '#/components/schemas/anyUri' + hreflang: + anyOf: + - $ref: '#/components/schemas/bcp47_string' + - type: array + items: + $ref: '#/components/schemas/bcp47_string' + required: + - href + additionalProperties: true + link_element: + allOf: + - $ref: '#/components/schemas/base_link_element' + - not: + description: A basic link element should not contain sizes + type: object + properties: + sizes: {} + required: + - sizes + - not: + description: A basic link element should not contain icon or tm:extends + properties: + rel: + enum: + - icon + - tm:extends + required: + - rel + icon_link_element: + allOf: + - $ref: '#/components/schemas/base_link_element' + - properties: + rel: + const: icon + sizes: + type: string + pattern: '[0-9]*x[0-9]+' + required: + - rel + additionalSecurityScheme: + description: >- + Applies to additional SecuritySchemes not defined in the WoT TD + specification. + $comment: >- + Additional SecuritySchemes should always be defined via a context + extension, using a prefixed value for the scheme. This prefix (e.g. 'ace', + see the example below) must contain at least one character in order to + reference a valid JSON-LD context extension. + examples: + - scheme: ace:ACESecurityScheme + ace:as: coaps://as.example.com/token + ace:audience: coaps://rs.example.com + ace:scopes: + - limited + - special + ace:cnonce: true + type: object + properties: + '@type': + $ref: '#/components/schemas/type_declaration' + description: + $ref: '#/components/schemas/description' + descriptions: + $ref: '#/components/schemas/descriptions' + proxy: + $ref: '#/components/schemas/anyUri' + scheme: + type: string + pattern: .+:.* + required: + - scheme + additionalProperties: true + noSecurityScheme: + type: object + properties: + '@type': + $ref: '#/components/schemas/type_declaration' + description: + $ref: '#/components/schemas/description' + descriptions: + $ref: '#/components/schemas/descriptions' + proxy: + $ref: '#/components/schemas/anyUri' + scheme: + type: string + enum: + - nosec + required: + - scheme + additionalProperties: true + autoSecurityScheme: + type: object + properties: + '@type': + $ref: '#/components/schemas/type_declaration' + description: + $ref: '#/components/schemas/description' + descriptions: + $ref: '#/components/schemas/descriptions' + proxy: + $ref: '#/components/schemas/anyUri' + scheme: + type: string + enum: + - auto + not: + required: + - name + required: + - scheme + additionalProperties: true + comboSecurityScheme: + oneOf: + - type: object + properties: + '@type': + $ref: '#/components/schemas/type_declaration' + description: + $ref: '#/components/schemas/description' + descriptions: + $ref: '#/components/schemas/descriptions' + proxy: + $ref: '#/components/schemas/anyUri' + scheme: + type: string + enum: + - combo + oneOf: + type: array + minItems: 2 + items: + type: string + required: + - scheme + - oneOf + additionalProperties: true + - type: object + properties: + '@type': + $ref: '#/components/schemas/type_declaration' + description: + $ref: '#/components/schemas/description' + descriptions: + $ref: '#/components/schemas/descriptions' + proxy: + $ref: '#/components/schemas/anyUri' + scheme: + type: string + enum: + - combo + allOf: + type: array + minItems: 2 + items: + type: string + required: + - scheme + - allOf + additionalProperties: true + basicSecurityScheme: + type: object + properties: + '@type': + $ref: '#/components/schemas/type_declaration' + description: + $ref: '#/components/schemas/description' + descriptions: + $ref: '#/components/schemas/descriptions' + proxy: + $ref: '#/components/schemas/anyUri' + scheme: + type: string + enum: + - basic + in: + type: string + enum: + - header + - query + - body + - cookie + - auto + name: + type: string + required: + - scheme + additionalProperties: true + digestSecurityScheme: + type: object + properties: + '@type': + $ref: '#/components/schemas/type_declaration' + description: + $ref: '#/components/schemas/description' + descriptions: + $ref: '#/components/schemas/descriptions' + proxy: + $ref: '#/components/schemas/anyUri' + scheme: + type: string + enum: + - digest + qop: + type: string + enum: + - auth + - auth-int + in: + type: string + enum: + - header + - query + - body + - cookie + - auto + name: + type: string + required: + - scheme + additionalProperties: true + apiKeySecurityScheme: + type: object + properties: + '@type': + $ref: '#/components/schemas/type_declaration' + description: + $ref: '#/components/schemas/description' + descriptions: + $ref: '#/components/schemas/descriptions' + proxy: + $ref: '#/components/schemas/anyUri' + scheme: + type: string + enum: + - apikey + in: + type: string + enum: + - header + - query + - body + - cookie + - uri + - auto + name: + type: string + required: + - scheme + additionalProperties: true + bearerSecurityScheme: + type: object + properties: + '@type': + $ref: '#/components/schemas/type_declaration' + description: + $ref: '#/components/schemas/description' + descriptions: + $ref: '#/components/schemas/descriptions' + proxy: + $ref: '#/components/schemas/anyUri' + scheme: + type: string + enum: + - bearer + authorization: + $ref: '#/components/schemas/anyUri' + alg: + type: string + format: + type: string + in: + type: string + enum: + - header + - query + - body + - cookie + - auto + name: + type: string + required: + - scheme + additionalProperties: true + pskSecurityScheme: + type: object + properties: + '@type': + $ref: '#/components/schemas/type_declaration' + description: + $ref: '#/components/schemas/description' + descriptions: + $ref: '#/components/schemas/descriptions' + proxy: + $ref: '#/components/schemas/anyUri' + scheme: + type: string + enum: + - psk + identity: + type: string + required: + - scheme + additionalProperties: true + oAuth2SecurityScheme: + type: object + properties: + '@type': + $ref: '#/components/schemas/type_declaration' + description: + $ref: '#/components/schemas/description' + descriptions: + $ref: '#/components/schemas/descriptions' + proxy: + $ref: '#/components/schemas/anyUri' + scheme: + type: string + enum: + - oauth2 + authorization: + $ref: '#/components/schemas/anyUri' + token: + $ref: '#/components/schemas/anyUri' + refresh: + $ref: '#/components/schemas/anyUri' + scopes: + oneOf: + - type: array + items: + type: string + - type: string + flow: + anyOf: + - type: string + - type: string + enum: + - code + - client + required: + - scheme + additionalProperties: true + securityScheme: + oneOf: + - $ref: '#/components/schemas/noSecurityScheme' + - $ref: '#/components/schemas/autoSecurityScheme' + - $ref: '#/components/schemas/comboSecurityScheme' + - $ref: '#/components/schemas/basicSecurityScheme' + - $ref: '#/components/schemas/digestSecurityScheme' + - $ref: '#/components/schemas/apiKeySecurityScheme' + - $ref: '#/components/schemas/bearerSecurityScheme' + - $ref: '#/components/schemas/pskSecurityScheme' + - $ref: '#/components/schemas/oAuth2SecurityScheme' + - $ref: '#/components/schemas/additionalSecurityScheme' + thing: + type: object + properties: + id: + type: string + format: uri + title: + $ref: '#/components/schemas/title' + titles: + $ref: '#/components/schemas/titles' + properties: + type: object + additionalProperties: + $ref: '#/components/schemas/property_element' + actions: + type: object + additionalProperties: + $ref: '#/components/schemas/action_element' + events: + type: object + additionalProperties: + $ref: '#/components/schemas/event_element' + description: + $ref: '#/components/schemas/description' + descriptions: + $ref: '#/components/schemas/descriptions' + version: + type: object + properties: + instance: + type: string + required: + - instance + links: + type: array + items: + oneOf: + - $ref: '#/components/schemas/link_element' + - $ref: '#/components/schemas/icon_link_element' + forms: + type: array + minItems: 1 + items: + $ref: '#/components/schemas/form_element_root' + base: + $ref: '#/components/schemas/anyUri' + securityDefinitions: + type: object + minProperties: 1 + additionalProperties: + $ref: '#/components/schemas/securityScheme' + schemaDefinitions: + type: object + minProperties: 1 + additionalProperties: + $ref: '#/components/schemas/dataSchema' + support: + $ref: '#/components/schemas/anyUri' + created: + type: string + format: date-time + modified: + type: string + format: date-time + profile: + oneOf: + - $ref: '#/components/schemas/anyUri' + - type: array + minItems: 1 + items: + $ref: '#/components/schemas/anyUri' + security: + oneOf: + - type: string + - type: array + minItems: 1 + items: + type: string + uriVariables: + type: object + additionalProperties: + $ref: '#/components/schemas/dataSchema' + '@type': + $ref: '#/components/schemas/type_declaration' + '@context': + $ref: '#/components/schemas/thing-context' + required: + - title + - security + - securityDefinitions + - '@context' + additionalProperties: true diff --git a/http-gateway/swagger.yaml b/http-gateway/swagger.yaml index e07d35627..72329ff07 100644 --- a/http-gateway/swagger.yaml +++ b/http-gateway/swagger.yaml @@ -19,6 +19,40 @@ paths: application/json: schema: $ref: "#/components/schemas/HubConfiguration" + "/api/v1/things": + get: + tags: + - "Web of Things" + summary: "Retrieve Hub Thing Description" + description: | + Retrieve the description of the PLGD hub, including links to all associated things. + responses: + 200: + description: "Thing description of the plgd hub." + content: + application/json: + schema: + $ref: "https://raw.githubusercontent.com/plgd-dev/hub/main/http-gateway/swagger.wot.yaml#/components/schemas/thing" + 401: + $ref: "#/components/responses/unauthorized" + "/api/v1/things/{deviceId}": + get: + tags: + - "Web of Things" + summary: "Retrieve Device Thing Description" + description: | + Retrieve the thing description for a specific device. The device must be listed in the links of /api/v1/things. + parameters: + - $ref: "#/components/parameters/deviceId" + responses: + 200: + description: "Thing description of the device." + content: + application/json: + schema: + $ref: "https://raw.githubusercontent.com/plgd-dev/hub/main/http-gateway/swagger.wot.yaml#/components/schemas/thing" + 401: + $ref: "#/components/responses/unauthorized" "/api/v1/devices": get: tags: