Skip to content

Commit

Permalink
allow to custom form properties
Browse files Browse the repository at this point in the history
  • Loading branch information
jkralik committed May 13, 2024
1 parent e10f602 commit b553d1a
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 43 deletions.
68 changes: 47 additions & 21 deletions bridge/device/thingDescription/thingDescription.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package thingDescription

import (
"fmt"
"net/http"
"net/url"

Expand Down Expand Up @@ -99,9 +100,20 @@ func (p PropertyElementOperations) ToSupportedOperations() resources.SupportedOp
return ops | resources.SupportedOperationRead | resources.SupportedOperationWrite
}

func createForm(hrefUri *url.URL, covMethod string, op thingDescription.StickyDescription, contentType message.MediaType) thingDescription.FormElementProperty {
type CreateFormFunc func(hrefUri *url.URL, op thingDescription.StickyDescription, contentType message.MediaType) (thingDescription.FormElementProperty, bool)

func CreateCOAPForm(hrefUri *url.URL, op thingDescription.StickyDescription, contentType message.MediaType) (thingDescription.FormElementProperty, bool) {
methods := map[thingDescription.StickyDescription]string{
thingDescription.Readproperty: http.MethodGet,
thingDescription.Writeproperty: http.MethodPost,
thingDescription.Observeproperty: http.MethodGet,
}
method, ok := methods[op]
if !ok {
return thingDescription.FormElementProperty{}, false
}
additionalFields := map[string]interface{}{
"cov:method": covMethod,
"cov:method": method,
"cov:accept": float64(contentType),
}
ops := []string{string(op)}
Expand All @@ -117,24 +129,46 @@ func createForm(hrefUri *url.URL, covMethod string, op thingDescription.StickyDe
StringArray: ops,
},
AdditionalFields: additionalFields,
}
}, true
}

func SetForms(hrefUri *url.URL, ops resources.SupportedOperation, contentType message.MediaType) []thingDescription.FormElementProperty {
type CreateFormsFunc func(hrefUri *url.URL, ops resources.SupportedOperation, contentType message.MediaType) []thingDescription.FormElementProperty

func CreateCOAPForms(hrefUri *url.URL, ops resources.SupportedOperation, contentType message.MediaType) []thingDescription.FormElementProperty {
forms := make([]thingDescription.FormElementProperty, 0, 3)
if ops.HasOperation(resources.SupportedOperationWrite) {
forms = append(forms, createForm(hrefUri, http.MethodPost, thingDescription.Writeproperty, contentType))
form, ok := CreateCOAPForm(hrefUri, thingDescription.Writeproperty, contentType)
if ok {
forms = append(forms, form)
}
}
if ops.HasOperation(resources.SupportedOperationRead) {
forms = append(forms, createForm(hrefUri, http.MethodGet, thingDescription.Readproperty, contentType))
form, ok := CreateCOAPForm(hrefUri, thingDescription.Readproperty, contentType)
if ok {
forms = append(forms, form)
}
}
if ops.HasOperation(resources.SupportedOperationObserve) {
forms = append(forms, createForm(hrefUri, http.MethodGet, thingDescription.Observeproperty, contentType))
form, ok := CreateCOAPForm(hrefUri, thingDescription.Observeproperty, contentType)
if ok {
forms = append(forms, form)
}
}
return forms
}

func PatchPropertyElement(prop thingDescription.PropertyElement, types []string, setForm bool, deviceID uuid.UUID, href string, ops resources.SupportedOperation, contentType message.MediaType) (thingDescription.PropertyElement, error) {
func GetPropertyHref(deviceID uuid.UUID, href string) (*url.URL, error) {
if len(href) == 0 {
return nil, fmt.Errorf("href is empty")

Check failure on line 162 in bridge/device/thingDescription/thingDescription.go

View workflow job for this annotation

GitHub Actions / lint

fmt.Errorf can be replaced with errors.New (perfsprint)
}
hrefStr := href
if deviceID != uuid.Nil {
hrefStr += "?di=" + deviceID.String()
}
return url.Parse(hrefStr)
}

func PatchPropertyElement(prop thingDescription.PropertyElement, types []string, deviceID uuid.UUID, href string, ops resources.SupportedOperation, contentType message.MediaType, createForms CreateFormsFunc) (thingDescription.PropertyElement, error) {
if len(types) > 0 {
prop.Type = &thingDescription.TypeDeclaration{
StringArray: types,
Expand All @@ -144,26 +178,18 @@ func PatchPropertyElement(prop thingDescription.PropertyElement, types []string,
prop.Observable = BoolToPtr(propOps.Observable)
prop.ReadOnly = BoolToPtr(propOps.ReadOnly)
prop.WriteOnly = BoolToPtr(propOps.WriteOnly)
if !setForm {
if createForms == nil {
return prop, nil
}
opsStrs := SupportedOperationToTDOperations(ops)
if len(opsStrs) == 0 {
return prop, nil
}
var hrefUri *url.URL
if len(href) > 0 {
hrefStr := href
if deviceID != uuid.Nil {
hrefStr += "?di=" + deviceID.String()
}
var err error
hrefUri, err = url.Parse(hrefStr)
if err != nil {
return thingDescription.PropertyElement{}, err
}
hrefUri, err := GetPropertyHref(deviceID, href)
if err != nil {
return thingDescription.PropertyElement{}, err
}
prop.Forms = SetForms(hrefUri, ops, contentType)
prop.Forms = createForms(hrefUri, ops, contentType)
return prop, nil
}

Expand Down
20 changes: 10 additions & 10 deletions bridge/resources/thingDescription/ocfResources.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,27 +40,27 @@ func GetOCFResourcePropertyElement(resourceHref string) (thingDescription.Proper
return prop, true
}

func patchResourcePropertyElement(pe thingDescription.PropertyElement, deviceID uuid.UUID, resourceTypes []string, resourceHref string, contentType message.MediaType) (thingDescription.PropertyElement, error) {
func patchResourcePropertyElement(pe thingDescription.PropertyElement, deviceID uuid.UUID, resourceTypes []string, resourceHref string, contentType message.MediaType, createForms bridgeTD.CreateFormsFunc) (thingDescription.PropertyElement, error) {
propOps := bridgeTD.GetPropertyElementOperations(pe)
return bridgeTD.PatchPropertyElement(pe, resourceTypes, true, deviceID, resourceHref, propOps.ToSupportedOperations(), contentType)
return bridgeTD.PatchPropertyElement(pe, resourceTypes, deviceID, resourceHref, propOps.ToSupportedOperations(), contentType, createForms)
}

func PatchDeviceResourcePropertyElement(pe thingDescription.PropertyElement, deviceID uuid.UUID, baseURL string, contentType message.MediaType, deviceType string) (thingDescription.PropertyElement, error) {
func PatchDeviceResourcePropertyElement(pe thingDescription.PropertyElement, deviceID uuid.UUID, baseURL string, contentType message.MediaType, deviceType string, createForms bridgeTD.CreateFormsFunc) (thingDescription.PropertyElement, error) {
var types []string
if deviceType != "" {
types = []string{schemaDevice.ResourceType, deviceType}
}
return patchResourcePropertyElement(pe, deviceID, types, baseURL+schemaDevice.ResourceURI, contentType)
return patchResourcePropertyElement(pe, deviceID, types, baseURL+schemaDevice.ResourceURI, contentType, createForms)
}

func PatchMaintenanceResourcePropertyElement(pe thingDescription.PropertyElement, deviceID uuid.UUID, baseURL string, contentType message.MediaType) (thingDescription.PropertyElement, error) {
return patchResourcePropertyElement(pe, deviceID, []string{schemaMaintenance.ResourceType}, baseURL+schemaMaintenance.ResourceURI, contentType)
func PatchMaintenanceResourcePropertyElement(pe thingDescription.PropertyElement, deviceID uuid.UUID, baseURL string, contentType message.MediaType, createForms bridgeTD.CreateFormsFunc) (thingDescription.PropertyElement, error) {
return patchResourcePropertyElement(pe, deviceID, []string{schemaMaintenance.ResourceType}, baseURL+schemaMaintenance.ResourceURI, contentType, createForms)
}

func PatchCloudResourcePropertyElement(pe thingDescription.PropertyElement, deviceID uuid.UUID, baseURL string, contentType message.MediaType) (thingDescription.PropertyElement, error) {
return patchResourcePropertyElement(pe, deviceID, []string{schemaCloud.ResourceType}, baseURL+schemaCloud.ResourceURI, contentType)
func PatchCloudResourcePropertyElement(pe thingDescription.PropertyElement, deviceID uuid.UUID, baseURL string, contentType message.MediaType, createForms bridgeTD.CreateFormsFunc) (thingDescription.PropertyElement, error) {
return patchResourcePropertyElement(pe, deviceID, []string{schemaCloud.ResourceType}, baseURL+schemaCloud.ResourceURI, contentType, createForms)
}

func PatchCredentialResourcePropertyElement(pe thingDescription.PropertyElement, deviceID uuid.UUID, baseURL string, contentType message.MediaType) (thingDescription.PropertyElement, error) {
return patchResourcePropertyElement(pe, deviceID, []string{schemaCredential.ResourceType}, baseURL+schemaCredential.ResourceURI, contentType)
func PatchCredentialResourcePropertyElement(pe thingDescription.PropertyElement, deviceID uuid.UUID, baseURL string, contentType message.MediaType, createForms bridgeTD.CreateFormsFunc) (thingDescription.PropertyElement, error) {
return patchResourcePropertyElement(pe, deviceID, []string{schemaCredential.ResourceType}, baseURL+schemaCredential.ResourceURI, contentType, createForms)
}
16 changes: 10 additions & 6 deletions bridge/test/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,12 @@ func GetPropertyElement(td wotTD.ThingDescription, device bridgeDeviceTD.Device,
if !ok {
return wotTD.PropertyElement{}, false
}
propElement, err := bridgeDeviceTD.PatchPropertyElement(propElement, resource.GetResourceTypes(), endpoint != "", device.GetID(), resource.GetHref(),
resource.SupportsOperations(), contentType)
var f bridgeDeviceTD.CreateFormsFunc
if endpoint != "" {
f = bridgeDeviceTD.CreateCOAPForms
}
propElement, err := bridgeDeviceTD.PatchPropertyElement(propElement, resource.GetResourceTypes(), device.GetID(), resource.GetHref(),
resource.SupportsOperations(), contentType, f)
return propElement, err == nil
}

Expand Down Expand Up @@ -163,7 +167,7 @@ func getOCFResourcesProperties(deviceID uuid.UUID, baseURL string, cloudEnabled,
if !ok {
return nil, errors.New("device resource not found")
}
deviceResource, err := thingDescriptionResource.PatchDeviceResourcePropertyElement(deviceResource, deviceID, baseURL, message.AppCBOR, "")
deviceResource, err := thingDescriptionResource.PatchDeviceResourcePropertyElement(deviceResource, deviceID, baseURL, message.AppCBOR, "", bridgeDeviceTD.CreateCOAPForms)
if err != nil {
return nil, err
}
Expand All @@ -174,7 +178,7 @@ func getOCFResourcesProperties(deviceID uuid.UUID, baseURL string, cloudEnabled,
return nil, errors.New("maintenance resource not found")
}
properties[schemaMaintenance.ResourceURI] = maintenanceResource
maintenanceResource, err = thingDescriptionResource.PatchMaintenanceResourcePropertyElement(maintenanceResource, deviceID, baseURL, message.AppCBOR)
maintenanceResource, err = thingDescriptionResource.PatchMaintenanceResourcePropertyElement(maintenanceResource, deviceID, baseURL, message.AppCBOR, bridgeDeviceTD.CreateCOAPForms)
if err != nil {
return nil, err
}
Expand All @@ -185,7 +189,7 @@ func getOCFResourcesProperties(deviceID uuid.UUID, baseURL string, cloudEnabled,
if !ok {
return nil, errors.New("cloud resource not found")
}
cloudResource, err = thingDescriptionResource.PatchCloudResourcePropertyElement(cloudResource, deviceID, baseURL, message.AppCBOR)
cloudResource, err = thingDescriptionResource.PatchCloudResourcePropertyElement(cloudResource, deviceID, baseURL, message.AppCBOR, bridgeDeviceTD.CreateCOAPForms)
if err != nil {
return nil, err
}
Expand All @@ -197,7 +201,7 @@ func getOCFResourcesProperties(deviceID uuid.UUID, baseURL string, cloudEnabled,
if !ok {
return nil, errors.New("credential resource not found")
}
credentialResource, err = thingDescriptionResource.PatchCredentialResourcePropertyElement(credentialResource, deviceID, baseURL, message.AppCBOR)
credentialResource, err = thingDescriptionResource.PatchCredentialResourcePropertyElement(credentialResource, deviceID, baseURL, message.AppCBOR, bridgeDeviceTD.CreateCOAPForms)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/bridge-device/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ apis:
id: 8f596b43-29c0-4147-8b40-e99268ab30f7
name: "my-bridge-example"
externalAddresses:
- "127.0.0.1:15683"
- "[::1]:15683"
- "127.0.0.1:35683"
- "[::1]:35683"
maxMessageSize: 2097152
log:
level: "info"
Expand Down
6 changes: 3 additions & 3 deletions cmd/bridge-device/device/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ func GetPropertyDescriptionForTestResource() thingDescription.PropertyElement {
}
}

func PatchTestResourcePropertyElement(pe thingDescription.PropertyElement, deviceID uuid.UUID, href string, contentType message.MediaType) (thingDescription.PropertyElement, error) {
func PatchTestResourcePropertyElement(pe thingDescription.PropertyElement, deviceID uuid.UUID, href string, contentType message.MediaType, createForms bridgeTD.CreateFormsFunc) (thingDescription.PropertyElement, error) {
propOps := bridgeTD.GetPropertyElementOperations(pe)
return bridgeTD.PatchPropertyElement(pe, []string{TestResourceType}, true, deviceID, href,
propOps.ToSupportedOperations(), contentType)
return bridgeTD.PatchPropertyElement(pe, []string{TestResourceType}, deviceID, href,
propOps.ToSupportedOperations(), contentType, createForms)
}

func GetAdditionalProperties() map[string]interface{} {
Expand Down
6 changes: 5 additions & 1 deletion cmd/bridge-device/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,11 @@ func patchPropertyElement(td wotTD.ThingDescription, dev *device.Device, endpoin
if !ok {
return wotTD.PropertyElement{}, false
}
propElement, err := thingDescription.PatchPropertyElement(propElement, resource.GetResourceTypes(), endpoint != "", dev.GetID(), resource.GetHref(), resource.SupportsOperations(), message.AppCBOR)
var f thingDescription.CreateFormsFunc
if endpoint != "" {
f = thingDescription.CreateCOAPForms
}
propElement, err := thingDescription.PatchPropertyElement(propElement, resource.GetResourceTypes(), dev.GetID(), resource.GetHref(), resource.SupportsOperations(), message.AppCBOR, f)
return propElement, err == nil
}

Expand Down

0 comments on commit b553d1a

Please sign in to comment.