def get_resource(p): try: r = db_session.get(p) except DBNotFound: try: p_segment, ch_segments = p.split('/', 1) except ValueError: raise CSENotFound() try: p = db_session.get(p_segment) r = db_session.get('/'.join([p.path, ch_segments])) except DBNotFound: raise CSENotFound() return r
def _check_existence_and_get_resource(self, db_session, path): if path.startswith('.'): path = self._cse_base + path[1:] def get_resource(p): try: r = db_session.get(p) except DBNotFound: try: p_segment, ch_segments = p.split('/', 1) except ValueError: raise CSENotFound() try: p = db_session.get(p_segment) r = db_session.get('/'.join([p.path, ch_segments])) except DBNotFound: raise CSENotFound() return r # virtual resource handling, see TS-0004 6.8 # oldest, latest -> Container # TODO(rst): fanOutPoint -> group # TODO(rst): pollingChannelURI -> pollingChannel if path.endswith(tuple(container_virtual_mapping.keys())): parent_path, virtual = path.rsplit('/', 1) parent = get_resource(parent_path) if isinstance(parent, model.Container): resource = getattr(parent, container_virtual_mapping[virtual]) if resource is None: raise CSENotFound() return resource return get_resource(path)
def _check_existence(db_session, path): try: # virtual resource handling, see TS-0004 6.8 # oldest, latest -> Container # TODO(rst): fanOutPoint -> group # TODO(rst): pollingChannelURI -> pollingChannel if path.endswith(('latest', 'oldest')): parent, virtual = path.rsplit('/', 1) resource = db_session.get(parent) if isinstance(resource, model.Container): resource = getattr(resource, virtual) if resource is None: raise CSENotFound() else: resource = db_session.get(path) else: resource = db_session.get(path) except DBNotFound: raise CSENotFound() return resource
def push_content(self, container, content, fmt=None, text=None): """ Creates a ContentInstance resource in the given container, wrapping the content. Defaults to serialising the content as JSON and base64 encodes it. NOTE: Will attempt to create the container, if not found. :param container: Container object or container path string :param content: the content data :param fmt: :param text: """ path = getattr(container, "path", container) if isinstance(content, (str, unicode)): fmt = 'text/plain' if fmt is None else fmt text = True if text is None else text elif isinstance(content, (dict, list)): fmt = 'application/json' if fmt is None else fmt text = False if text is None else text else: raise CSENotImplemented("Only dict, list and str are supported!") if fmt == 'application/json' or re.search(self.fmt_json_regex, fmt): if text: # TODO(rst): check if it should be with masked quotation marks # con = json_dumps(content) # cnf = fmt + ':' + str(EncodingTypeE.plain.value) raise CSENotImplemented("Only json as b64 is supported!") else: con = b64encode(json_dumps(content)) cnf = fmt + ':' + str(EncodingTypeE.base64String.value) elif fmt == 'text/plain': if text: con = content cnf = fmt + ':' + str(EncodingTypeE.plain.value) else: con = b64encode(content) cnf = fmt + ':' + str(EncodingTypeE.base64String.value) else: # TODO(rst): add handling of other formats or raise not implemented raise CSENotImplemented("Only json and text are supported!") cin = ContentInstance(content=con, contentInfo=cnf) try: return self.mapper.create(path, cin) except CSENotFound: raise CSENotFound()
def _run_controller(self, ctrl, request, resource): with Promise() as p: try: p.fulfill(ctrl(request, resource)) except Exception as error: self.logger.debug("Handling %s: %s", type(error).__name__, error) if isinstance(error, OneM2MErrorResponse): p.reject(error) elif isinstance(error, DBConflict): p.reject(CSEConflict()) elif isinstance(error, DBNotFound): p.reject(CSENotFound()) else: try: status_code = error.response_status_code except AttributeError: status_code = STATUS_INTERNAL_SERVER_ERROR result = OneM2MErrorResponse(status_code, request=request) p.reject(result) return p
def _handle_remote_cse(self, remote_cse): """ Sends a create request for the RemoteCSE resource. Retrieves resource data afterwards. @return: RemoteCSE instance representing the created resource. """ try: remote_cse_id = "/" + remote_cse["cse_id"] except KeyError: raise ConfigurationError('Missing parameter (cse_id) in %s' % remote_cse) # cse type remote_cse_type = remote_cse.get("cse_type") try: remote_cse_type = getattr( CSETypeIDE, str(remote_cse_type).replace("-", "_").upper()) except (AttributeError, TypeError, ValueError): raise ConfigurationError("Invalid value for 'cse_type': %s" % (remote_cse_type, )) remote_cse_type = CSETypeIDE(remote_cse_type) remote_cse_base = remote_cse.get("cse_base", "onem2m") remote_cse_uri = remote_cse_id + '/' + remote_cse_base self.logger.info("registering %s at %s", self.cse_id, remote_cse_id) def _create_own_remote_cse_remotely(): endpoints = self.api.get_onem2m_endpoints() from openmtc.util import datetime_the_future # init RemoteCSE object cse = RemoteCSE(resourceName=self.cse_id[1:], labels=self.labels, cseType=self.cse_type, pointOfAccess=endpoints, CSEBase=self.cse_base, CSE_ID=self.cse_id, requestReachability=bool(len(endpoints)), expirationTime=datetime_the_future( self.get_offset)) if remote_cse.get('own_poa'): cse.pointOfAccess = remote_cse.get('own_poa') request = OneM2MRequest(OneM2MOperation.create, remote_cse_uri, self.originator, ty=RemoteCSE, pc=cse) return self.api.send_onem2m_request(request) def _retrieve_remote_cse_base(): request = OneM2MRequest(OneM2MOperation.retrieve, remote_cse_uri, self.originator, ty=CSEBase) return self.api.send_onem2m_request(request) def _create_remote_cse_locally(cse_base): cse = RemoteCSE(resourceName=remote_cse_id[1:], CSEBase=remote_cse_base, CSE_ID=remote_cse_id, cseType=remote_cse_type, pointOfAccess=cse_base.pointOfAccess) cse.pointOfAccess = remote_cse.get('poa') request = OneM2MRequest(OneM2MOperation.create, self.cse_base, self.originator, ty=RemoteCSE, pc=cse) return self.api.handle_onem2m_request(request) try: instance = _create_own_remote_cse_remotely().get().content def _update_function(updated_instance): self._handle_remote_cse_update_expiration_time( remote_cse, updated_instance) self.refresher.start(instance, send_update=_update_function) except CSETargetNotReachable as e_not_reachable: # TODO(rst): print error message raise e_not_reachable except OneM2MErrorResponse as error_response: if error_response.response_status_code == STATUS_CONFLICT: # TODO(rst): handle conflict here raise CSEConflict() else: retrieved_cse_base = _retrieve_remote_cse_base().get().content if retrieved_cse_base is None: raise CSENotFound() _create_remote_cse_locally(retrieved_cse_base).get()