Example #1
0
    def decorated_method(self, path, request):

        if request.headers['Accept'] == self.response_type_plain:
            response = ApiAdapterResponse(
                self.response_data_plain,
                content_type=self.response_type_plain, status_code=self.response_code)
        else:
            response = ApiAdapterResponse(
                self.response_data_json,
                content_type=self.response_type_json, status_code=self.response_code)

        return response
Example #2
0
    def put(self, path, request):
        """
        Handle an HTTP PUT request.

        This method handles an HTTP PUT request, returning a JSON response.

        :param path: URI path of request
        :param request: HTTP request object
        :return: an ApiAdapterResponse object with the appropriate response
        """
        content_type = 'application/json'
        status_code = 200
        response = {}
        checkAdapters = True if len(path) > 0 else False
        requestSent = False
        try:
            if checkAdapters:
                for name, adapter in self.adapters.items():
                    if path.startswith(name):

                        relative_path = path.split(name + '/')
                        reply = adapter.put(path=relative_path[1],
                                            request=request)
                        requestSent = True
                        if reply.status_code != 200:
                            status_code = reply.status_code
                            response = reply.data
                            logging.debug(response)
                            return ApiAdapterResponse(
                                response,
                                content_type=content_type,
                                status_code=status_code)

            # Only pass request to Hexitec member if no matching adapter found
            if requestSent is False:
                data = convert_unicode_to_string(decode_request_body(request))
                self.hexitec.set(path, data)
                response = self.hexitec.get(path)
        except HexitecError as e:
            response = {'error': str(e)}
            status_code = 400
        except (TypeError, ValueError) as e:
            response = {
                'error': 'Failed to decode PUT request body: {}'.format(str(e))
            }
            status_code = 400

        logging.debug(response)

        return ApiAdapterResponse(response,
                                  content_type=content_type,
                                  status_code=status_code)
Example #3
0
    def decorated_method(self, path, request):
        """Decorated method having defined request, response and default types."""
        if request.headers['Accept'] == self.response_type_plain:
            response = ApiAdapterResponse(
                self.response_data_plain,
                content_type=self.response_type_plain,
                status_code=self.response_code)
        else:
            response = ApiAdapterResponse(self.response_data_json,
                                          content_type=self.response_type_json,
                                          status_code=self.response_code)

        return response
Example #4
0
    def test_response_with_set_calls(self):

        data = '{\'some_json_value\' : 1.234}'
        content_type = 'application/json'
        status_code = 400

        response = ApiAdapterResponse(data)
        response.set_content_type(content_type)
        response.set_status_code(status_code)

        assert_equal(response.data, data)
        assert_equal(response.content_type, content_type)
        assert_equal(response.status_code, status_code)
Example #5
0
    def put(self, path, request):
        """
        Handle an HTTP PUT request.

        This method handles an HTTP PUT request, returning a JSON response.

        :param path: URI path of request
        :param request: HTTP request object
        :return: an ApiAdapterResponse object containing the appropriate response
        """
        # Update the target specified in the path, or all targets if none specified

        try:
            json_decode(request.body)  # ensure request body is JSON. Will throw a TypeError if not
            if "/" in path:
                path_elem, target_path = path.split('/', 1)
            else:
                path_elem = path
                target_path = ""
            for target in self.targets:
                if path_elem == '' or path_elem == target.name:
                    target.remote_set(target_path, request.body)
            response = self.param_tree.get(path)
            status_code = 200
        except ParameterTreeError as param_tree_err:
            response = {'error': str(param_tree_err)}
            status_code = 400
        except (TypeError, ValueError) as type_val_err:
            response = {'error': 'Failed to decode PUT request body: {}'.format(str(type_val_err))}
            status_code = 415

        return ApiAdapterResponse(response, status_code=status_code)
Example #6
0
    def get(self, path, request):
        """
        Handle an HTTP GET request.

        This method handles an HTTP GET request, returning a JSON response.

        :param path: URI path of request
        :param request: HTTP request object
        :return: an ApiAdapterResponse object containing the appropriate response
        """
        # Update the target specified in the path, or all targets if none specified
        if "/" in path:
            path_elem, target_path = path.split('/', 1)
        else:
            path_elem = path
            target_path = ""
        for target in self.targets:
            if path_elem == '' or path_elem == target.name:
                target.remote_get(target_path)

        # Build the response from the adapter parameter tree
        try:
            response = self.param_tree.get(path)
            status_code = 200
        except ParameterTreeError as param_tree_err:
            response = {'error': str(param_tree_err)}
            status_code = 400

        return ApiAdapterResponse(response, status_code=status_code)
Example #7
0
 def wrapper(_self, *args, **kwargs):
     # Extract version as first argument
     version = args[0]
     subsystem = args[1]
     rem_args = args[2:]
     if version != str(required_version):
         _self.respond(ApiAdapterResponse(
             "API version {} is not supported".format(version),
             status_code=400))
         return wrap_result(None)
     if not _self.route.has_adapter(subsystem):
         _self.respond(ApiAdapterResponse(
             "No API adapter registered for subsystem {}".format(subsystem),
             status_code=400))
         return wrap_result(None)
     return func(_self, subsystem, *rem_args, **kwargs)
Example #8
0
    def get(self, path, request):
        """
        Implementation of the HTTP GET verb for OdinDataAdapter

        :param path: URI path of the GET request
        :param request: Tornado HTTP request object
        :return: ApiAdapterResponse object to be returned to the client
        """
        status_code = 200
        response = {}

        # First check if we are interested in the config items
        #
        # Store these parameters locally:
        # config/hdf/file/path
        # config/hdf/file/name
        # config/hdf/file/extension
        #
        # When this arrives write all params into a single IPC message
        # config/hdf/write
        if path in self._param:
            response['value'] = self._param[path]
        else:
            return super(FrameProcessorAdapter, self).get(path, request)

        return ApiAdapterResponse(response, status_code=status_code)
Example #9
0
    def put(self, path, request):
        """Handle an HTTP PUT request.

        This method handles an HTTP PUT request, returning a JSON response.

        :param path: URI path of request
        :param request: HTTP request object
        :return: an ApiAdapterResponse object containing the appropriate response
        """

        content_type = 'application/json'

        try:
            data = json_decode(request.body)
            self.workshop.set(path, data)
            response = self.workshop.get(path)
            status_code = 200
        except WorkshopError as e:
            response = {'error': str(e)}
            status_code = 400
        except (TypeError, ValueError) as e:
            response = {
                'error': 'Failed to decode PUT request body: {}'.format(str(e))
            }
            status_code = 400

        logging.debug(response)

        return ApiAdapterResponse(response,
                                  content_type=content_type,
                                  status_code=status_code)
Example #10
0
    def get(self, path, request):
        """Handle an HTTP GET request.

        This method handles an HTTP GET request, returning a JSON response. To facilitate
        testing of the background task, if the URI path is set appropriately, the task
        counter is returned in the JSON response.

        :param path: URI path of request
        :param request: HTTP request object
        :return: an ApiAdapterResponse object containing the appropriate response
        """
        if path == 'background_task_count':
            response = {
                'response': {
                    'background_task_count': self.background_task_counter
                }
            }
        else:
            response = {
                'response': 'DummyAdapter: GET on path {}'.format(path)
            }

        content_type = 'application/json'
        status_code = 200

        logging.debug(response)

        return ApiAdapterResponse(response,
                                  content_type=content_type,
                                  status_code=status_code)
Example #11
0
    def put(self, path, request):
        """Handle an HTTP PUT request.
        This method handles an HTTP PUT request routed to the adapter. This decodes the
        JSON body of the request into a dict, and passes the result with the request path, to
        the underlying PSCUData instance set method, where it is parsed and the appropriate
        actions performed on the PSCU.
        :param path: URI path of request
        :param request: HTTP request object
        :return: an ApiAdapterResponse object containing the appropriate response from the PSCU.
        """

        try:
            data = json_decode(request.body)
            self.backplane_data.set(path, data)
            response = self.backplane_data.get(path, False)
            status_code = 200
        except MetadataParameterError as e:
            response = {'error': str(e)}
            status_code = 400
        except (TypeError, ValueError) as e:
            response = {
                'error': 'Failed to decode PUT request body: {}'.format(str(e))
            }
            status_code = 400
        return ApiAdapterResponse(response, status_code=status_code)
Example #12
0
    def put(self, path, request):
        """
        Handle an HTTP PUT request.

        This method handles an HTTP PUT request, returning a JSON response. The request is
        passed to the adapter proxy to set data on the remote targets and resolved into responses
        from those targets.

        :param path: URI path of request
        :param request: HTTP request object
        :return: an ApiAdapterResponse object containing the appropriate response
        """
        # Decode the request body from JSON, handling and returning any errors that occur. Otherwise
        # send the PUT request to the remote target
        try:
            body = decode_request_body(request)
        except (TypeError, ValueError) as type_val_err:
            response = {
                'error':
                'Failed to decode PUT request body: {}'.format(
                    str(type_val_err))
            }
            status_code = 415
        else:
            self.proxy_set(path, body)
            (response, status_code) = self._resolve_response(path)

        return ApiAdapterResponse(response, status_code=status_code)
Example #13
0
    def put(self, path, request):
        """Handle an HTTP PUT request.

        This method is the implementation of the HTTP PUT handler for ExcaliburAdapter/

        :param path: URI path of the PUT request
        :param request: Tornado HTTP request object
        :return: ApiAdapterResponse object to be returned to the client
        """
        try:
            data = json_decode(request.body)
            self.detector.set(path, data)
            response = self.detector.get(path)
            status_code = 200
        except ExcaliburDetectorError as e:
            response = {'error': str(e)}
            status_code = 400
            logging.error(e)
        except (TypeError, ValueError) as e:
            response = {
                'error': 'Failed to decode PUT request body: {}'.format(str(e))
            }
            logging.error(e)
            status_code = 400

        return ApiAdapterResponse(response, status_code=status_code)
Example #14
0
    async def get(self, path, request):
        """Handle an HTTP GET request.

        This method handles an HTTP GET request, returning a JSON response. The parameter tree
        data at the specified path is returned in the response. The underlying tree has a mix of
        sync and async parameter accessors, and GET requests simulate the concurrent operation of
        async adapters by sleeping for specified periods where appropriate.

        :param path: URI path of request
        :param request: HTTP request object
        :return: an ApiAdapterResponse object containing the appropriate response
        """
        try:
            response = await self.param_tree.get(path)
            status_code = 200
        except ParameterTreeError as param_error:
            response = {'error': str(param_error)}
            status_code = 400

        logging.debug("GET on path %s : %s", path, response)
        content_type = 'application/json'

        return ApiAdapterResponse(response,
                                  content_type=content_type,
                                  status_code=status_code)
    def get(self, path, request):
        """Implementation of the HTTP GET verb for MetaListenerAdapter

        :param path: URI path of the GET request
        :param request: Tornado HTTP request object
        :return: ApiAdapterResponse object to be returned to the client

        """
        status_code = 200
        response = {}
        logging.debug("GET path: %s", path)
        logging.debug("GET request: %s", request)

        if path == "config/acquisition_id":
            response["value"] = self.acquisitionID
        elif path == "status/acquisition_active":
            response["value"] = self.acquisition_active
        elif path == "config/acquisitions":
            acquisition_tree = self.traverse_parameters(
                self._clients[0].parameters, ["config", "acquisitions"])
            if acquisition_tree is not None:
                response["value"] = ",".join(acquisition_tree.keys())
            else:
                response["value"] = None
        elif path in self._readback_parameters:
            response["value"] = self._readback_parameters[path]
        elif path in self._config_parameters:
            response["value"] = self._config_parameters[path]
        else:
            return super(MetaListenerAdapter, self).get(path, request)

        return ApiAdapterResponse(response, status_code=status_code)
Example #16
0
    def get(self, path, request):
        """Handle an HTTP GET request.
        This method handles an HTTP GET request routed to the adapter. This passes
        the path of the request to the underlying BackplaneData instance, where it is interpreted
        and returned as a dictionary containing the appropriate parameter tree.
        :param path: URI path of request
        :param request: HTTP request object
        :return: an ApiAdapterResponse object containing the appropriate response from the backplane
        """

        try:
            #Check for metadata argument
            metadata = False
            if "Accept" in request.headers:
                splitted = request.headers["Accept"].split(';')

                if len(splitted) > 1:
                    splitted = splitted[1:]
                    for arg in splitted:
                        if '=' in arg:
                            arg = arg.split('=')
                            if arg[0] == "metadata":
                                metadata = bool(arg[1])

            #Get response
            response = self.backplane_data.get(path, metadata)
            status_code = 200

        except Exception as e:
            #Return the error
            response = {'error': str(e)}
            status_code = 400

        return ApiAdapterResponse(response, status_code=status_code)
Example #17
0
 def dummy_get(self, subsystem, path=''):
     """Dummy HTTP GET verb method to allow the request validation decorator to be tested."""
     response = ApiAdapterResponse(
         {'subsystem': subsystem, 'path': path },
         content_type='application/json',
         status_code=200
     )
     self.respond(response)
Example #18
0
    def test_simple_response(self):
        """Test that a simple rewponse contains the correct default values in fields."""
        data = 'This is a simple response'
        response = ApiAdapterResponse(data)

        assert response.data == data
        assert response.content_type == 'text/plain'
        assert response.status_code == 200
Example #19
0
 def get(self, path, request):
     """
     HTTP Get Request Handler. Return the requested data from the parameter tree
     """
     response = self.param_tree.get(path)
     content_type = 'application/json'
     status = 200
     return ApiAdapterResponse(response, content_type, status)
Example #20
0
    def test_simple_response(self):

        data = 'This is a simple response'
        response = ApiAdapterResponse(data)

        assert_equal(response.data, data)
        assert_equal(response.content_type, 'text/plain')
        assert_equal(response.status_code, 200)
Example #21
0
 def test_handler_respond_valid_json(self, test_base_handler):
     """Test that the base handler respond method handles a valid JSON ApiAdapterResponse."""
     data = {'valid': 'json', 'value': 1.234}
     valid_response = ApiAdapterResponse(data,
                                         content_type="application/json")
     test_base_handler.handler.respond(valid_response)
     assert test_base_handler.handler.get_status() == 200
     assert json.loads(test_base_handler.write_data) == data
Example #22
0
    def put(self, path, request):  # pylint: disable=W0613
        """
        Implementation of the HTTP PUT verb for OdinDataAdapter

        :param path: URI path of the PUT request
        :param request: Tornado HTTP request object
        :return: ApiAdapterResponse object to be returned to the client
        """
        status_code = 200
        response = {}
        logging.debug("PUT path: %s", path)
        logging.debug("PUT request: %s", request)
        logging.debug("PUT request.body: %s",
                      str(escape.url_unescape(request.body)))

        # Clear any errors
        self.clear_error()

        request_command = path.strip('/')

        try:
            # Request should start with config/
            if request_command.startswith("config/"):
                request_command = remove_prefix(
                    request_command, "config/")  # Take the rest of the URI

                # Parse the parameters
                parameters = None
                try:
                    parameters = json.loads(
                        str(escape.url_unescape(request.body)))
                except ValueError:
                    # If the body could not be parsed into an object it may be a simple string
                    parameters = str(escape.url_unescape(request.body))

                # Do not store this configuration if it is the config file
                if not request_command.startswith('config_file'):
                    # Check if the parameter is a dict, and if so then merge.  Otherwise replace the value
                    if request_command in self._config_params:
                        if isinstance(self._config_params[request_command],
                                      dict):
                            self._config_params[request_command].update(
                                parameters)
                        else:
                            self._config_params[request_command] = parameters
                    else:
                        self._config_params[request_command] = parameters
                    logging.debug("Stored config items: %s",
                                  self._config_params)
                response, status_code = self.process_configuration(
                    request_command, parameters)
        except Exception as ex:
            self.set_error(str(ex))
            raise

        return ApiAdapterResponse(response, status_code=status_code)
Example #23
0
    def test_response_with_type_and_code(self):

        data = '{\'some_json_value\' : 1.234}'
        content_type = 'application/json'
        status_code = 400

        response = ApiAdapterResponse(data, content_type=content_type, status_code=status_code)
        assert_equal(response.data, data)
        assert_equal(response.content_type, content_type)
        assert_equal(response.status_code, status_code)
Example #24
0
    def decorated_method_without_default(self, path, request):

        if request.headers['Accept'] == self.response_type_plain:
            response = ApiAdapterResponse(
                self.response_data_plain,
                content_type=self.response_type_plain, status_code=self.response_code)
        elif request.headers['Accept'] == '*/*':
            response = ApiAdapterResponse(
                self.response_data_plain,
                content_type=self.response_type_plain, status_code=self.response_code)
        elif request.headers['Accept'] == self.response_type_json:
            response = ApiAdapterResponse(
                self.response_data_json,
                content_type=self.response_type_json, status_code=self.response_code)
        else:  # pragma: no cover
            response = None
            assert ("Request type decorator failed to trap unknown content type")

        return response
Example #25
0
    def test_handler_respond_invalid_json(self, test_base_handler):
        """
        Test that the base handler respond method raises an ApiError when passed
        an invalid response.
        """
        invalid_response = ApiAdapterResponse(1234,
                                              content_type="application/json")
        with pytest.raises(ApiError) as excinfo:
            test_base_handler.handler.respond(invalid_response)

        assert 'A response with content type application/json must have str or dict data' \
            in str(excinfo.value)
Example #26
0
    def get(self, path, request):
        """
        Handle an HTTP GET request.

        This method handles an HTTP GET request, returning a JSON response.

        :param path: URI path of request
        :param request: HTTP request object
        :return: an ApiAdapterResponse object with the appropriate response
        """
        content_type = "application/json"
        status_code = 200
        response = {}
        request = ApiAdapterRequest(None, accept="application/json")
        # Check adapters if path isn't empty
        #   e.g. If asking for /api/0.1/hexitec/fr/status/frames,
        #                   path = "fr/status/frames"
        #        Compare:      /api/0.1/hexitec/, path = ""
        checkAdapters = True if len(path) > 0 else False
        try:
            if checkAdapters:
                for name, adapter in self.adapters.items():
                    if path.startswith(name):
                        tokens = path.split("/")
                        path = "/".join(tokens[1:])
                        response = adapter.get(path=path, request=request).data
                        logging.debug(response)
                        return ApiAdapterResponse(response,
                                                  content_type=content_type,
                                                  status_code=status_code)

            # No matching adapter found, try Hexitec member:
            response = self.hexitec.get(path)
        except ParameterTreeError as e:
            response = {'error': str(e)}
            status_code = 400

        return ApiAdapterResponse(response,
                                  content_type=content_type,
                                  status_code=status_code)
Example #27
0
 def put(self, path, request):
     """
     HTTP Put Request Handler. Return the requested data after changes were made.
     """
     try:
         data = json_decode(request.body)
         self.param_tree.set(path, data)
         response = self.param_tree.get(path)
         status_code = 200
     except ParameterTreeError as set_err:
         response = {'error': str(set_err)}
         status_code = 400
     return ApiAdapterResponse(response, status_code=status_code)
Example #28
0
    def delete(self, path, request):  # pylint: disable=W0613
        """
        Implementation of the HTTP DELETE verb for OdinDataAdapter

        :param path: URI path of the DELETE request
        :param request: Tornado HTTP request object
        :return: ApiAdapterResponse object to be returned to the client
        """
        response = {'response': '{}: DELETE on path {}'.format(self.name, path)}
        status_code = 501

        logging.debug(response)

        return ApiAdapterResponse(response, status_code=status_code)
    def delete(self, path, request):
        """Handle an HTTP DELETE request.

        This method handles an HTTP DELETE request, returning a JSON response.
        :param path: URI path of request
        :param request: HTTP request object
        :return: an ApiAdapterResponse object containing the appropriate response
        """
        response = 'FileInterfaceAdapter: DELETE on path {}'.format(path)
        status_code = 200

        logging.debug(response)

        return ApiAdapterResponse(response, status_code=status_code)
Example #30
0
    async def put(self, path, request):
        """Handle an HTTP PUT request.

        This method is an abstract implementation of the PUT request handler for AsyncApiAdapter.

        :param path: URI path of resource
        :param request: HTTP request object passed from handler
        :return: ApiAdapterResponse container of data, content-type and status_code
        """
        logging.debug('PUT on path %s from %s: method not implemented by %s',
                      path, request.remote_ip, self.name)
        await asyncio.sleep(0)
        response = "PUT method not implemented by {}".format(self.name)
        return ApiAdapterResponse(response, status_code=400)
Example #31
0
    def test_response_with_type_and_code(self):
        """
        Test that a response with explicit content type and status codes 
        correctly populates the fields.
        """
        data = '{\'some_json_value\' : 1.234}'
        content_type = 'application/json'
        status_code = 400

        response = ApiAdapterResponse(data,
                                      content_type=content_type,
                                      status_code=status_code)
        assert response.data == data
        assert response.content_type == content_type
        assert response.status_code == status_code