adds correct resultContent handling

This commit is contained in:
Ronald Steinke 2018-10-05 15:31:05 +02:00
parent 1647abd1c1
commit 8cf2ba09ae
8 changed files with 38 additions and 62 deletions

View File

@ -370,7 +370,8 @@ class OneM2MMQTTClient(OneM2MClient):
sp_id, cse_id, _ = split_onem2m_address(response.to)
response.content = self._decode(
encode_onem2m_content(response.content, 'application/json',
path=sp_id + cse_id)[1]
path=sp_id + cse_id,
fields=response.fields)[1]
)
self._publish_message(

View File

@ -105,6 +105,7 @@ class OneM2MMapper(BasicMapper):
path,
self.originator,
filter_criteria=fc,
rcn=5,
**request_options
)).get()

View File

@ -122,15 +122,17 @@ class ResponseType(OneM2MIntEnum):
# @unique
# class ResultConentE(OneM2MIntEnum):
# nothing = 0
# attributes = 1
# hierarchical_address = 2
# hierarchical_address_and_attributes = 3
# attributes_and_child_resources = 4
# attributes_and_child_resource_references = 6
# child_resource_references = 6
# original_resource = 7
class ResultContentE(OneM2MIntEnum):
nothing = 0
attributes = 1
hierarchical_address = 2
hierarchical_address_and_attributes = 3
attributes_and_child_resources = 4
attributes_and_child_resource_references = 5
child_resource_references = 6
original_resource = 7
child_resources = 8
modified_attributes = 9
@unique

View File

@ -49,7 +49,7 @@ class OneM2MSerializer(LoggerMixin):
except (TypeError, AttributeError, KeyError, ValueError):
raise CSEValueError("Invalid entry in child resources: %s",
child_resource)
if resource_type is Notification and "notificationEvent" in data:
if resource_type is Notification and data.get("notificationEvent"):
representation = data["notificationEvent"]["representation"]
representation = self.decode(self.dumps(representation))
data["notificationEvent"]["representation"] = representation
@ -62,7 +62,10 @@ class OneM2MSerializer(LoggerMixin):
class OneM2MDictSerializer(OneM2MSerializer):
def encode_resource(self, resource, pretty=False, path=None, encoding="utf-8", fields=None,
encapsulated=False):
representation = resource.values
if fields and isinstance(resource, OneM2MResource):
representation = {k: v for k, v in resource.values.items() if fields and k in fields}
else:
representation = resource.values
self.logger.debug("Encoding representation: %s", representation)
@ -93,7 +96,7 @@ class OneM2MDictSerializer(OneM2MSerializer):
return resource_id
return val_path + resource_id
if isinstance(resource, OneM2MResource):
if isinstance(resource, OneM2MResource) and "childResource" in representation:
def get_child_rep(c):
return {
@ -112,53 +115,12 @@ class OneM2MDictSerializer(OneM2MSerializer):
if isinstance(resource.oldest, ContentInstance):
representation['oldest'] = resource.oldest.resourceID
# cleans representation
def clean_representation(o):
try:
# removes empty attributes
empty_keys = []
for k, v in o.items():
if v is None:
empty_keys.append(k)
elif isinstance(v, OneM2MEntity):
o[k] = self.encode_resource(v, pretty, path, encoding, fields)
elif isinstance(v, list):
def encode_list_item(item):
if isinstance(item, OneM2MEntity):
return self.encode_resource(item, pretty, path, encoding, fields)
return item
if len(v):
o[k] = map(encode_list_item, v)
else:
empty_keys.append(k)
else:
try:
if len(v) == 0:
empty_keys.append(k)
except TypeError:
pass
for k in empty_keys:
del o[k]
for k, v in o.items():
if not isinstance(v, (unicode, str, bool, datetime,
OneM2MIntEnum)):
clean_representation(v)
except AttributeError:
if isinstance(o, list):
for p in o:
clean_representation(p)
if not isinstance(resource, OneM2MContentResource):
representation = {
get_short_resource_name(k) or get_short_attribute_name(k) or
get_short_member_name(k): v for
k, v in representation.items()}
clean_representation(representation)
if not isinstance(resource, (OneM2MResource, Notification,
SecurityInfo, OneM2MContentResource)):
return representation

View File

@ -27,9 +27,6 @@ def encode_onem2m_content(content, content_type, pretty=False, path=None,
if content is None:
return None, None
fields = fields # TODO(rst): maybe necessary
# fields = ["resourceID"]
serializer = get_onem2m_encoder(content_type)
data = serializer.encode_resource(content, pretty=pretty, path=path,

View File

@ -385,7 +385,7 @@ class OneM2MResponse(object):
"""Class representing a OneM2M response"""
def __init__(self, status_code, request=None, rqi=None, pc=None, to=None,
fr=None, rsc=None):
fr=None, rsc=None, fields=None):
# Operation result
if isinstance(status_code, STATUS):
self.response_status_code = status_code
@ -405,6 +405,7 @@ class OneM2MResponse(object):
self.originator = fr
# Resource content to be transferred.
self.content = pc
self.fields = fields
@property
def status_code(self):

View File

@ -31,7 +31,7 @@ from openmtc_onem2m.model import (ExpiringResource, Notification,
DiscResTypeE, Container, AccessControlPolicy,
AccessControlPolicyIDHolder, AccessControlRuleC,
DynAuthDasRequestC, SecurityInfo, SecurityInfoTypeE,
AE, ContentInstance)
AE, ResultContentE, ContentInstance)
from openmtc_onem2m.transport import (OneM2MResponse, OneM2MRequest,
OneM2MOperation, OneM2MErrorResponse)
from openmtc_onem2m.util import split_onem2m_address
@ -804,6 +804,12 @@ class OneM2MDefaultController(LoggerMixin):
self.fields = self.request.content and self.request.content.values
def _handle_retrieve(self):
try:
self.request.rcn = ResultContentE(int(self.request.rcn))
except ValueError:
raise CSEBadRequest()
except TypeError:
self.request.rcn = ResultContentE.attributes
try:
fu = self.request.filter_criteria.filterUsage
except AttributeError:
@ -887,10 +893,15 @@ class OneM2MDefaultController(LoggerMixin):
if self.fields and isinstance(self.fields, list):
res.set_values({k: v if k in self.fields else None for
k, v in res.get_values().items()})
return self._retrieve_children()
if self.request.rcn == ResultContentE.attributes_and_child_resource_references:
self._retrieve_children()
def _send_retrieve_response(self):
return OneM2MResponse(STATUS_OK, pc=self.result, request=self.request)
fields = self.resource.values.keys()
if self.request.rcn != ResultContentE.attributes_and_child_resource_references:
fields = [k for k in fields if k != 'childResource']
return OneM2MResponse(STATUS_OK, pc=self.result, request=self.request, fields=fields)
def _retrieve_children(self):
return self._retrieve_children_for_resource(self.resource)

View File

@ -339,7 +339,8 @@ class OpenMTCWSGIApplication(LoggerMixin):
try:
content_type, payload = encode_onem2m_content(response.content,
accept, pretty,
path=resource_id_pre)
path=resource_id_pre,
fields=response.fields)
except CSEContentsUnacceptable as e:
status_code = e.status_code
content_type = "text/plain"