Example #1
0
 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
Example #2
0
    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()
Example #5
0
    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()