def send_update(m2mpoc, fields): uri = self.nscl_uri + "/" + "scls/" + self.gscl_id\ + "/" + "m2mPocs" + "/" + m2mpoc.id rq = UpdateRequestIndication(uri, m2mpoc) rq.requestingEntity = self.config.get("requesting_entity") # TODO: add restore function in case of 404 or something return self.api.send_request_indication(rq)
def _create_nscl_copy(response): resource = response.resource # 8) path = instance.path = "/m2m/scls" + "/" + self.nscl_id # 9) fields = [ "searchStrings", "aPocHandling", "accessRightID", # "creationTime", "lastModifiedTime", ] for f in fields: if f == "searchStrings": # HACK: setattr or even a simple assignment wont work instance.values[f]["searchString"].extend( resource.searchStrings) else: setattr(instance, f, getattr(resource, f)) setattr(instance, "mgmtProtocolType", self.mgmt_protocol) fields.append("mgmtProtocolType") rq = UpdateRequestIndication(path, instance, fields=fields) rq.internal = True return self.api.handle_request_indication(rq)
def send_update(instance, fields): # TODO fields param?? def _update_instance(data=None): def _fill_instance(result): # instance = Scl( self._gscl.path, **data[1]) self._gscl.expirationTime = result.resource.expirationTime # side effect # update expirationTime of NSCL copy path = "/m2m/scls/" + self.nscl_id + "/expirationTime" fields = ["expirationTime"] rq = UpdateRequestIndication(path, self._gscl, fields=fields) p = self.api.handle_request_indication(rq) # p.fulfill(instance) return p def _retrieve_instance(): rq = RetrieveRequestIndication(uri) rq.requestingEntity = self.config.get("requesting_entity") promise = self.api.send_request_indication(rq) return promise return _retrieve_instance().then(_fill_instance) def _restore(err): """ Restarts registration, if 404. """ def reregister(a=None, b=None): return self._register().then(failure=self._error) # ISSUE; dont know what request it was? <- m2mPocs? self.logger.warn("GSCL ExpirationTime update failed: %s", err) NOT_FOUND = (404, "404", "STATUS_NOT_FOUND", "NOT_FOUND") if err.statusCode in NOT_FOUND: # FIXME: better error handling # cleanup rq = DeleteRequestIndication("/m2m/scls/" + self.nscl_id) p = self.api.handle_request_indication(rq)\ .then(reregister) self.refresher.stop() self.poc_refresher.stop() return p else: # TODO other statuses possible? return Promise().fulfill(None) uri = instance.path if not uri.startswith((self.nscl_uri, "coap://", "http://")): # TODO: kca: use urljoin uri = self.nscl_uri + uri rq = UpdateRequestIndication(uri, instance) rq.requestingEntity = self.config.get("requesting_entity") # rq = UpdateRequestIndication(uri, instance, fields=fields) promise = self.api.send_request_indication(rq) \ .then(_update_instance, _restore) return promise
def _handle_updated(self, instance, req_ind): """ #example: instance:M2mPoc(path='/m2m/scls/gscl/m2mPocs/m2mPoc1qvr4rUOGJAKEPFK', name='m2mPoc1qvr4rUOGJAKEPFK') req_ind:RequestIndication: { path: /m2m/scls/gscl/m2mPocs/m2mPoc1qvr4rUOGJAKEPFK, method: update, typename: m2mPoc, resource: { 'expirationTime': '2014-07-11T17:05:09.004744+00:00', 'contactInfo': 'https://[2001:638:806:65:f4bf:ccb0:cad5:a203]:6000', 'onlineStatus': 'ONLINE' } } """ self.logger.debug("_handle_updated: instance:%s req_ind:%s", instance, req_ind) resource = req_ind.resource poc_path = instance.path scl_path = poc_path.rpartition('/')[0].rpartition('/')[0] online_status = resource['onlineStatus'] self.logger.debug("_handle_updated: pocs_info:%s", self.pocs_info) self.pocs_info[scl_path][poc_path] = {'onlineStatus': online_status} has_offline = False has_online = False for key, value in self.pocs_info.get(scl_path).items(): if key != 'onlineStatus': if value['onlineStatus'] == 'ONLINE': has_online = True elif value['onlineStatus'] == 'OFFLINE': has_offline = True if has_online: self.pocs_info[scl_path]['onlineStatus'] = "ONLINE" elif has_offline: self.pocs_info[scl_path]['onlineStatus'] = "OFFLINE" else: self.pocs_info[scl_path]['onlineStatus'] = "NOT_REACHABLE" onlinestatus_path = scl_path + "/onlineStatus" online_status = { "onlineStatus": self.pocs_info[scl_path]['onlineStatus'] } rq = UpdateRequestIndication(onlinestatus_path, resource=online_status, typename="scl") rq.internal = True promises = [ self._update_scl(scl_path, self.pocs_info[scl_path]), self.api.handle_request_indication(rq) ] return async_all(promises, fulfill_with_none=True)
def send_update_annc(scl_uri, local_ar=False): endpoint = self.api.get_mid_uri(urlparse(scl_uri).scheme) annc = annc_model() # link hast to be set annc.link = urljoin(endpoint, resource.path) # * searchStrings from the original resource; annc.searchStrings = resource.searchStrings # * accessRightID from the original resource; if local_ar: annc.accessRightID = urljoin(endpoint, urlparse( resource.accessRightID).path) else: annc.accessRightID = resource.accessRightID # * expirationTime handling is to the discretion of the SCL # implementation. It is the responsibility of the local SCL to # keep the announced resource in sync with the lifetime of the # original resource, as long as the announcement is active. One # strategy to minimize signalling would be to request the same # expiration from the original resource. If this is accepted by # the remote SCL, then no explicit de-announce is needed in case # of expiration of the original resource; annc.expirationTime = resource.expirationTime update_req_ind = UpdateRequestIndication( uris[scl_uri], annc, requestingEntity=endpoint) # todo investigate response for not accepted expirationTime return self.api.send_request_indication(update_req_ind)
def add_parameters(response): path = response.resource.path resource = ('{"mgmtObjs" : ' + json.dumps(resources_dict) + '}') request = UpdateRequestIndication(path, resource, content_type="application/json") response = self.api.handle_request_indication(request)
def handle_mgmtobjs(response): mgmtobj_exists = False for mgmtobj in response.resource.mgmtObjCollection: if mgmtobj.name == object_name + "_" + str(object_inst_id): mgmtobj_exists = True path = mgmtobj.path request = RetrieveRequestIndication(path) response = self.api.handle_request_indication(request) try: if res_name_res_inst_id in response.value.resource.flex_values: if response.value.resource.flex_values[ res_name_res_inst_id] == str(res_value): continue elif res_name in response.value.resource.flex_values: if response.value.resource.flex_values[ res_name] == str(res_value): continue except: pass resource = ('{"mgmtObjs" : ' + json.dumps(resources_dict) + '}') request = UpdateRequestIndication( path, resource, content_type="application/json") response = self.api.handle_request_indication(request) break if not mgmtobj_exists: mgmtobj_ = MgmtObj(id=str(object_name) + "_" + str(object_inst_id), moID=moID_value) path = response.resource.path request = CreateRequestIndication(path, mgmtobj_) response = self.api.handle_request_indication(request) response.then(add_parameters)
def update(self, resource, fields=()): """Creates and serializes a UpdateRequestIndication to a CoAP PUT message and sends it using a CoapClient :param path: Resource path :return: Corresponding UpdateResponseConfirmation """ return self.send_request_indication( UpdateRequestIndication(resource.path, resource, fields=fields))
def error_handling(result): path = "/m2m/scls/mgmtObjs/" + object_name_obj_inst_id self.logger.warning("Path not found. %s", result) self.logger.info("Looking for other path at %s", path) resource = ('{"mgmtObjs" : ' + dumps(resource_dict) + '}') request = UpdateRequestIndication(path, resource, content_type="application/json") response = self.api.handle_request_indication(request) response.then(success, failure)
def _handle_deleted(self, instance, req_ind): poc_path = instance.path scl_path = poc_path.rpartition('/')[0].rpartition('/')[0] self.logger.debug("_handle_deleted: instance: %s %s", poc_path, scl_path) promises = [] del (self.pocs_info[scl_path][poc_path]) #delete m2mpoc from list if len(self.pocs_info[scl_path]) <= 1: #check if the scl has more pocs del (self.pocs_info[scl_path]) #delete scl from the list onlinestatus_path = scl_path + "/onlineStatus" online_status = {"onlineStatus": "OFFLINE"} rq = UpdateRequestIndication(onlinestatus_path, resource=online_status, typename="scl") rq.internal = True serverCapability_path = scl_path + "/serverCapability" serverCapability = {"serverCapability": "FALSE"} rq2 = UpdateRequestIndication(serverCapability_path, resource=serverCapability, typename="scl") rq2.internal = True promises = [ self.api.handle_request_indication(rq), self.api.handle_request_indication(rq2) ] promises.append(self._update_scl(scl_path, self.pocs_info[scl_path])) return async_all(promises, fulfill_with_none=True)
def _fill_instance(result): # instance = Scl( self._gscl.path, **data[1]) self._gscl.expirationTime = result.resource.expirationTime # side effect # update expirationTime of NSCL copy path = "/m2m/scls/" + self.nscl_id + "/expirationTime" fields = ["expirationTime"] rq = UpdateRequestIndication(path, self._gscl, fields=fields) p = self.api.handle_request_indication(rq) # p.fulfill(instance) return p
def update_resources(self, endpoint_name, object_id, object_inst_id, payload, content_type=None): """ Push the resouces change/update on the gateway resource tree """ self.logger.info("Updating the Gateway Resource Tree") resource_dict = {} resources = loads(payload) object_id_object_inst_id = str(object_id) + "_" + str(object_inst_id) object_name = lwm2m_dict_objects[str(object_id)]["object_name"] object_name_obj_inst_id = object_name + "_" + str(object_inst_id) for res_id, res in resources.iteritems(): res_name = lwm2m_dict_objects[str(object_id)]["resource_list"][str( res_id)]["resName"] if lwm2m_dict_objects[str(object_id)]["resource_list"][str( res_id)]["multiInst"]: res_name_res_inst_id = res_name + "_" + res["res_inst_id"] else: res_name_res_inst_id = res_name res_value = res["res_value"] resource_dict.update({res_name_res_inst_id: res_value}) def success(result): self.logger.info("Resource Tree is updated") def failure(result): self.logger.error("Error occurred: %s", result) def error_handling(result): path = "/m2m/scls/mgmtObjs/" + object_name_obj_inst_id self.logger.warning("Path not found. %s", result) self.logger.info("Looking for other path at %s", path) resource = ('{"mgmtObjs" : ' + dumps(resource_dict) + '}') request = UpdateRequestIndication(path, resource, content_type="application/json") response = self.api.handle_request_indication(request) response.then(success, failure) path = "/m2m/scls/" + endpoint_name + "/mgmtObjs/" + object_name_obj_inst_id resource = ('{"mgmtObjs" : ' + dumps(resource_dict) + '}') request = UpdateRequestIndication(path, resource, content_type="application/json") response = self.api.handle_request_indication(request) response.then(success, error_handling)
def update(self, resource, fields=()): return self._send_update(UpdateRequestIndication(resource.path, resource, fields=fields))
def update_announce_to(): update_req_ind = UpdateRequestIndication(resource.path + '/announceTo', resource, fields=['announceTo'], do_announce=False) return self.api.handle_request_indication(update_req_ind).get()
def map_request_to_request_indication(request): path = request.path method = request.method if method == RequestMethod.create: req_ind = CreateRequestIndication(path=path, resource=request.payload, content_type=request.content_type) elif method == RequestMethod.retrieve: req_ind = RetrieveRequestIndication(path) if path.endswith(("/contentInstances", "/discovery")): args = request.params filter_criteria = {k: v for k, v in args.items() if k not in ("ifNoneMatch", "searchString", "contentType", "searchPrefix", "maxSize")} filter_criteria = FilterCriteria(**filter_criteria) if_none_match = args.getlist("ifNoneMatch") if if_none_match: filter_criteria.ifNoneMatch = if_none_match search_string = args.getlist("searchString") if search_string: filter_criteria.searchString = search_string content_type = args.getlist("contentType") if content_type: filter_criteria.contentType = content_type req_ind.filterCriteria = filter_criteria if path.endswith("/discovery"): req_ind.searchPrefix = args.get("searchPrefix") req_ind.maxSize = args.get("maxSize") # obtain some filter-criteria from HTTP headers, where appropriate # TODO: kca: not sure if this is actually standard compliant, but it # seems like common sense. Check if its in the standard, if not, # allow to turn it off via config # TODO: use generic format environ = request.metadata for n in ("if_None_Match", "if_Unmodified_Since", "if_Modified_Since"): try: header = environ["HTTP_" + n.upper()] except KeyError: pass else: filter_criteria.setdefault(n.replace("_", ""), header) elif method == RequestMethod.update: req_ind = UpdateRequestIndication(path=path, resource=request.payload, content_type=request.content_type) elif method == RequestMethod.delete: req_ind = DeleteRequestIndication(path) elif method == RequestMethod.notify: req_ind = NotifyRequestIndication(path=path, resource=request.payload, content_type=request.content_type) else: raise ErrorResponse(ResponseCode.method_not_allowed) # TODO: set correlationID, rcat, trpdt req_ind.requestingEntity = get_requesting_entity(request) via = request.via if via: req_ind.via = request.via return req_ind
def _handle_created(self, instance, req_ind): """ #example: instance:M2mPoc(path='/m2m/scls/gscl/m2mPocs/m2mPocnRIjsAAZmqm1U49j', name='m2mPocnRIjsAAZmqm1U49j') req_ind:RequestIndication: { path: /m2m/scls/gscl/m2mPocs, method: create, typename: m2mPoc, resource: { 'creationTime': datetime.datetime(2014, 7, 11, 13, 37, 40, 385438, tzinfo=<openmtc.util.Utc object at 0x7f4d9bf68e50>), 'expirationTime': datetime.datetime(2014, 7, 11, 13, 43, 40, tzinfo=<FixedOffset '+00:00'>), 'onlineStatus': 'ONLINE', 'contactInfo': 'http://[2001:638:806:65:f4bf:ccb0:cad5:a203]:5000', 'lastModifiedTime': datetime.datetime(2014, 7, 11, 13, 37, 40, 385438, tzinfo=<openmtc.util.Utc object at 0x7f4d9bf68e50>) } } """ self.logger.debug("_handle_created: instance:%s req_ind:%s", instance, req_ind) resource = req_ind.resource poc_path = instance.path scl_path = req_ind.path[:-8] online_status = resource['onlineStatus'] if self.pocs_info.get(scl_path) is None: self.pocs_info[scl_path] = {'onlineStatus': online_status} self.pocs_info[scl_path][poc_path] = { 'onlineStatus': online_status } else: self.pocs_info[scl_path][poc_path] = { 'onlineStatus': online_status } has_offline = False has_online = False for key, value in self.pocs_info.get(scl_path).items(): if key != 'onlineStatus': if value['onlineStatus'] == 'ONLINE': has_online = True elif value['onlineStatus'] == 'OFFLINE': has_offline = True if has_online: self.pocs_info[scl_path]['onlineStatus'] = "ONLINE" elif has_offline: self.pocs_info[scl_path]['onlineStatus'] = "OFFLINE" else: self.pocs_info[scl_path]['onlineStatus'] = "NOT_REACHABLE" self.logger.debug("_handle_created: self.pocs_info: %s", self.pocs_info) onlinestatus_path = scl_path + "/onlineStatus" online_status = { "onlineStatus": self.pocs_info[scl_path]['onlineStatus'] } rq = UpdateRequestIndication(onlinestatus_path, resource=online_status, typename="scl") rq.internal = True serverCapability_path = scl_path + "/serverCapability" serverCapability = {"serverCapability": True} rq2 = UpdateRequestIndication(serverCapability_path, resource=serverCapability, typename="scl") rq2.internal = True promises = [self._update_scl(scl_path, self.pocs_info[scl_path]), self.api.handle_request_indication(rq), \ self.api.handle_request_indication(rq2)] return async_all(promises, fulfill_with_none=True)
def update_gscl(data): data.expirationTime = gscl.expirationTime rq = UpdateRequestIndication(uri + '/' + gscl.sclId, data) rq.requestingEntity = self.config.get("requesting_entity") return self.api.send_request_indication(rq).then(lambda x: data)
def _do_update(self, instance, fields): request_indication = UpdateRequestIndication(instance.path, instance, fields=fields) self._send_request(request_indication)