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) sp_id, cse_id, _ = split_onem2m_address(response.to)
response.content = self._decode( response.content = self._decode(
encode_onem2m_content(response.content, 'application/json', 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( self._publish_message(

View File

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

View File

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

View File

@ -49,7 +49,7 @@ class OneM2MSerializer(LoggerMixin):
except (TypeError, AttributeError, KeyError, ValueError): except (TypeError, AttributeError, KeyError, ValueError):
raise CSEValueError("Invalid entry in child resources: %s", raise CSEValueError("Invalid entry in child resources: %s",
child_resource) 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 = data["notificationEvent"]["representation"]
representation = self.decode(self.dumps(representation)) representation = self.decode(self.dumps(representation))
data["notificationEvent"]["representation"] = representation data["notificationEvent"]["representation"] = representation
@ -62,6 +62,9 @@ class OneM2MSerializer(LoggerMixin):
class OneM2MDictSerializer(OneM2MSerializer): class OneM2MDictSerializer(OneM2MSerializer):
def encode_resource(self, resource, pretty=False, path=None, encoding="utf-8", fields=None, def encode_resource(self, resource, pretty=False, path=None, encoding="utf-8", fields=None,
encapsulated=False): encapsulated=False):
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 representation = resource.values
self.logger.debug("Encoding representation: %s", representation) self.logger.debug("Encoding representation: %s", representation)
@ -93,7 +96,7 @@ class OneM2MDictSerializer(OneM2MSerializer):
return resource_id return resource_id
return val_path + resource_id return val_path + resource_id
if isinstance(resource, OneM2MResource): if isinstance(resource, OneM2MResource) and "childResource" in representation:
def get_child_rep(c): def get_child_rep(c):
return { return {
@ -112,53 +115,12 @@ class OneM2MDictSerializer(OneM2MSerializer):
if isinstance(resource.oldest, ContentInstance): if isinstance(resource.oldest, ContentInstance):
representation['oldest'] = resource.oldest.resourceID 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): if not isinstance(resource, OneM2MContentResource):
representation = { representation = {
get_short_resource_name(k) or get_short_attribute_name(k) or get_short_resource_name(k) or get_short_attribute_name(k) or
get_short_member_name(k): v for get_short_member_name(k): v for
k, v in representation.items()} k, v in representation.items()}
clean_representation(representation)
if not isinstance(resource, (OneM2MResource, Notification, if not isinstance(resource, (OneM2MResource, Notification,
SecurityInfo, OneM2MContentResource)): SecurityInfo, OneM2MContentResource)):
return representation return representation

View File

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

View File

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

View File

@ -31,7 +31,7 @@ from openmtc_onem2m.model import (ExpiringResource, Notification,
DiscResTypeE, Container, AccessControlPolicy, DiscResTypeE, Container, AccessControlPolicy,
AccessControlPolicyIDHolder, AccessControlRuleC, AccessControlPolicyIDHolder, AccessControlRuleC,
DynAuthDasRequestC, SecurityInfo, SecurityInfoTypeE, DynAuthDasRequestC, SecurityInfo, SecurityInfoTypeE,
AE, ContentInstance) AE, ResultContentE, ContentInstance)
from openmtc_onem2m.transport import (OneM2MResponse, OneM2MRequest, from openmtc_onem2m.transport import (OneM2MResponse, OneM2MRequest,
OneM2MOperation, OneM2MErrorResponse) OneM2MOperation, OneM2MErrorResponse)
from openmtc_onem2m.util import split_onem2m_address 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 self.fields = self.request.content and self.request.content.values
def _handle_retrieve(self): 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: try:
fu = self.request.filter_criteria.filterUsage fu = self.request.filter_criteria.filterUsage
except AttributeError: except AttributeError:
@ -887,10 +893,15 @@ class OneM2MDefaultController(LoggerMixin):
if self.fields and isinstance(self.fields, list): if self.fields and isinstance(self.fields, list):
res.set_values({k: v if k in self.fields else None for res.set_values({k: v if k in self.fields else None for
k, v in res.get_values().items()}) 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): 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): def _retrieve_children(self):
return self._retrieve_children_for_resource(self.resource) return self._retrieve_children_for_resource(self.resource)

View File

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