From 5e257d0ca2d8d074f1e468e61702ddbd1770fbd1 Mon Sep 17 00:00:00 2001 From: Daniel Adam Date: Tue, 30 Apr 2024 12:13:25 +0200 Subject: [PATCH] fixup! bridge: updates for tests --- Makefile | 3 +- .../thingDescription/ocfResources.go | 74 +++++++++++++++++++ .../thingDescription/ocfResources.jsonld | 18 ++++- bridge/test/test.go | 68 ++++++++++++----- cmd/bridge-device/device.go | 5 +- cmd/bridge-device/main.go | 2 +- 6 files changed, 145 insertions(+), 25 deletions(-) diff --git a/Makefile b/Makefile index b214580f..ae5e4d66 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,8 @@ CERT_TOOL_SIGN_ALG ?= ECDSA-SHA256 # supported values: P256, P384, P521 CERT_TOOL_ELLIPTIC_CURVE ?= P256 DEVSIM_IMAGE ?= ghcr.io/iotivity/iotivity-lite/cloud-server-discovery-resource-observable-debug:vnext -HUB_TEST_DEVICE_IMAGE = ghcr.io/plgd-dev/hub/test-cloud-server:main +# HUB_TEST_DEVICE_IMAGE = ghcr.io/plgd-dev/hub/test-cloud-server:main +HUB_TEST_DEVICE_IMAGE = ghcr.io/plgd-dev/hub/test-cloud-server:vnext-pr1274 default: build diff --git a/bridge/resources/thingDescription/ocfResources.go b/bridge/resources/thingDescription/ocfResources.go index 63008024..ce52c80f 100644 --- a/bridge/resources/thingDescription/ocfResources.go +++ b/bridge/resources/thingDescription/ocfResources.go @@ -2,7 +2,13 @@ package thingDescription import ( _ "embed" + "net/url" + schemaCloud "github.com/plgd-dev/device/v2/schema/cloud" + schemaCredential "github.com/plgd-dev/device/v2/schema/credential" + schemaDevice "github.com/plgd-dev/device/v2/schema/device" + schemaMaintenance "github.com/plgd-dev/device/v2/schema/maintenance" + "github.com/plgd-dev/go-coap/v3/message" "github.com/web-of-things-open-source/thingdescription-go/thingDescription" ) @@ -32,3 +38,71 @@ func GetOCFResourcePropertyElement(resourceHref string) (thingDescription.Proper } return prop, true } + +func boolToPtr(v bool) *bool { + if !v { + return nil + } + return &v +} + +func stringToPtr(v string) *string { + if v == "" { + return nil + } + return &v +} + +func createForm(pe *thingDescription.PropertyElement, href string, contentType string, op []string) error { + uri, err := url.Parse(href) + if err != nil { + return err + } + pe.Forms = []thingDescription.FormElementProperty{ + { + ContentType: stringToPtr(contentType), + Op: &thingDescription.FormElementPropertyOp{ + StringArray: op, + }, + Href: *uri, + }, + } + return nil +} + +func PatchDeviceResourcePropertyElement(pe *thingDescription.PropertyElement, baseURL, deviceType string, setForm bool) error { + if deviceType != "" { + pe.Type = &thingDescription.TypeDeclaration{ + StringArray: []string{schemaDevice.ResourceType, deviceType}, + } + } + pe.ReadOnly = boolToPtr(true) + if setForm { + err := createForm(pe, baseURL+schemaDevice.ResourceURI, message.AppCBOR.String(), []string{"readproperty"}) + if err != nil { + return err + } + } + return nil +} + +func PatchMaintenanceResourcePropertyElement(pe *thingDescription.PropertyElement, baseURL string, setForm bool) error { + if !setForm { + return nil + } + return createForm(pe, baseURL+schemaMaintenance.ResourceURI, message.AppCBOR.String(), []string{"readproperty", "writeproperty"}) +} + +func PatchCloudResourcePropertyElement(pe *thingDescription.PropertyElement, baseURL string, setForm bool) error { + if !setForm { + return nil + } + return createForm(pe, baseURL+schemaCloud.ResourceURI, message.AppCBOR.String(), []string{"readproperty", "writeproperty"}) +} + +func PatchCredentialResourcePropertyElement(pe *thingDescription.PropertyElement, baseURL string, setForm bool) error { + if !setForm { + return nil + } + return createForm(pe, baseURL+schemaCredential.ResourceURI, message.AppCBOR.String(), []string{"readproperty", "writeproperty"}) +} diff --git a/bridge/resources/thingDescription/ocfResources.jsonld b/bridge/resources/thingDescription/ocfResources.jsonld index c7766334..116d6f52 100644 --- a/bridge/resources/thingDescription/ocfResources.jsonld +++ b/bridge/resources/thingDescription/ocfResources.jsonld @@ -26,7 +26,10 @@ "readOnly": true, "format": "uuid" } - } + }, + "@type": [ + "oic.wk.d" + ] }, "/oic/mnt": { "title": "Maintenance", @@ -36,7 +39,10 @@ "title": "Factory Reset", "type": "boolean" } - } + }, + "@type": [ + "oic.wk.mnt" + ] }, "/CoapCloudConfResURI": { "title": "CoapCloudConfResURI", @@ -76,7 +82,10 @@ "title": "Last error code", "type": "integer" } - } + }, + "@type": [ + "oic.r.coapcloudconf" + ] }, "/oic/sec/cred": { "title": "Credentials", @@ -240,6 +249,9 @@ "required": [ "creds", "rowneruuid" + ], + "@type": [ + "oic.r.cred" ] } } diff --git a/bridge/test/test.go b/bridge/test/test.go index f181b486..931485a7 100644 --- a/bridge/test/test.go +++ b/bridge/test/test.go @@ -155,40 +155,70 @@ func NewBridgedDeviceWithThingDescription(t *testing.T, s *service.Service, id s return NewBridgedDeviceWithConfig(t, s, cfg, opts...) } -func ThingDescription(deviceID string, cloudEnabled, credentialEnabled bool) (wotTD.ThingDescription, error) { - td := wotTD.ThingDescription{} - td.Context = &thingDescription.Context - td.Type = &wotTD.TypeDeclaration{StringArray: []string{"Thing"}} - id, err := uri.Parse("urn:uuid:" + deviceID) - if err != nil { - return wotTD.ThingDescription{}, err - } - td.ID = id - - td.Properties = make(map[string]wotTD.PropertyElement) +func getProperties(deviceID string, cloudEnabled, credentialEnabled bool) (map[string]wotTD.PropertyElement, error) { + properties := make(map[string]wotTD.PropertyElement) deviceResource, ok := thingDescriptionResource.GetOCFResourcePropertyElement(schemaDevice.ResourceURI) if !ok { - return wotTD.ThingDescription{}, errors.New("device resource not found") + return nil, errors.New("device resource not found") + } + baseURL := "/" + deviceID + err := thingDescriptionResource.PatchDeviceResourcePropertyElement(&deviceResource, baseURL, "", true) + if err != nil { + return nil, err } - td.Properties[schemaDevice.ResourceURI] = deviceResource + properties[schemaDevice.ResourceURI] = deviceResource + maintenanceResource, ok := thingDescriptionResource.GetOCFResourcePropertyElement(schemaMaintenance.ResourceURI) if !ok { - return wotTD.ThingDescription{}, errors.New("maintenance resource not found") + return nil, errors.New("maintenance resource not found") } - td.Properties[schemaMaintenance.ResourceURI] = maintenanceResource + properties[schemaMaintenance.ResourceURI] = maintenanceResource + err = thingDescriptionResource.PatchMaintenanceResourcePropertyElement(&maintenanceResource, baseURL, true) + if err != nil { + return nil, err + } + properties[schemaMaintenance.ResourceURI] = maintenanceResource + if cloudEnabled { cloudResource, ok := thingDescriptionResource.GetOCFResourcePropertyElement(schemaCloud.ResourceURI) if !ok { - return wotTD.ThingDescription{}, errors.New("cloud resource not found") + return nil, errors.New("cloud resource not found") + } + err = thingDescriptionResource.PatchCloudResourcePropertyElement(&cloudResource, baseURL, true) + if err != nil { + return nil, err } - td.Properties[schemaCloud.ResourceURI] = cloudResource + properties[schemaCloud.ResourceURI] = cloudResource } + if credentialEnabled { credentialResource, ok := thingDescriptionResource.GetOCFResourcePropertyElement(credential.ResourceURI) if !ok { - return wotTD.ThingDescription{}, errors.New("credential resource not found") + return nil, errors.New("credential resource not found") + } + err = thingDescriptionResource.PatchCredentialResourcePropertyElement(&credentialResource, baseURL, true) + if err != nil { + return nil, err } - td.Properties[credential.ResourceURI] = credentialResource + properties[credential.ResourceURI] = credentialResource + } + return properties, nil +} + +func ThingDescription(deviceID string, cloudEnabled, credentialEnabled bool) (wotTD.ThingDescription, error) { + td := wotTD.ThingDescription{} + td.Context = &thingDescription.Context + td.Type = &wotTD.TypeDeclaration{StringArray: []string{"Thing"}} + id, err := uri.Parse("urn:uuid:" + deviceID) + if err != nil { + return wotTD.ThingDescription{}, err + } + td.ID = id + + properties, err := getProperties(deviceID, cloudEnabled, credentialEnabled) + if err != nil { + return wotTD.ThingDescription{}, err } + td.Properties = properties return td, nil } diff --git a/cmd/bridge-device/device.go b/cmd/bridge-device/device.go index fea5ef69..e788d875 100644 --- a/cmd/bridge-device/device.go +++ b/cmd/bridge-device/device.go @@ -23,7 +23,10 @@ import ( "github.com/web-of-things-open-source/thingdescription-go/thingDescription" ) -const myPropertyKey = "my-property" +const ( + ResourceType = "oic.d.virtual" + myPropertyKey = "my-property" +) //go:embed bridge-device.jsonld var bdResourcesData []byte diff --git a/cmd/bridge-device/main.go b/cmd/bridge-device/main.go index 348f1b65..c9cf3727 100644 --- a/cmd/bridge-device/main.go +++ b/cmd/bridge-device/main.go @@ -177,7 +177,7 @@ func main() { newDevice := func(id uuid.UUID, piid uuid.UUID) (service.Device, error) { return device.New(device.Config{ Name: fmt.Sprintf("bridged-device-%d", i), - ResourceTypes: []string{"oic.d.virtual"}, + ResourceTypes: []string{ResourceType}, ID: id, ProtocolIndependentID: piid, MaxMessageSize: cfg.Config.API.CoAP.MaxMessageSize,