Пример #1
0
    def process(self):
        """
        Process the request.
     
        @return:  HTTP result structure.
        @rtype:   Result
        
        """
        method = self.request.getRequestMethod()

        if method == HTTP.GET_METHOD:
            # It's the responsibility of the browser class to provide breadcrumbs
            self.breadcrumbs = [("Home", "/"),
                                ("Resource", settings.PREFIX_RESOURCE)]

        if self.request.getRequestPath() == settings.PREFIX_RESOURCE:
            #
            # Request to the base URL of all resources (listing resources)
            #
            if method == HTTP.GET_METHOD:
                #
                # List all the resources
                #
                return Result.ok(listResources())
            else:
                raise RestxMethodNotAllowedException()

        else:
            # Path elements (the known resource prefix is stripped off)
            path = self.request.getRequestPath()[len(settings.PREFIX_RESOURCE
                                                     ):]
            path_elems = path.split("/")[1:]
            resource_name = path_elems[
                0]  # This should be the name of the resource base

            # If the path ends with a '/' then there might be an empty element at the end,
            # which we can remove.
            if not path_elems[-1:][0]:
                path_elems.pop()

            # Before calling delete on a resource, we have to make sure that this DELETE
            # is just for the resource itself, not a DELETE to some of the sub-services.
            # If it's just for the resource then there will be only one path element (the
            # resource name).
            if method == HTTP.DELETE_METHOD and len(path_elems) == 1:
                try:
                    deleteResourceFromStorage(self.request.getRequestPath())
                    return Result.ok("Resource deleted")
                except RestxException, e:
                    return Result(e.code, str(e))

            # Get the public representation of the resource
            rinfo = _getResourceDetails(resource_name)
            complete_resource_def = rinfo['complete_resource_def']
            resource_home_uri = rinfo['resource_home_uri']
            public_resource_def = rinfo['public_resource_def']
            code_uri = rinfo['code_uri']
            component = rinfo['component']
            services = public_resource_def['services']
            public_resource_def['uri'] = Url(public_resource_def['uri'])

            if method == HTTP.GET_METHOD:
                self.breadcrumbs.append((resource_name, resource_home_uri))

            # Was there more to access?
            if len(path_elems) > 1:
                #
                # Some sub-service of the component was requested. This means
                # we actually need to pass the parameters to the component
                # and call this service function.
                #

                # This service has some possible runtime parameters defined.
                runtime_param_dict = get_request_query_dict(self.request)

                service_name = path_elems[1]
                positional_params = path_elems[2:]
                input = self.request.getRequestBody()
                try:
                    http_method = __HTTP_METHOD_LOOKUP.get(
                        self.request.getRequestMethod().upper(),
                        HttpMethod.UNKNOWN)
                    result = _accessComponentService(
                        component, services, complete_resource_def,
                        resource_name, service_name, positional_params,
                        runtime_param_dict, input, self.request, http_method)
                except RestxException, e:
                    result = Result(e.code, e.msg)
                except Exception, e:
                    # The service code threw an exception. We need to log that and return a
                    # normal error back to the user.
                    print traceback.format_exc()
                    log("Exception in component for service '%s': %s" %
                        (service_name, str(e)),
                        facility=LOGF_COMPONENTS)
                    result = Result.internalServerError(
                        "Internal server error. Details have been logged...")
Пример #2
0
    def process(self):
        """
        Process the request.
     
        @return:  HTTP result structure.
        @rtype:   Result
        
        """
        method = self.request.getRequestMethod()

        if method == HTTP.GET_METHOD:
            # It's the responsibility of the browser class to provide breadcrumbs
            self.breadcrumbs = [ ("Home", "/"), ("Resource", settings.PREFIX_RESOURCE) ]

        if self.request.getRequestPath() == settings.PREFIX_RESOURCE:
            #
            # Request to the base URL of all resources (listing resources)
            #
            if method == HTTP.GET_METHOD:
                #
                # List all the resources
                #
                return Result.ok(listResources())
            else:
                raise RestxMethodNotAllowedException()
            
        else:
            # Path elements (the known resource prefix is stripped off)
            path          = self.request.getRequestPath()[len(settings.PREFIX_RESOURCE):]
            path_elems    = path.split("/")[1:]
            resource_name = path_elems[0]   # This should be the name of the resource base

            # If the path ends with a '/' then there might be an empty element at the end,
            # which we can remove.
            if not path_elems[-1:][0]:
                path_elems.pop()
            
            # Before calling delete on a resource, we have to make sure that this DELETE
            # is just for the resource itself, not a DELETE to some of the sub-services.
            # If it's just for the resource then there will be only one path element (the
            # resource name).
            if method == HTTP.DELETE_METHOD  and  len(path_elems) == 1:
                try:
                    deleteResourceFromStorage(self.request.getRequestPath())
                    return Result.ok("Resource deleted")
                except RestxException, e:
                    return Result(e.code, str(e))

            # Get the public representation of the resource
            rinfo = _getResourceDetails(resource_name)
            complete_resource_def = rinfo['complete_resource_def']
            resource_home_uri     = rinfo['resource_home_uri']
            public_resource_def   = rinfo['public_resource_def']
            code_uri              = rinfo['code_uri']
            component             = rinfo['component']
            services              = public_resource_def['services']
            public_resource_def['uri'] = Url(public_resource_def['uri'])

            if method == HTTP.GET_METHOD:
                self.breadcrumbs.append((resource_name, resource_home_uri))

            # Was there more to access?
            if len(path_elems) > 1:
                #
                # Some sub-service of the component was requested. This means
                # we actually need to pass the parameters to the component
                # and call this service function.
                #
                
                # This service has some possible runtime parameters defined.
                runtime_param_dict = get_request_query_dict(self.request)

                service_name      = path_elems[1]
                positional_params = path_elems[2:]
                input             = self.request.getRequestBody()
                try:
                    http_method = __HTTP_METHOD_LOOKUP.get(self.request.getRequestMethod().upper(), HttpMethod.UNKNOWN)
                    result      = _accessComponentService(component, services, complete_resource_def,
                                                          resource_name, service_name, positional_params,
                                                          runtime_param_dict, input, self.request,
                                                          http_method)
                except RestxException, e:
                    result = Result(e.code, e.msg)
                except Exception, e:
                    # The service code threw an exception. We need to log that and return a
                    # normal error back to the user.
                    print traceback.format_exc()
                    log("Exception in component for service '%s': %s" % (service_name, str(e)), facility=LOGF_COMPONENTS)
                    result = Result.internalServerError("Internal server error. Details have been logged...")
Пример #3
0
    def process(self):
        """
        Process the request.
     
        @return:  HTTP result structure.
        @rtype:   Result
        
        """
        method = self.request.getRequestMethod()

        if method == HTTP.GET_METHOD:
            # It's the responsibility of the browser class to provide breadcrumbs
            self.breadcrumbs = [ ("Home", "/"), ("Resource", settings.PREFIX_RESOURCE) ]

        if self.request.getRequestPath() == settings.PREFIX_RESOURCE:
            #
            # Request to the base URL of all resources (listing resources)
            #
            if method == HTTP.GET_METHOD:
                #
                # List all the resources
                #
                return Result.ok(listResources())
            else:
                raise RestxMethodNotAllowedException()
            
        else:
            # Path elements (the known resource prefix is stripped off)
            path          = self.request.getRequestPath()[len(settings.PREFIX_RESOURCE):]
            path_elems    = path.split("/")[1:]
            resource_name = path_elems[0]   # This should be the name of the resource base

            # If the path ends with a '/' then there might be an empty element at the end,
            # which we can remove.
            if not path_elems[-1:][0]:
                path_elems.pop()
            
            # Before calling delete on a resource, we have to make sure that this DELETE
            # is just for the resource itself, not a DELETE to some of the sub-services.
            # If it's just for the resource then there will be only one path element (the
            # resource name).
            if method == HTTP.DELETE_METHOD  and  len(path_elems) == 1:
                try:
                    deleteResourceFromStorage(self.request.getRequestPath())
                    return Result.ok("Resource deleted")
                except RestxException, e:
                    return Result(e.code, e.msg)

            # Get the public representation of the resource
            rinfo = _getResourceDetails(resource_name)
            if not rinfo:
                return Result.notFound("Unknown component")
            complete_resource_def = rinfo['complete_resource_def']
            resource_home_uri     = rinfo['resource_home_uri']
            public_resource_def   = rinfo['public_resource_def']
            code_uri              = rinfo['code_uri']
            component             = rinfo['component']
            services              = public_resource_def['services']
            public_resource_def['uri'] = Url(public_resource_def['uri'])

            if method == HTTP.GET_METHOD:
                self.breadcrumbs.append((resource_name, resource_home_uri))

            # Was there more to access?
            if len(path_elems) > 1:
                #
                # Some sub-service of the component was requested. This means
                # we actually need to pass the parameters to the component
                # and call this service function.
                #
                
                service_name = path_elems[1]

                # If the service name contains a "." then we might deal with
                # a content type ID in the URI (used by clients who don't know how
                # to deal with the 'Accept' or 'Content-type' headers properly).
                # In that case, we remove that ID from the service name.
                content_type_from_id = None
                if "." in service_name:
                    service_name, content_id = service_name.split(".")
                    content_type_from_id = RENDERER_ID_SHORTCUTS.get(content_id)
                    self.request.setContentType(content_type_from_id)

                if not content_type_from_id:
                    # Get the supported output content types for this service method
                    requested_content_types = self.request.preferredContentTypes()
                else:
                    # We have a content type specified in the URI
                    requested_content_types = [ content_type_from_id ]

                try:
                    service_def = complete_resource_def['public']['services'][service_name]
                except KeyError, e:
                    raise RestxResourceNotFoundException("Cannot find '%s'." % service_name)

                # This service has some possible runtime parameters defined.
                # We pass this service definition's parameter list in, since that
                # means we are filtering out all those parameters that we are
                # not expecting.
                service_params = service_def.get('params')
                if service_params:
                    # Only_params is the list of defined service parameters. Passing this to
                    # get_request_query_dict() means that all other runtime parameters are
                    # filtered out.
                    only_params = service_params.keys()
                    runtime_param_dict = get_request_query_dict(self.request, only_params)
                else:
                    only_params = None
                    runtime_param_dict = dict()   # No service parameters defined? All runtime parameters are removed (ignored).

                possible_output_types   = service_def.get('output_types')
                if not possible_output_types:
                    # If the service method didn't define any type(s) then we just
                    # indicate the ability to create any of the default types
                    possible_output_types = DEFAULT_OUTPUT_TYPES

                if type(possible_output_types) in [ str, unicode, java.lang.String ]:
                    # Always store the output types in a list, even if the service method just
                    # defined a single one
                    possible_output_types = [ possible_output_types ]

                # See that we can match the accepted to possible types
                matched_type      = content_type_match(possible_output_types, requested_content_types)
                positional_params = path_elems[2:]
                input             = self.request.getRequestBody()
                try:
                    http_method = __HTTP_METHOD_LOOKUP.get(self.request.getRequestMethod().upper(), HttpMethod.UNKNOWN)
                    result      = _accessComponentService(component, complete_resource_def,
                                                          resource_name, service_name, positional_params,
                                                          runtime_param_dict, input, self.request,
                                                          http_method)
                    if result == None  or  type(result) is not Result:
                        result = Result.noContent()
                    else:
                        result.setNegotiatedContentType(matched_type)
                except RestxException, e:
                    result = Result(e.code, e.msg)