Skip to content

Commit

Permalink
cleanup interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
jkralik committed Jan 17, 2024
1 parent 633185b commit ea0acaf
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 70 deletions.
67 changes: 49 additions & 18 deletions bridge/device/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,21 @@ import (
"github.com/plgd-dev/go-coap/v3/pkg/sync"
)

type Resource interface {
Close()
ETag() []byte
GetHref() string
GetResourceTypes() []string
GetResourceInterfaces() []string
HandleRequest(req *net.Request) (*pool.Message, error)
GetPolicyBitMask() schema.BitMask
SetObserveHandler(createSubscription resources.CreateSubscriptionFunc)
UpdateETag()
}

type Device struct {
cfg Config
resources *sync.Map[string, *resources.Resource]
resources *sync.Map[string, Resource]
cloudManager *cloud.Manager
onDeviceUpdated func(d *Device)
}
Expand Down Expand Up @@ -95,7 +107,7 @@ func (cfg *Config) Validate() error {
return nil
}

func New(cfg Config, onDeviceUpdated func(d *Device)) *Device {
func New(cfg Config, onDeviceUpdated func(d *Device), additionalProperties resourcesDevice.GetAdditionalPropertiesForResponseFunc) *Device {
if onDeviceUpdated == nil {
onDeviceUpdated = func(d *Device) {
// do nothing
Expand All @@ -104,23 +116,23 @@ func New(cfg Config, onDeviceUpdated func(d *Device)) *Device {
cfg.ResourceTypes = resources.Unique(append(cfg.ResourceTypes, plgdDevice.ResourceType))
d := &Device{
cfg: cfg,
resources: sync.NewMap[string, *resources.Resource](),
resources: sync.NewMap[string, Resource](),
onDeviceUpdated: onDeviceUpdated,
}
d.AddResource(resourcesDevice.New(plgdDevice.ResourceURI, d).Resource)
d.AddResource(resourcesDevice.New(plgdDevice.ResourceURI, d, additionalProperties))

if cfg.Cloud.Enabled {
d.cloudManager = cloud.New(d.cfg.ID, func() {
d.onDeviceUpdated(d)
}, d.HandleRequest, d.GetLinksFilteredBy, cfg.MaxMessageSize)
d.AddResource(cloudResource.New(cloudSchema.ResourceURI, d.cloudManager).Resource)
d.AddResource(cloudResource.New(cloudSchema.ResourceURI, d.cloudManager))
d.cloudManager.ImportConfig(cfg.Cloud.Config)
}
return d
}

func (d *Device) AddResource(resource *resources.Resource) {
d.resources.Store(resource.Href, resource)
func (d *Device) AddResource(resource Resource) {
d.resources.Store(resource.GetHref(), resource)
}

func (d *Device) Init() {
Expand All @@ -133,12 +145,23 @@ func (d *Device) UnregisterFromCloud() {
}
}

func (d *Device) Range(f func(key string, resource *resources.Resource) bool) {
func (d *Device) Range(f func(resourceHref string, resource Resource) bool) {
d.resources.Range(f)
}

func (d *Device) GetResource(key string) (*resources.Resource, bool) {
return d.resources.Load(key)
func (d *Device) GetResource(resourceHref string) (Resource, bool) {
return d.resources.Load(resourceHref)
}

func hasResourceTypes(resourceTypes []string, oneOf []string) bool {
for _, rt := range oneOf {
for _, rrt := range resourceTypes {
if rt == rrt {
return true
}
}
}
return false
}

func (d *Device) GetLinksFilteredBy(endpoints schema.Endpoints, deviceIDfilter uuid.UUID, resourceTypesFitler []string, policyBitMaskFitler schema.BitMask) (links schema.ResourceLinks) {
Expand All @@ -147,19 +170,19 @@ func (d *Device) GetLinksFilteredBy(endpoints schema.Endpoints, deviceIDfilter u
return nil
}
links = make(schema.ResourceLinks, 0, d.resources.Length())
d.resources.Range(func(key string, resource *resources.Resource) bool {
if len(resourceTypesFitler) > 0 && !resource.HasResourceTypes(resourceTypesFitler) {
d.resources.Range(func(key string, resource Resource) bool {
if len(resourceTypesFitler) > 0 && !hasResourceTypes(resource.GetResourceTypes(), resourceTypesFitler) {
return true
}
if policyBitMaskFitler != 0 && resource.PolicyBitMask&policyBitMaskFitler == 0 {
if policyBitMaskFitler != 0 && resource.GetPolicyBitMask()&policyBitMaskFitler == 0 {
return true
}
links = append(links, schema.ResourceLink{
Href: key,
ResourceTypes: resource.ResourceTypes,
Interfaces: resource.ResourceInterfaces,
ResourceTypes: resource.GetResourceTypes(),
Interfaces: resource.GetResourceInterfaces(),
Policy: &schema.Policy{
BitMask: resource.PolicyBitMask & (^resources.PublishToCloud),
BitMask: resource.GetPolicyBitMask() & (^resources.PublishToCloud),
},
Anchor: "ocf://" + d.GetID().String(),
DeviceID: d.GetID().String(),
Expand All @@ -174,8 +197,16 @@ func (d *Device) GetLinks(request *net.Request) (links schema.ResourceLinks) {
return d.GetLinksFilteredBy(request.Endpoints, request.DeviceID(), request.ResourceTypes(), 0)
}

func (d *Device) RemoveResource(resource *resources.Resource) {
d.resources.Delete(resource.Href)
func (d *Device) LoadAndDeleteResource(resourceHref string) (Resource, bool) {
return d.resources.LoadAndDelete(resourceHref)
}

func (d *Device) CloseAndDeleteResource(resourceHref string) bool {
r, ok := d.resources.LoadAndDelete(resourceHref)
if ok {
r.Close()
}
return ok
}

func createResponseNotFound(ctx context.Context, uri string, token message.Token) *pool.Message {
Expand Down
50 changes: 42 additions & 8 deletions bridge/resources/device/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,36 +39,70 @@ type Device interface {
GetProtocolIndependentID() uuid.UUID
}

type GetAdditionalPropertiesForResponseFunc func() map[string]interface{}

type Resource struct {
*resources.Resource
device Device
device Device
getAdditionalProperties GetAdditionalPropertiesForResponseFunc
}

func New(uri string, dev Device) *Resource {
func New(uri string, dev Device, getAdditionalProperties GetAdditionalPropertiesForResponseFunc) *Resource {
if getAdditionalProperties == nil {
getAdditionalProperties = func() map[string]interface{} { return nil }
}
d := &Resource{
device: dev,
device: dev,
getAdditionalProperties: getAdditionalProperties,
}
d.Resource = resources.NewResource(uri, d.Get, nil, dev.GetResourceTypes(), []string{interfaces.OC_IF_BASELINE, interfaces.OC_IF_R})
return d
}

func mergeCBORStructs(a ...interface{}) interface{} {
var merged map[interface{}]interface{}
for _, v := range a {
if v == nil {
continue
}
data, err := cbor.Encode(v)
if err != nil {
continue
}
var m map[interface{}]interface{}
err = cbor.Decode(data, &m)
if err != nil {
continue
}
if merged == nil {
merged = m
} else {
for k, v := range m {
merged[k] = v
}
}
}
return merged
}

func (d *Resource) Get(request *net.Request) (*pool.Message, error) {
v := device.Device{
additionalProperties := d.getAdditionalProperties()
deviceProperties := device.Device{
ID: d.device.GetID().String(),
Name: d.device.GetName(),
ProtocolIndependentID: d.device.GetProtocolIndependentID().String(),
//DataModelVersion: "ocf.res.1.3.0",

Check failure on line 94 in bridge/resources/device/resource.go

View workflow job for this annotation

GitHub Actions / lint

File is not `gofumpt`-ed (gofumpt)
//SpecificationVersion: "ocf.2.0.5",
}
if request.Interface() == interfaces.OC_IF_BASELINE {
v.ResourceTypes = d.Resource.ResourceTypes
v.Interfaces = d.Resource.ResourceInterfaces
deviceProperties.ResourceTypes = d.Resource.ResourceTypes
deviceProperties.Interfaces = d.Resource.ResourceInterfaces
}

properties := mergeCBORStructs(additionalProperties, deviceProperties)
res := pool.NewMessage(request.Context())
res.SetCode(codes.Content)
res.SetContentFormat(message.AppOcfCbor)
data, err := cbor.Encode(v)
data, err := cbor.Encode(properties)
if err != nil {
return nil, err
}
Expand Down
24 changes: 15 additions & 9 deletions bridge/resources/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,20 @@ type Resource struct {
etag atomic.Uint64
}

func (r *Resource) HasResourceTypes(resourceTypes []string) bool {
for _, rt := range resourceTypes {
for _, rrt := range r.ResourceTypes {
if rt == rrt {
return true
}
}
}
return false
func (r *Resource) GetPolicyBitMask() schema.BitMask {
return r.PolicyBitMask
}

func (r *Resource) GetHref() string {
return r.Href
}

func (r *Resource) GetResourceTypes() []string {
return r.ResourceTypes
}

func (r *Resource) GetResourceInterfaces() []string {
return r.ResourceInterfaces
}

func Unique(strSlice []string) []string {
Expand Down Expand Up @@ -165,6 +170,7 @@ func (r *Resource) wakeWatchSubscriptions() {
}
}

// Close closes resource and cancel all subscriptions
func (r *Resource) Close() {
if !r.closed.CompareAndSwap(false, true) {
return
Expand Down
Loading

0 comments on commit ea0acaf

Please sign in to comment.