def test_get_header_token(self):
        # ensure 'Authorization' header is used if available
        with self.__app.test_request_context(
                '/test', headers={'Authorization': 'Bearer aaa-bbb'}):
            token = UserAuthentication.get_header_token()
        self.assertEqual(token, 'aaa-bbb')

        # ensure 'no_token' is used if 'Authorization' header is not available
        with self.__app.test_request_context('/test'):
            token = UserAuthentication.get_header_token()
        self.assertEqual(token, 'no_token')
    def test_get_x_user_name_header(self):
        # ensure 'X-User-Name' header is used if available
        with self.__app.test_request_context('/test',
                                             headers={'X-User-Name': 'Test'}):
            owner = UserAuthentication.get_x_user_name_header()
        self.assertEqual(owner, 'Test')

        # ensure 'default-owner' is used if 'X-User-Name' header is not available
        with self.__app.test_request_context('/test'):
            owner = UserAuthentication.get_x_user_name_header()
        self.assertEqual(owner, 'default-owner')
    def test_can_modify(self):
        with self.__app.test_request_context('/test',
                                             headers={'X-User-Name': 'Test'}):
            self.assertTrue(
                UserAuthentication.can_modify(FakeSimulation('Test')))
            self.assertFalse(
                UserAuthentication.can_modify(FakeSimulation('default-owner')))

        with self.__app.test_request_context('/test'):
            self.assertFalse(
                UserAuthentication.can_modify(FakeSimulation('Test')))
            self.assertTrue(
                UserAuthentication.can_modify(FakeSimulation('default-owner')))
Exemple #4
0
    def post(self, sim_id):
        """
        Save the current running experiment SDF back to the storage
        :param sim_id: The sim_id
        :param context_id: The context_id of the experiment
        :status 500: Error saving file
        :status 200: Success. File written.
        """
        # pylint: disable=too-many-locals
        simulation = _get_simulation_or_abort(sim_id)

        try:
            rospy.wait_for_service('/gazebo/export_world_sdf', 3)
        except rospy.ROSException as exc:
            raise NRPServicesUnavailableROSService(str(exc))

        dump_sdf_world = rospy.ServiceProxy('/gazebo/export_world_sdf',
                                            ExportWorldSDF)

        try:
            sdf_string = dump_sdf_world().sdf_dump
            tree = ET.fromstring(sdf_string)
            # Erase all robots from the SDF
            robots = simulation.cle.get_simulation_robots()
            for robot in robots:
                for m in tree.findall(".//model[@name='" + robot.robot_id +
                                      "']"):
                    m.getparent().remove(m)
            sdf_string = ET.tostring(tree, encoding='utf8', method='xml')
        except rospy.ServiceException as exc:
            raise NRPServicesClientErrorException(
                "Service did not process request:" + str(exc))

        client = StorageClient()

        # find the sdf world filename from the .exc
        exp_xml_file_path = client.clone_file(
            'experiment_configuration.exc',
            UserAuthentication.get_header_token(), simulation.experiment_id)

        experiment_file = client.parse_and_check_file_is_valid(
            exp_xml_file_path, exp_conf_api_gen.CreateFromDocument,
            exp_conf_api_gen.ExD_)

        world_file_name = experiment_file.environmentModel.src

        client.create_or_update(UserAuthentication.get_header_token(),
                                simulation.experiment_id, world_file_name,
                                sdf_string, "text/plain")

        return 200
Exemple #5
0
 def _check_and_extract_environment_zip(self, experiment):
     """
     Checks for validity and extracts a zipped environment. First we
     make sure that the zip referenced in the experiment exists in the
     list of user environments, then we unzip it on the fly in the temporary
     simulation directory. After the extraction we also make sure to copy
     the sdf from the experiment folder cause the user may have modified it
     :param experiment: The experiment object.
     """
     from hbp_nrp_backend.storage_client_api.StorageClient import StorageClient
     client = StorageClient()
     environments_list = client.get_custom_models(
         UserAuthentication.get_header_token(request),
         self.simulation.ctx_id, 'environments')
     # we use the paths of the uploaded zips to make sure the selected
     # zip is there
     paths_list = [environment['path'] for environment in environments_list]
     # check if the zip is in the user storage
     zipped_model_path = [
         path for path in paths_list
         if experiment.environmentModel.customModelPath in path
     ]
     if len(zipped_model_path):
         environment_path = os.path.join(
             client.get_temp_directory(),
             os.path.basename(experiment.environmentModel.src))
         storage_env_zip_data = client.get_custom_model(
             UserAuthentication.get_header_token(request),
             self.simulation.ctx_id, zipped_model_path[0])
         env_sdf_name = os.path.basename(experiment.environmentModel.src)
         env_path = os.path.join(
             client.get_temp_directory(),
             experiment.environmentModel.customModelPath)
         with open(env_path, 'w') as environment_zip:
             environment_zip.write(storage_env_zip_data)
         with zipfile.ZipFile(env_path) as env_zip_to_extract:
             env_zip_to_extract.extractall(path=client.get_temp_directory())
         # copy back the .sdf from the experiment folder, cause we don't want the one
         # in the zip, cause the user might have made manual changes
         client.clone_file(env_sdf_name,
                           UserAuthentication.get_header_token(request),
                           self.simulation.experiment_id)
     # if the zip is not there, prompt the user to check his uploaded
     # models
     else:
         raise NRPServicesGeneralException(
             "Could not find selected zip %s in the list of uploaded models. Please make\
                 sure that it has been uploaded correctly" %
             (os.path.dirname(experiment.environmentModel.src)),
             "Zipped model retrieval failed")
     return environment_path
Exemple #6
0
    def post(self, sim_id):
        """
        Extends the simulation timeout

        :param sim_id: The simulation id

        :status 404: {0}
        :status 402: Failed to extend the timeout
        :status 412: Failed due to simulation timeout type being 'simulation'
        :status 401: {1}
        :status 200: Success. The simulation timeout has been extended
        """
        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        if simulation.timeout_type == TimeoutType.SIMULATION:
            return {}, 412

        new_timeout = simulation.kill_datetime + \
            datetime.timedelta(minutes=SIMULATION_TIMEOUT_EXTEND)

        if not simulation.cle.extend_simulation_timeout(new_timeout):
            return {}, 402

        simulation.kill_datetime = new_timeout

        return {}, 200
    def _get_brain_info_from_storage(cls, experiment_id, context_id):
        """
        Gathers from the storage the brain script and the populations by getting the BIBI
        configuration file.

        :param experiment_id: the id of the experiment in which to look for the brain information
        :param context_id: the context ID for collab based simulations
        :return: A tuple with the path to the brain file and a list of populations
        """
        del context_id  # Unused

        request_token = UserAuthentication.get_header_token()

        experiment_file = cls.storage_client.get_file(
            request_token, experiment_id, 'experiment_configuration.exc', by_name=True)

        bibi_filename = exp_conf_api_gen.CreateFromDocument(experiment_file).bibiConf.src

        # find the brain filename from the bibi
        bibi_file = cls.storage_client.get_file(
            request_token, experiment_id, bibi_filename, by_name=True)

        bibi_file_obj = bibi_api_gen.CreateFromDocument(bibi_file)
        brain_filename = os.path.basename(bibi_file_obj.brainModel.file)

        brain_filepath = cls.storage_client.clone_file(brain_filename, request_token, experiment_id)

        neurons_config = get_all_neurons_as_dict(bibi_file_obj.brainModel.populations)

        neurons_config_clean = \
            [SimulationResetStorage._get_experiment_population(name, v)
             for (name, v) in neurons_config.iteritems()]

        return brain_filepath, neurons_config_clean, neurons_config
    def reset_from_storage_all(cls, simulation, experiment_id, context_id):
        """
        Reset states machines and transfer functions

        :param: the simulation id
        :param: the experiment id
        :param: the context_id for collab based simulations
        """

        SimUtil.clear_dir(simulation.lifecycle.sim_dir)

        token = UserAuthentication.get_header_token()
        cls.storage_client.clone_all_experiment_files(
            token, experiment_id, destination_dir=simulation.lifecycle.sim_dir)

        with open(simulation.lifecycle.experiment_path) as exc_file:
            exc = exp_conf_api_gen.CreateFromDocument(exc_file.read())

        bibi_path = os.path.join(os.path.dirname(simulation.lifecycle.experiment_path),
                                 exc.bibiConf.src)
        with open(bibi_path) as bibi_file:
            bibi = bibi_api_gen.CreateFromDocument(bibi_file.read())

        cls.reset_brain(simulation, experiment_id, context_id)
        cls.reset_transfer_functions(simulation, bibi, simulation.lifecycle.sim_dir)
        cls.reset_state_machines(simulation, exc, simulation.lifecycle.sim_dir)
Exemple #9
0
    def put(self, sim_id):
        """
        Set the populations of the brain in a simulation with the specified simulation id.

        :param sim_id: The simulation ID

        :< json dict brain_populations: A dictionary indexed by population names and containing
                                             neuron indices

        :< json string brain_type: Type of the brain file ('h5' or 'py')
        :< param brain_populations: Contents of the brain file. Encoding given in field data_type
        :< json string data_type: type of the data field ('text' or 'base64')
        :< json string change_population: indicates if it has to be changes
                                        in the transfer functions
        :> json string message: Error Message if there is a syntax error in the code
        :status 404: {0}
        :status 200: Success. The populations of the brain where successfully set
        """

        simulation = _get_simulation_or_abort(sim_id)
        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        body = request.get_json(force=True)

        result = simulation.cle.set_simulation_populations(
            brain_type=body['brain_type'],
            brain_populations=json.dumps(body['brain_populations']),
            data_type=body['data_type'],
            change_population=body['change_population'])

        if result.message:
            return {'error_message': result.message}, 400

        return {'message': 'Success'}, 200
    def put(self, sim_id):
        """
        Puts the structured transfer functions

        :param sim_id: The simulation id

        :status 500: Simulation in state [STATE]. Can't update transfer function
        :status 404: {0}
        :status 401: {1}
        :status 400: {2}
        :status 200: Success. The transfer function was successfully patched
        """
        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.matches_x_user_name_header(
                request, simulation.owner):
            raise NRPServicesWrongUserException()

        transfer_function = json.loads(request.data, object_hook=JSONObject)
        error_message = simulation.cle.set_structured_transfer_function(
            transfer_function)
        if error_message:
            raise NRPServicesTransferFunctionException(
                "Transfer function patch failed: " + error_message + "\n" +
                "Transfer function:\n" + request.data)
        return 200
    def get(self, sim_id):
        """
        Gets the list of robots in the running simulation.
        """
        # pylint: disable=no-self-use
        sim = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_view(sim):
            raise NRPServicesWrongUserException()

        try:
            robots = SimulationRobots.__get_simulation_robots(sim)
        except ROSCLEClientException as e:
            raise NRPServicesGeneralException(str(e), 'CLE error', 500)

        result = {
            'robots': [{
                ParamNames.ROBOT_ID:
                robot.robot_id,
                ParamNames.ROBOT_ABS_PATH:
                robot.robot_model,
                ParamNames.IS_CUSTOM:
                robot.is_custom,
                ParamNames.ROBOT_POSE:
                SimulationRobots.__jsonisePose(robot.pose)
            } for robot in robots]
        }
        return result, 200
    def delete(self, sim_id, robot_id):
        """
        Delete a robot from the simulation.

        :param sim_id: The simulation ID.
        :param robot_id: The robot ID.

        :status 500: {0}
        :status 404: {1}
        :status 401: {2}
        :status 400: Invalid request, the JSON parameters are incorrect
        :status 200: The requested robot was deleted successfully
        """
        # pylint: disable=no-self-use
        sim = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_modify(sim):
            raise NRPServicesWrongUserException()
        try:
            res, err = SimulationRobot.__delete_robot(sim, robot_id)

        except ROSCLEClientException as e:
            raise NRPServicesGeneralException(str(e), 'CLE error', 500)
        if not res:
            return {'res': err}, 404
        return {'res': 'success'}, 200
Exemple #13
0
    def post(self, sim_id):
        """
        Extends the simulation timeout

        :param sim_id: The simulation id

        :status 404: {0}
        :status 402: Failed to extend the timeout
        :status 401: {1}
        :status 200: Success. The simulation timeout has been extended
        """
        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.matches_x_user_name_header(
                request, simulation.owner):
            raise NRPServicesWrongUserException()

        new_timeout = simulation.kill_datetime + \
            datetime.timedelta(minutes=SIMULATION_TIMEOUT_EXTEND)

        if not simulation.cle.extend_simulation_timeout(new_timeout):
            return {}, 402

        simulation.kill_datetime = new_timeout

        return {}, 200
    def post(self, sim_id, command):
        """
        Issue user commands to the simulator recorder. See parameter description for
        supported query commands.

        :param sim_id: The simulation ID to command.
        :param command: The command to issue, supported: [start, stop, cancel, reset, save]

        :status 500: {0}
        :status 404: {1}
        :status 401: {2}
        :status 400: The command is invalid/refused by recorder - see message returned.
        :status 200: Success. The command was issued.
        """

        # validate simulation id
        sim = _get_simulation_or_abort(sim_id)

        # only the simulation owner can command the recorder
        if not UserAuthentication.can_modify(sim):
            raise NRPServicesWrongUserException()

        # pure local command to save file to storage
        if command == 'save':
            try:
                file_name = sim.lifecycle.save_record_to_user_storage()
                return {'filename': file_name}, 200

            except Exception as e:
                raise NRPServicesClientErrorException(
                    'Cannot copy record to client storage', error_code=404)

        else:

            # validate the remote command type
            valid_commands = {
                'start': SimulationRecorderRequest.START,
                'stop': SimulationRecorderRequest.STOP,
                'cancel': SimulationRecorderRequest.CANCEL,
                'reset': SimulationRecorderRequest.RESET
            }
            if command not in valid_commands:
                raise NRPServicesClientErrorException(
                    'Invalid recorder command: %s' % command, error_code=404)

            # command the recorder, if unsuccessful return the error message
            try:
                resp = sim.cle.command_simulation_recorder(
                    valid_commands[command])

                # check the command success, on failure return status 400 + error
                if not resp.value:
                    raise NRPServicesClientErrorException(resp.message)

                # successful, return status 200
                return 'success', 200

            # internal CLE ROS error if service call fails, notify frontend
            except ROSCLEClientException as e:
                raise NRPServicesGeneralException(str(e), 'CLE error', 500)
    def put(self, sim_id):
        """
        Sets the simulation with the given name into a new state. Allowed values are:
        created, initialized, started, paused, stopped

        :param sim_id: The simulation id

        :< json string state: The state of the simulation to set

        :> json string state: The state of the simulation

        :status 404: {0}
        :status 401: {1}
        :status 400: The state transition is invalid
        :status 200: The state of the simulation with the given ID was successfully set
        """
        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        body = request.get_json(force=True)
        try:
            simulation.state = body['state']
        except MachineError:
            raise NRPServicesStateException("Invalid transition (" +
                                            simulation.state + "->" +
                                            body['state'] + ")")
        return {'state': str(simulation.state)}, 200
    def test_can_view(self):

        sim = FakeSimulation('Test')
        with self.__app.test_request_context('/test'):
            # UserAuthentication.NO_TOKEN should return False
            self.assertFalse(UserAuthentication.can_view(sim))

        with self.__app.test_request_context(
                '/test', headers={'Authorization': 'bearer my_token'}):
            with patch(
                    "hbp_nrp_backend.simulation_control.__BackendSimulationLifecycle.UserAuthentication.client"
            ) as client:
                client.can_acess_experiment = MagicMock(return_value=True)
                # If failed to 'can_acess_experiment', it should default to false
                client.can_acess_experiment.side_effect = Exception('Test')
                self.assertFalse(UserAuthentication.can_view(sim))
Exemple #17
0
    def put(self, sim_id):
        """
        Change the material of a given visual. Currently, only the change of screen materials is
        implemented

        :param sim_id: The simulation ID

        :< json string visual_path: The path to the visual for which a change in material is
                                    requested
        :< json string material_name: The name of the material that will be applied

        :status 404: {0}
        :status 401: {1}
        :status 400: The parameters are invalid
        :status 200: Material applied successfully
        """
        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.matches_x_user_name_header(
                request, simulation.owner):
            raise NRPServicesWrongUserException()

        body = request.get_json(force=True)
        if 'visual_path' not in body:
            return "No visual_path given", 400
        if 'material' not in body:
            return "No material given", 400

        return self.__set_material(body['visual_path'], body['material'])
Exemple #18
0
    def get(self, sim_id):
        """
        Gets the simulation with the specified simulation id

        :param sim_id: The simulation id

        :> json string state: The current state of the simulation
        :> json integer simulationID: The id of the simulation (needed for further REST calls)
        :> json string environmentConfiguration: Path and name of the environment configuration file
        :> json string owner: The simulation owner (Unified Portal user id or 'hbp-default')
        :> json string creationDate: Date of creation of this simulation
        :> json string gzserverHost: Denotes where the simulation will run once started. Set to
                                     'local' for localhost and 'lugano' for a dedicate machine on
                                     the Lugano viz cluster
        :> json string reservation: the name of the cluster reservation subsequently used to
                                    allocate a job
        :> json string experimentID: The experiment ID if the experiment is using the storage
        :> json integer brainProcesses: Number of brain processes to use (overrides ExD conf.)
        :> json string creationUniqueID: unique creation ID (used by Frontend to identify this sim.)

        :status 404: {0}
        :status 401: {1}
        :status 200: The simulation with the given ID is successfully retrieved
        """
        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_view(simulation):
            raise NRPServicesWrongUserException()

        return simulation, 200
    def get(self, sim_id):
        """
        Get brain data of the simulation specified with simulation ID.

        :param sim_id: The simulation ID

        :> json string brain_type: Type of the brain file ('h5' or 'py')
        :> json string data_type: type of the data field ('text' or 'base64')
        :> json string data: Contents of the brain file. Encoding given in field data_type
        :> json dict brain_populations: A dictionary indexed by population names and containing
                                             neuron indices.

        :status 500: {0}
        :status 404: {1}
        :status 401: {2}
        :status 200: Success. The experiment brain file was retrieved
        """

        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_view(simulation):
            raise NRPServicesWrongUserException()

        result = simulation.cle.get_simulation_brain()

        return {
            'data': result.brain_data,
            'brain_type': result.brain_type,
            'data_type': result.data_type,
            'brain_populations': json.loads(result.brain_populations)
        }, 200
    def get(self, sim_id):
        """
        Gets the simulation CSV recorders' content

        :param sim_id: The simulation ID whose transfer functions are retrieved will be saved

        :> json string file: CSV file name
        :> json array data: CSV data as a list of strings

        :status 500: Error when retrieving recorder files
        :status 404: {0}
        :status 401: {1}
        :status 200: Returns a list of recorded csv files and data
        """
        simulation = _get_simulation_or_abort(sim_id)
        if not UserAuthentication.matches_x_user_name_header(
                request, simulation.owner):
            raise NRPServicesWrongUserException()

        response = []
        csv_files = simulation.cle.get_simulation_CSV_recorders_files()
        if csv_files:
            for csv_file in csv_files:
                file_data = []
                response.append({"file": csv_file.name, "data": file_data})
                with open(csv_file.temporary_path) as csvfile:
                    spamreader = csv.reader(csvfile,
                                            delimiter=' ',
                                            quotechar='|')
                    for row in spamreader:
                        file_data.append(', '.join(row))

        return response, 200
    def put(self, sim_id, transfer_function_name, activate):
        """

        Sets the activation state of the transfer function

        :param sim_id: The simulation ID
        :param transfer_function_name: The name of the transfer function to be modified
        :param activate A boolean denoting the new desired activation status

        :status 404: {0}
        :status 401: {1}
        :status 400: {2}
        :status 200: Success. The activation state of the TF has been successfully changed

        """

        simulation = _get_simulation_or_abort(sim_id)
        if not UserAuthentication.matches_x_user_name_header(
                request, simulation.owner):
            raise NRPServicesWrongUserException()

        activate_bool = activate.lower(
        ) == "true"  # convert unicode to boolean

        error_message = simulation.cle.activate_simulation_transfer_function(
            transfer_function_name, activate_bool)

        if error_message:
            raise NRPServicesTransferFunctionException(
                "Transfer function (de-)activation failed: " + error_message +
                "\n")

        return 200
Exemple #22
0
    def delete(self, sim_id, state_machine_name):
        """
        Delete a state machine

        :param sim_id: The simulation ID
        :param state_machine_name: The name of the state machine to be deleted

        :status 500: {0}
        :status 404: {1}
        :status 401: {2}
        :status 200: The delete operation was successfully called. This does not imply that the
                     state machine function was correctly deleted though.
        """
        simulation = _get_simulation_or_abort(sim_id)
        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        failure_message = "State machine destruction failed: "
        try:
            ok, response_message = simulation.delete_state_machine(
                state_machine_name)
            if ok:
                return "Success. The state machine was successfully deleted.", 200
        except Exception as e:
            info = exc_info()
            raise NRPServicesGeneralException(
                failure_message +
                " {0}: {1}".format(e.__class__.__name__, e.message),
                "State machine error",
            ), None, info[2]
        raise NRPServicesStateMachineException(
            failure_message + "\n" + response_message, 404)
Exemple #23
0
    def put(self, sim_id, transfer_function_name):
        """
        Applies user changes to transfer function code

        :param sim_id: The simulation ID
        :param transfer_function_name: The name of the transfer function to be modified

        :< string data: The source code of the transfer function

        :status 404: {0}
        :status 403: {1}
        :status 401: {2}
        :status 400: {3}
        :status 200: Success. The transfer function was successfully patched
        """
        simulation = _get_simulation_or_abort(sim_id)
        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        transfer_function_source = request.data
        error_message = simulation.cle.edit_simulation_transfer_function(
            transfer_function_name, transfer_function_source)

        if error_message:
            ex_msg = ("Transfer Function patch failed: {error_msg}\n"
                      "Updated source:\n"
                      "{tf_src}").format(error_msg=error_message,
                                         tf_src=str(transfer_function_source))
            raise NRPServicesDuplicateNameException(ex_msg) if "duplicate" in error_message \
                else NRPServicesTransferFunctionException(ex_msg)

        return 200
    def put(self, sim_id, transfer_function_name):
        """
        Applies user changes to transfer function code

        :param sim_id: The simulation ID
        :param transfer_function_name: The name of the transfer function to be modified

        :< string data: The source code of the transfer function

        :status 404: {0}
        :status 403: {1}
        :status 401: {2}
        :status 400: {3}
        :status 200: Success. The transfer function was successfully patched
        """
        simulation = _get_simulation_or_abort(sim_id)
        if not UserAuthentication.matches_x_user_name_header(
                request, simulation.owner):
            raise NRPServicesWrongUserException()

        transfer_function_source = request.data
        error_message = simulation.cle.edit_simulation_transfer_function(
            transfer_function_name, transfer_function_source)

        if error_message and "duplicate" in error_message:
            raise NRPServicesDuplicateNameException(
                "Transfer function patch failed: " + error_message + "\n" +
                "Updated source:\n" + str(transfer_function_source))
        elif error_message:
            raise NRPServicesTransferFunctionException(
                "Transfer function patch failed: " + error_message + "\n" +
                "Updated source:\n" + str(transfer_function_source))
        return 200
Exemple #25
0
    def post(self, sim_id):
        """
        Adds a new transfer function

        :param sim_id: The simulation ID

        :< string data: The source code of the transfer function

        :status 404: {0}
        :status 403: {1}
        :status 401: {2}
        :status 400: {3}
        :status 200: Success. The transfer function was successfully added
        """
        simulation = _get_simulation_or_abort(sim_id)
        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        transfer_function_source = request.data

        error_message = simulation.cle.add_simulation_transfer_function(
            transfer_function_source)
        if error_message:
            ex_msg = ("Adding a new Transfer Function failed: {error_msg}\n"
                      "Updated source:\n"
                      "{tf_src}").format(error_msg=error_message,
                                         tf_src=str(transfer_function_source))
            raise NRPServicesDuplicateNameException(ex_msg) if "duplicate" in error_message \
                else NRPServicesTransferFunctionException(ex_msg)

        return 200
Exemple #26
0
    def get(self, sim_id):
        """
        Gets all transfer functions (robot to neuron and neuron to robot) in a dictionary with
        string values.

        :param sim_id: The simulation ID

        :> json dict data: Dictionary containing all transfer functions ('name': 'source')
        :> json dict active: Dictionary containing a mask for active TFs ('name': 'isActive')

        :status 404: {0}
        :status 401: {1}
        :status 200: Transfer functions retrieved successfully
        """

        simulation = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_view(simulation):
            raise NRPServicesWrongUserException()

        transfer_functions = dict()
        active_tfs_mask = dict()

        transfer_functions_list, active_tfs_mask_list = \
            simulation.cle.get_simulation_transfer_functions()

        for tf, tf_active in zip(transfer_functions_list,
                                 active_tfs_mask_list):
            name = get_tf_name(tf)
            transfer_functions[name] = tf
            active_tfs_mask[name] = tf_active

        return dict(data=transfer_functions, active=active_tfs_mask), 200
    def put(self, sim_id, experiment_id):
        """
        Calls the CLE for resetting a given simulation to the last saved state in the storage.

        :param sim_id: The simulation ID.
        :param experiment_id: The experiment ID

        :> json resetType: the reset type the user wants to be performed, details about possible
                          values are given in
                          GazeboRosPackages/src/cle_ros_msgs/srv/ResetSimulation.srv

        :status 500: {0}
        :status 404: {1}
        :status 401: {2}
        :status 400: Invalid request, the JSON parameters are incorrect
        :status 200: The requested reset was performed successfully
        """
        sim = _get_simulation_or_abort(sim_id)

        if not UserAuthentication.can_modify(sim):
            raise NRPServicesWrongUserException()

        req_body = request.get_json(force=True)
        context_id = req_body.get('contextId', None)

        for missing_par in (par for par in self.ResetRequest.required if par not in req_body):
            raise NRPServicesClientErrorException('Missing parameter {}'.format(missing_par))

        for invalid_p in (par for par in req_body if par not in self.ResetRequest.resource_fields):
            raise NRPServicesClientErrorException('Invalid parameter {}'.format(invalid_p))

        reset_type = req_body.get('resetType')

        rsr = srv.ResetSimulationRequest

        try:
            if reset_type == rsr.RESET_ROBOT_POSE:
                sim.cle.reset(reset_type)
            elif reset_type == rsr.RESET_WORLD:
                sim.cle.reset(reset_type,
                              world_sdf=self._get_sdf_world_from_storage(experiment_id, context_id))
            elif reset_type == rsr.RESET_FULL:
                brain_path, populations, _ = \
                    self._get_brain_info_from_storage(experiment_id, context_id)

                if sim.playback_path is None:
                    self.reset_from_storage_all(sim, experiment_id, context_id)

                sim.cle.reset(reset_type,
                              world_sdf=self._get_sdf_world_from_storage(experiment_id, context_id),
                              brain_path=brain_path,
                              populations=populations)
            else:
                return {}, 400  # Other reset modes are unsupported

        except ROSCLEClientException as e:
            raise NRPServicesGeneralException(str(e), 'CLE error', 500)

        return {}, 200
    def put(self, sim_id):
        """
        Set brain file of the simulation specified with simulation ID.
        Depending on the type of brain file, it has to be transmitted as text or as base64
        :param sim_id: The simulation ID

        :< json string brain_type: Type of the brain file ('h5' or 'py')
        :< json string data_type: type of the data field ('text' or 'base64')
        :< json string data: Contents of the brain file. Encoding given in field data_type
        :< json dict brain_populations: A dictionary indexed by population names and containing
                                        neuron indices
        :> json string error_message: Error Message if there is a syntax error in the code
        :> json int error_line: Line of code, where error occurred
        :> json int error_column: Column, where error occurred (if available)
        :> json bool handle_population_change: a flag indicating if user wants to change transfer
                                               functions according to population changes.

        :status 500: {0}
        :status 404: {1}
        :status 401: {2}
        :status 400: {3}
        :status 200: Success. The experiment brain file was replaced
        """

        simulation = _get_simulation_or_abort(sim_id)
        storage_client = StorageClient()
        if not UserAuthentication.can_modify(simulation):
            raise NRPServicesWrongUserException()

        body = request.get_json(force=True)

        file_url = body.get('urls', {}).get('fileUrl')
        if file_url:
            # TODO: fix server certificate and remove verify
            with requests.get(file_url, verify=False) as h5:
                filename = os.path.basename(file_url)
                with open(os.path.join(simulation.lifecycle.sim_dir, filename),
                          'w') as f:
                    f.write(h5.content)
                storage_client.create_or_update(simulation.token,
                                                simulation.experiment_id,
                                                filename, h5.content,
                                                "text/plain")

        result = simulation.cle.set_simulation_brain(
            brain_type=body['brain_type'],
            data=body['data'],
            data_type=body['data_type'],
            brain_populations=json.dumps(body['brain_populations']))

        if result.error_message:
            # Error in given brain
            return {
                'error_message': result.error_message,
                'error_line': result.error_line,
                'error_column': result.error_column
            }, 400
        # Success
        return {'message': "Success"}, 200
    def test_matches_x_user_name_header(self):
        with self.__app.test_request_context('/test',
                                             headers={'X-User-Name': 'Test'}):
            self.assertTrue(
                UserAuthentication.matches_x_user_name_header(
                    flask.request, 'Test'))
            self.assertFalse(
                UserAuthentication.matches_x_user_name_header(
                    flask.request, 'default-owner'))

        with self.__app.test_request_context('/test'):
            self.assertFalse(
                UserAuthentication.matches_x_user_name_header(
                    flask.request, 'Test'))
            self.assertTrue(
                UserAuthentication.matches_x_user_name_header(
                    flask.request, 'default-owner'))
 def test_get_user(self):
     with self.__app.test_request_context('/test',
                                          headers={'X-User-Name': 'Test'}):
         self.assertEqual(UserAuthentication.get_user(), 'Test')
     with self.__app.test_request_context('/test', headers={}):
         self.assertEqual(UserAuthentication.get_user(), 'default-owner')
     with self.__app.test_request_context('/test',
                                          headers={
                                              'Authorization':
                                              'bearer my_incorrect_token'
                                          }):
         self.assertEqual(UserAuthentication.get_user(), 'default-owner')
     with patch(
             "hbp_nrp_backend.simulation_control.__BackendSimulationLifecycle.UserAuthentication.client"
     ) as client:
         client.get_user = MagicMock(return_value={'id': 'myid'})
         with self.__app.test_request_context(
                 '/test', headers={'Authorization': 'bearer my_token'}):
             self.assertEqual(UserAuthentication.get_user(), 'myid')