handles release version indicator and updates request/response attributes

This commit is contained in:
Ronald Steinke 2018-10-05 15:33:20 +02:00
parent 8cf2ba09ae
commit 6cb4ee3d41
6 changed files with 180 additions and 22 deletions

View File

@ -48,7 +48,7 @@ _method_map_to_http = {
_clients = LRUCache(threadsafe=False)
_query_params = frozenset(['rt', 'rp', 'rcn', 'da', 'drt'])
_query_params = frozenset(['rt', 'rp', 'rcn', 'da', 'drt', 'rids', 'tids', 'ltids', 'tqi'])
_header_to_field_map = {
'X-M2M-ORIGIN': 'originator',
@ -59,6 +59,8 @@ _header_to_field_map = {
'X-M2M-RET': 'rqet',
'X-M2M-OET': 'oet',
'X-M2M-EC': 'ec',
'X-M2M-RVI': 'rvi',
'X-M2M-VSI': 'vsi',
}
@ -162,7 +164,8 @@ class OneM2MHTTPClient(OneM2MClient):
content_type += '; ty=' + str(ResourceTypeE[onem2m_request.resource_type.typename])
headers = {
header: getattr(onem2m_request, field) for header, field in _header_to_field_map.iteritems()
header: getattr(onem2m_request, field)
for header, field in _header_to_field_map.iteritems()
if getattr(onem2m_request, field) is not None
}
headers['content-type'] = content_type

View File

@ -83,11 +83,12 @@ class OneM2MMQTTClient(OneM2MClient):
__request_fields = frozenset([
'op',
'to',
'fr',
'rqi',
'ty',
'pc',
'rol',
'rids',
'ot',
'rqet',
'rset',
@ -98,17 +99,28 @@ class OneM2MMQTTClient(OneM2MClient):
'ec',
'da',
'gid',
'drt',
'to',
'fc',
'drt',
'tids',
'ltids',
'tqi',
'rvi',
'vsi',
])
__response_fields = frozenset([
'rsc',
'rqi',
'pc',
'fr',
'to',
'fr',
'ot',
'rset',
'ec',
'cts',
'cto',
'rvi',
'vsi',
])
@staticmethod

View File

@ -49,7 +49,8 @@ class OneM2MMapper(BasicMapper):
path,
self.originator,
ty=type(instance),
pc=instance
pc=instance,
rvi='2a'
)).get()
try:
@ -83,7 +84,8 @@ class OneM2MMapper(BasicMapper):
OneM2MOperation.update,
instance.path,
self.originator,
pc=instance
pc=instance,
rvi='2a'
)).get()
try:
@ -105,6 +107,7 @@ class OneM2MMapper(BasicMapper):
path,
self.originator,
filter_criteria=fc,
rvi='2a',
rcn=5,
**request_options
)).get()
@ -113,7 +116,8 @@ class OneM2MMapper(BasicMapper):
self._send_request(OneM2MRequest(
OneM2MOperation.delete,
getattr(instance, "path", instance),
self.originator
self.originator,
rvi='2a'
))
# TODO(rst): check if this can be removed in parent class

View File

@ -201,10 +201,11 @@ class OneM2MRequest(object):
"""Class representing a OneM2M request"""
def __init__(self, op, to, fr=None, rqi=None, ty=None, pc=None, rol=None,
def __init__(self, op, to, fr=None, rqi=None, ty=None, pc=None, rids=None,
ot=None, rqet=None, rset=None, oet=None, rt=None, rp=None,
rcn=None, ec=None, da=None, gid=None, filter_criteria=None,
fc=None, drt=None):
fc=None, drt=None, tids=None, ltids=None, tqi=None, rvi=None,
vsi=None):
# Operation
self.operation = op
# Target uri
@ -216,7 +217,7 @@ class OneM2MRequest(object):
self.resource_type = ty
# Resource content to be transferred.
self.content = pc
self.role = rol
self.role_ids = rids
self.originating_timestamp = ot
self.request_expiration_timestamp = rqet
self.result_expiration_timestamp = rset
@ -230,6 +231,11 @@ class OneM2MRequest(object):
self.filter_criteria = filter_criteria or fc
# Optional Discovery result type
self.discovery_result_type = drt
self.token_ids = tids
self.local_token_ids = ltids
self.token_request_identifier = tqi
self.release_version_indicator = rvi
self.vendor_information = vsi
@property
def op(self):
@ -272,12 +278,12 @@ class OneM2MRequest(object):
self.content = pc
@property
def rol(self):
return self.role
def rids(self):
return self.role_ids
@rol.setter
def rol(self, rol):
self.role = rol
@rids.setter
def rids(self, rids):
self.role_ids = rids
@property
def ot(self):
@ -375,6 +381,46 @@ class OneM2MRequest(object):
def drt(self, drt):
self.discovery_result_type = drt
@property
def tids(self):
return self.token_ids
@tids.setter
def tids(self, tids):
self.token_ids = tids
@property
def ltids(self):
return self.local_token_ids
@ltids.setter
def ltids(self, rvi):
self.local_token_ids = ltids
@property
def tqi(self):
return self.token_request_identifier
@tqi.setter
def tqi(self, tqi):
self.token_request_identifier = tqi
@property
def rvi(self):
return self.release_version_indicator
@rvi.setter
def rvi(self, rvi):
self.release_version_indicator = rvi
@property
def vsi(self):
return self.vendor_information
@vsi.setter
def vsi(self, vsi):
self.vendor_information = vsi
def __str__(self):
return '%s: %s' % (self.__class__.__name__, ' | '.join([
'%s: %s' % (str(k), str(v)) for k, v in self.__dict__.iteritems()
@ -385,7 +431,8 @@ 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, fields=None):
fr=None, rsc=None, ot=None, rset=None, ec=None, cts=None,
cto=None, rvi=None, vsi=None, fields=None):
# Operation result
if isinstance(status_code, STATUS):
self.response_status_code = status_code
@ -397,14 +444,26 @@ class OneM2MResponse(object):
self.to = request.to
# Originator ID
self.originator = request.fr
self.originating_timestamp = request.ot
self.result_expiration_timestamp = request.rset
self.event_category = request.ec
self.release_version_indicator = request.rvi
self.vendor_information = request.vsi
else:
self.request_identifier = rqi
# Target uri
self.to = to
# Originator ID
self.originator = fr
self.originating_timestamp = ot
self.release_version_indicator = rvi
self.vendor_information = vsi
self.result_expiration_timestamp = rset
self.event_category = ec
# Resource content to be transferred.
self.content = pc
self.content_status = cts
self.content_offset = cto
self.fields = fields
@property
@ -439,6 +498,62 @@ class OneM2MResponse(object):
def fr(self, fr):
self.originator = fr
@property
def ot(self):
return self.originating_timestamp
@ot.setter
def ot(self, ot):
self.originating_timestamp = ot
@property
def rset(self):
return self.result_expiration_timestamp
@rset.setter
def rset(self, rset):
self.result_expiration_timestamp = rset
@property
def ec(self):
return self.event_category
@ec.setter
def ec(self, ec):
self.event_category = ec
@property
def cts(self):
return self.content_status
@cts.setter
def cts(self, cts):
self.content_status = cts
@property
def cto(self):
return self.content_offset
@cto.setter
def cto(self, cto):
self.content_offset = cto
@property
def rvi(self):
return self.release_version_indicator
@rvi.setter
def rvi(self, rvi):
self.release_version_indicator = rvi
@property
def vsi(self):
return self.vendor_information
@vsi.setter
def vsi(self, vsi):
self.vendor_information = vsi
def __str__(self):
return '%s: %s' % (self.__class__.__name__, ' | '.join([
'%s: %s' % (str(k), str(v)) for k, v in self.__dict__.iteritems()

View File

@ -106,6 +106,10 @@ class OneM2MDefaultController(LoggerMixin):
self._dynamic_authorization_supported = dynamic_authorization.get('enabled', False)
self._dynamic_authorization_poa = dynamic_authorization.get('poa', [])
# release version indicator
if not self.request.rvi:
self.request.rvi = '2a'
return self._handle_request()
def _handle_request(self):

View File

@ -249,11 +249,21 @@ class OpenMTCWSGIApplication(LoggerMixin):
# request and response primitives, and vice versa, if applicable.
ec = get_header("x-m2m-ec")
# The X-M2M-CTS header shall be mapped to the Content Status parameter
# of response primitives and vice versa, if applicable.
rvi = get_header("x-m2m-rvi")
# The X-M2M-CTS header shall be mapped to the Content Status parameter
# of response primitives and vice versa, if applicable.
vsi = get_header("x-m2m-vsi")
onem2m_request = OneM2MRequest(op=op, to=to, fr=fr, rqi=rqi, ty=ty,
pc=pc, ot=ot, rqet=rqet, rset=rset,
oet=oet, rt=rt, ec=ec, gid=gid)
oet=oet, rt=rt, ec=ec, gid=gid, rvi=rvi,
vsi=vsi)
not_filter_params = ('rt', 'rp', 'rcn', 'da', 'drt')
not_filter_params = ('rt', 'rp', 'rcn', 'da', 'drt', 'rids', 'tids',
'ltids', 'tqi')
multiple_params = ('lbl', 'ty', 'cty', 'atr')
if http_request.query_string:
@ -315,9 +325,18 @@ class OpenMTCWSGIApplication(LoggerMixin):
headers = {
"x-m2m-ri": str(response.rqi),
"x-m2m-rsc": str(response.rsc)
"x-m2m-rsc": str(response.rsc),
'x-m2m-rvi': str(response.rvi)
}
if response.fr:
headers['x-m2m-origin'] = str(response.fr)
response_fields = ['ot', 'rset', 'ec', 'cts', 'cto', 'vsi']
for f in response_fields:
if getattr(response, f):
headers['x-m2m-%s' % f] = str(getattr(response, f))
try:
headers['Content-Location'] = (resource_id_pre + response.content.resourceID)
except (AttributeError, TypeError):
@ -370,7 +389,8 @@ class OpenMTCWSGIApplication(LoggerMixin):
headers = {
"x-m2m-ri": str(response.rqi),
"x-m2m-rsc": str(response.rsc)
"x-m2m-rsc": str(response.rsc),
'x-m2m-rvi': str(response.rvi)
}
except AttributeError:
status_code = STATUS_INTERNAL_SERVER_ERROR.http_status_code