def _marshaled_single_dispatch(self, request, dispatch_method=None):
        """
        Dispatches a single method call

        :param request: A validated request dictionary
        :param dispatch_method: Custom dispatch method (for method resolution)
        :return: A JSON-RPC response dictionary, or None if it was a
                 notification request
        """
        method = request.get('method')
        params = request.get('params')

        # Prepare a request-specific configuration
        if 'jsonrpc' not in request and self.json_config.version >= 2:
            # JSON-RPC 1.0 request on a JSON-RPC 2.0
            # => compatibility needed
            config = self.json_config.copy()
            config.version = 1.0
        else:
            # Keep server configuration as is
            config = self.json_config

        try:
            # TODO - Use the multiprocessing if it is a notification
            # Call the method
            if dispatch_method is not None:
                response = dispatch_method(method, params)
            else:
                response = self._dispatch(method, params, config)

        except:
            # Return a fault
            exc_type, exc_value, _ = sys.exc_info()
            fault = Fault(-32603,
                          '{0}:{1}'.format(exc_type, exc_value),
                          config=config)
            return fault.dump()

        if 'id' not in request or request['id'] in (None, ''):
            # It's a notification, no result needed
            # Do not use 'not id' as it might be the integer 0
            return None

        # Prepare a JSON-RPC dictionary
        try:
            return jsonrpclib.dump(response,
                                   rpcid=request['id'],
                                   is_response=True,
                                   config=config)
        except:
            # JSON conversion exception
            exc_type, exc_value, _ = sys.exc_info()
            fault = Fault(-32603,
                          '{0}:{1}'.format(exc_type, exc_value),
                          config=config)
            return fault.dump()
Exemplo n.º 2
0
    def _marshaled_single_dispatch(self, request, dispatch_method=None):
        """
        Dispatches a single method call

        :param request: A validated request dictionary
        :param dispatch_method: Custom dispatch method (for method resolution)
        :return: A JSON-RPC response dictionary, or None if it was a
                 notification request
        """
        # TODO - Use the multiprocessing and skip the response if
        # it is a notification
        method = request.get('method')
        params = request.get('params')

        # Prepare a request-specific configuration
        if 'jsonrpc' not in request and self.json_config.version >= 2:
            # JSON-RPC 1.0 request on a JSON-RPC 2.0
            # => compatibility needed
            config = self.json_config.copy()
            config.version = 1.0
        else:
            # Keep server configuration as is
            config = self.json_config

        try:
            # Call the method
            if dispatch_method is not None:
                response = dispatch_method(method, params)
            else:
                response = self._dispatch(method, params, config)

        except:
            # Return a fault
            exc_type, exc_value, _ = sys.exc_info()
            fault = Fault(-32603, '{0}:{1}'.format(exc_type, exc_value),
                          config=config)
            return fault.dump()

        if 'id' not in request or request['id'] in (None, ''):
            # It's a notification, no result needed
            # Do not use 'not id' as it might be the integer 0
            return None

        # Prepare a JSON-RPC dictionary
        try:
            # TODO: use a copy of the configuration, to JSON-RPC version
            return jsonrpclib.dump(response, rpcid=request['id'],
                                   is_response=True, config=config)

        except:
            # JSON conversion exception
            exc_type, exc_value, _ = sys.exc_info()
            fault = Fault(-32603, '{0}:{1}'.format(exc_type, exc_value),
                          config=config)
            return fault.dump()
Exemplo n.º 3
0
    def _unmarshaled_dispatch(self, request, dispatch_method=None):
        """
        Loads the request dictionary (unmarshaled), calls the method(s)
        accordingly and returns a JSON-RPC dictionary (not marshaled)

        :param request: JSON-RPC request dictionary (or list of)
        :param dispatch_method: Custom dispatch method (for method resolution)
        :return: A JSON-RPC dictionary (or an array of) or None if the request
                 was a notification
        :raise NoMulticallResult: No result in batch
        """
        if not request:
            # Invalid request dictionary
            fault = Fault(-32600, 'Request invalid -- no request data.',
                          config=self.json_config)
            _logger.warning("Invalid request: %s", fault)
            return fault.dump()

        if isinstance(request, utils.ListType):
            # This SHOULD be a batch, by spec
            responses = []
            for req_entry in request:
                # Validate the request
                result = validate_request(req_entry, self.json_config)
                if isinstance(result, Fault):
                    responses.append(result.dump())
                    continue

                # Call the method
                resp_entry = self._marshaled_single_dispatch(req_entry,
                                                             dispatch_method)

                # Store its result
                if isinstance(resp_entry, Fault):
                    # pylint: disable=E1103
                    responses.append(resp_entry.dump())
                elif resp_entry is not None:
                    responses.append(resp_entry)

            if not responses:
                # No non-None result
                _logger.error("No result in Multicall")
                raise NoMulticallResult("No result")

            return responses

        else:
            # Single call
            result = validate_request(request, self.json_config)
            if isinstance(result, Fault):
                return result.dump()

            # Call the method
            response = self._marshaled_single_dispatch(request,
                                                       dispatch_method)
            if isinstance(response, Fault):
                # pylint: disable=E1103
                return response.dump()

            return response
    def _unmarshaled_dispatch(self, request, dispatch_method=None):
        """
        Loads the request dictionary (unmarshaled), calls the method(s)
        accordingly and returns a JSON-RPC dictionary (not marshaled)

        :param request: JSON-RPC request dictionary (or list of)
        :param dispatch_method: Custom dispatch method (for method resolution)
        :return: A JSON-RPC dictionary (or an array of) or None if the request
                 was a notification
        :raise NoMulticallResult: No result in batch
        """
        if not request:
            # Invalid request dictionary
            fault = Fault(-32600, 'Request invalid -- no request data.',
                          config=self.json_config)
            _logger.warning("Invalid request: %s", fault)
            return fault.dump()

        if isinstance(request, utils.ListType):
            # This SHOULD be a batch, by spec
            responses = []
            for req_entry in request:
                # Validate the request
                result = validate_request(req_entry, self.json_config)
                if isinstance(result, Fault):
                    responses.append(result.dump())
                    continue

                # Call the method
                resp_entry = self._marshaled_single_dispatch(req_entry,
                                                             dispatch_method)

                # Store its result
                if isinstance(resp_entry, Fault):
                    # pylint: disable=E1103
                    responses.append(resp_entry.dump())
                elif resp_entry is not None:
                    responses.append(resp_entry)

            if not responses:
                # No non-None result
                _logger.error("No result in Multicall")
                raise NoMulticallResult("No result")

            return responses

        else:
            # Single call
            result = validate_request(request, self.json_config)
            if isinstance(result, Fault):
                return result.dump()

            # Call the method
            response = self._marshaled_single_dispatch(request,
                                                       dispatch_method)
            if isinstance(response, Fault):
                # pylint: disable=E1103
                return response.dump()

            return response
Exemplo n.º 5
0
    def _marshaled_single_dispatch(self, request, dispatch_method=None):
        """
        Dispatches a single method call
        
        :param request: A validated request dictionary
        :param dispatch_method: Custom dispatch method (for method resolution)
        :return: A JSON-RPC response dictionary, or None if it was a
                 notification request
        """
        # TODO - Use the multiprocessing and skip the response if
        # it is a notification
        method = request.get('method')
        params = request.get('params')
        try:
            # Call the method
            if dispatch_method is not None:
                response = dispatch_method(method, params)
            else:
                response = self._dispatch(method, params)

        except:
            # Return a fault
            exc_type, exc_value, _ = sys.exc_info()
            fault = Fault(-32603, '{0}:{1}'.format(exc_type, exc_value))
            return fault.dump()

        if 'id' not in request or request['id'] in (None, ''):
            # It's a notification, no result needed
            # Do not use 'not id' as it might be the integer 0
            return None

        # Prepare a JSON-RPC dictionary
        try:
            return jsonrpclib.dump(response, rpcid=request['id'],
                                   is_response=True)

        except:
            # JSON conversion exception
            exc_type, exc_value, _ = sys.exc_info()
            fault = Fault(-32603, '{0}:{1}'.format(exc_type, exc_value))
            return fault.dump()
Exemplo n.º 6
0
    def _marshaled_single_dispatch(self, request, dispatch_method=None):
        """
        Dispatches a single method call

        :param request: A validated request dictionary
        :param dispatch_method: Custom dispatch method (for method resolution)
        :return: A JSON-RPC response dictionary, or None if it was a
                 notification request
        """
        method = request.get('method')
        params = request.get('params')

        # Prepare a request-specific configuration
        if 'jsonrpc' not in request and self.json_config.version >= 2:
            # JSON-RPC 1.0 request on a JSON-RPC 2.0
            # => compatibility needed
            config = self.json_config.copy()
            config.version = 1.0
        else:
            # Keep server configuration as is
            config = self.json_config

        # Test if this is a notification request
        is_notification = 'id' not in request or request['id'] in (None, '')
        if is_notification and self.__notification_pool is not None:
            # Use the thread pool for notifications
            if dispatch_method is not None:
                self.__notification_pool.enqueue(dispatch_method,
                                                 method, params)
            else:
                self.__notification_pool.enqueue(self._dispatch,
                                                 method, params, config)

            # Return immediately
            return None
        else:
            # Synchronous call
            try:
                # Call the method
                if dispatch_method is not None:
                    response = dispatch_method(method, params)
                else:
                    response = self._dispatch(method, params, config)
            except Exception as ex:
                # Return a fault
                fault = Fault(-32603, '{0}:{1}'.format(type(ex).__name__, ex),
                              config=config)
                _logger.error("Error calling method %s: %s", method, fault)
                return fault.dump()

            if is_notification:
                # It's a notification, no result needed
                # Do not use 'not id' as it might be the integer 0
                return None

        # Prepare a JSON-RPC dictionary
        try:
            return jsonrpclib.dump(response, rpcid=request['id'],
                                   is_response=True, config=config)
        except Exception as ex:
            # JSON conversion exception
            fault = Fault(-32603, '{0}:{1}'.format(type(ex).__name__, ex),
                          config=config)
            _logger.error("Error preparing JSON-RPC result: %s", fault)
            return fault.dump()
    def _marshaled_single_dispatch(self, request, dispatch_method=None):
        """
        Dispatches a single method call

        :param request: A validated request dictionary
        :param dispatch_method: Custom dispatch method (for method resolution)
        :return: A JSON-RPC response dictionary, or None if it was a
                 notification request
        """
        method = request.get('method')
        params = request.get('params')

        # Prepare a request-specific configuration
        if 'jsonrpc' not in request and self.json_config.version >= 2:
            # JSON-RPC 1.0 request on a JSON-RPC 2.0
            # => compatibility needed
            config = self.json_config.copy()
            config.version = 1.0
        else:
            # Keep server configuration as is
            config = self.json_config

        # Test if this is a notification request
        is_notification = 'id' not in request or request['id'] in (None, '')
        if is_notification and self.__notification_pool is not None:
            # Use the thread pool for notifications
            if dispatch_method is not None:
                self.__notification_pool.enqueue(dispatch_method,
                                                 method, params)
            else:
                self.__notification_pool.enqueue(self._dispatch,
                                                 method, params, config)

            # Return immediately
            return None
        else:
            # Synchronous call
            try:
                # Call the method
                if dispatch_method is not None:
                    response = dispatch_method(method, params)
                else:
                    response = self._dispatch(method, params, config)
            except Exception as ex:
                # Return a fault
                fault = Fault(-32603, '{0}:{1}'.format(type(ex).__name__, ex),
                              config=config)
                _logger.error("Error calling method %s: %s", method, fault)
                return fault.dump()

            if is_notification:
                # It's a notification, no result needed
                # Do not use 'not id' as it might be the integer 0
                return None

        # Prepare a JSON-RPC dictionary
        try:
            return jsonrpclib.dump(response, rpcid=request['id'],
                                   is_response=True, config=config)
        except Exception as ex:
            # JSON conversion exception
            fault = Fault(-32603, '{0}:{1}'.format(type(ex).__name__, ex),
                          config=config)
            _logger.error("Error preparing JSON-RPC result: %s", fault)
            return fault.dump()