def get_task(task_identifier, user=None): """Take a task from the queue # noqa: E501 :param task_identifier: :type task_identifier: str :rtype: TaskDetailed """ try: session = Database.get_session() try: identifier = int(task_identifier) except ValueError: return Error(code=400, message="Invalid task identifier"), 400 q = session.query(Task).filter( Task.uid == int(identifier)) # type: Query model = q.first() if model: return model.to_swagger_model_detailed(user=user) else: return Error(code=404, message="Task not found"), 404 except Exception as e: return handle_exception(e)
def get_simulation_run(sim_identifier, run_identifier, expand=None, user=None): # noqa: E501 """Get simulation run # noqa: E501 :param sim_identifier: :type sim_identifier: int :param run_identifier: :type run_identifier: int :param expand: :type expand: bool :rtype: SimulationRunDetailed """ try: session = Database.get_session() q = session.query(SimulationRun).filter( SimulationRun.uid == run_identifier) # type: Query model = q.first() if model and model.simulation_id == sim_identifier: return model.to_swagger_model_detailed(user=user, expand=expand) else: return Error(code=404, message="Simulation run not found"), 404 except Exception as e: return handle_exception(e)
def put_task_inner(task_identifier, task, user=None): """Update a task # noqa: E501 :param task_identifier: :type task_identifier: str :param task: The task :type task: dict | bytes :rtype: TaskDetailed """ session = Database.get_session() try: identifier = int(task_identifier) except ValueError: return Error(code=400, message="Invalid task identifier"), 400 q = session.query(Task).filter(Task.uid == int(identifier)) # type: Query model = q.first() # type: Task if model: model.from_swagger_model(task, user=user) session.commit() # Return a fresh copy from the DB q = session.query(Task).filter(Task.uid == model.uid) return q.first().to_swagger_model_detailed(user=user), 200 else: return Error(code=404, message="Task not found"), 404
def delete_simulation(sim_identifier, user=None): # noqa: E501 """Delete simulation # noqa: E501 :param sim_identifier: :type sim_identifier: int :rtype: None """ session = Database.get_session() try: # Check the store q = session.query(Simulation).filter( Simulation.uid == sim_identifier) # type: Query if q.first(): session.delete(q.first()) session.commit() return "", 204 else: return Error(code=404, message="Simulation not found"), 404 except Exception as e: logging.exception("Simulation deletion failed") session.rollback() return Error(code=500, message="Exception occurred"), 500
def delete_simulation_environment(env_name, user=None): # noqa: E501 """Delete simulation # noqa: E501 :param env_name: Name of the simulation environment :type env_name: str :rtype: None """ session = Database.get_session() try: # Check the store q = session.query(SimulationEnvironment).filter( SimulationEnvironment.name == env_name) # type: Query if q.first(): session.delete(q.first()) session.commit() return "", 204 else: return Error(code=404, message="Simulation environment not found"), 404 except Exception as e: logging.exception("Simulation environment deletion failed") session.rollback() return Error(code=500, message="Exception occurred"), 500
def put_simulation_environment(env_name, environment, block_on_existing=None, user=None): # noqa: E501 """Create/update a simulation environment # noqa: E501 :param env_name: Name of the simulation environment :type env_name: str :param environment: Simulation environment :type environment: dict | bytes :rtype: SimulationEnvironmentDetailed """ try: if connexion.request.is_json: environment = SimulationEnvironmentDetailed.from_dict( connexion.request.get_json()) # noqa: E501 session = Database.get_session() q = session.query(SimulationEnvironment).filter( SimulationEnvironment.name == env_name) # type: Query model = SimulationEnvironment() if q.count() == 1: if block_on_existing: return Error(code=1000, message="Already exists."), 400 model = q.first() else: if environment.name != env_name: return Error( code=400, message= "Path and body tag have to be equal for a new environment" ), 400 session.add(model) model.from_swagger_model(environment, user=user) if environment.rosbag_store: q = session.query(RosbagStore).filter( RosbagStore.name == environment.rosbag_store) # type: Query rosbag_store = q.first() if not rosbag_store: return Error(code=400, message="Rosbag store not found"), 400 model.rosbag_store_id = rosbag_store.uid session.commit() return model.to_swagger_model_detailed(user=user) except Exception as e: return handle_exception(e)
def list_queue(limit=None, offset=None, ordering=None, running=None, finished=None, queued=None, user=None): """List task queue # noqa: E501 :rtype: List[TaskSummary] """ try: session = Database.get_session() q = session.query(Task) #type: Query filters = [] if running: filters.append(Task.state == TaskState.Running) if finished: filters.append( or_(Task.state == TaskState.Cancelled, Task.state == TaskState.Finished, Task.state == TaskState.CancellationRequested)) if queued: filters.append( or_(Task.state == TaskState.Queued, Task.state == TaskState.Paused)) if len(filters) > 0: q = q.filter(reduce((lambda x, y: or_(x, y)), filters)) q = db_helper.query_pagination_ordering( q, offset, limit, ordering, { 'priority': Task.priority, 'identifier': Task.uid, 'last_updated': Task.last_updated, 'created': Task.created, 'state': Task.state, 'success': Task.success, 'runtime': Task.runtime }) return [p.to_swagger_model_summary(user=user) for p in q] except Exception as e: return handle_exception(e)
def new_simulation_run(sim_identifier, simulation_run, user=None): # noqa: E501 """New simulation run # noqa: E501 :param sim_identifier: :type sim_identifier: int :param simulation_run: Simulation run :type simulation_run: dict | bytes :rtype: SimulationRunDetailed """ try: if connexion.request.is_json: simulation_run = SimulationRunDetailed.from_dict( connexion.request.get_json()) # noqa: E501 session = Database.get_session() # Find the simulation q = session.query(Simulation).filter(Simulation.uid == sim_identifier) simulation = q.first() if not simulation: return Error(code=404, message="Simulation not found"), 404 model = SimulationRun() model.from_swagger_model(simulation_run, user=user) model.simulation_id = simulation.uid if simulation_run.bag_store_name and simulation_run.bag_name: # Find the bag of the run q = session.query(Rosbag).filter( and_(RosbagStore.name == simulation_run.bag_store_name, Rosbag.name == simulation_run.bag_name)) bag = q.first() if not bag: return Error(code=400, message="Bag not found"), 400 model.bag_id = bag.uid model.uid = None session.add(model) session.commit() # Return a fresh copy from the DB q = session.query(SimulationRun).filter(SimulationRun.uid == model.uid) return q.first().to_swagger_model_detailed(user=user), 200 except Exception as e: return handle_exception(e)
def do_task_action(task_identifier, action, task=None, user=None): # noqa: E501 """Perform an action on the task # noqa: E501 :param task_identifier: :type task_identifier: str :param action: Action to perform (cancel/prio_up) :type action: str :param task: The task, required depending on the action :type task: dict | bytes :rtype: TaskDetailed """ try: if connexion.request.is_json and task: task = TaskDetailed.from_dict( connexion.request.get_json()) # noqa: E501 session = Database.get_session() q = session.query(Task).filter( Task.uid == int(task_identifier)) # type: Query model = q.first() # type: Task if not model: return Error(code=404, message="Task not found"), 404 if action == "cancel": if model.state == TaskState.Queued: model.state = TaskState.Cancelled model.last_updated = datetime.datetime.utcnow() session.commit() return model.to_swagger_model_detailed(user) elif action == "cancel_running": if model.state == TaskState.Running: model.state = TaskState.CancellationRequested model.last_updated = datetime.datetime.utcnow() session.commit() return model.to_swagger_model_detailed(user) elif action == "prio_up": Task.task_prio_up(session, model.uid) session.commit() q = session.query(Task).filter(Task.uid == int(task_identifier)) return q.first().to_swagger_model_detailed(user) else: return Error(code=400, message="Unknown action"), 400 except Exception as e: return handle_exception(e)
def list_simulation_environments(user=None): """List available simulation environments # noqa: E501 :rtype: List[SimulationEnvironmentSummary] """ try: session = Database.get_session() q = session.query(SimulationEnvironment) #type: Query return [p.to_swagger_model_summary(user=user) for p in q] except Exception as e: return handle_exception(e)
def put_simulation(sim_identifier, simulation, user=None): # noqa: E501 """Update a simulation # noqa: E501 :param sim_identifier: :type sim_identifier: int :param simulation: Simulation :type simulation: dict | bytes :rtype: SimulationDetailed """ try: if connexion.request.is_json: simulation = SimulationDetailed.from_dict( connexion.request.get_json()) # noqa: E501 if simulation.identifier != sim_identifier: return Error( code=400, message="Body and path identifier are not the same"), 400 session = Database.get_session() q = session.query(Simulation).filter(Simulation.uid == sim_identifier) model = q.first() if not model: return Error(code=404, message="Simulation not found"), 404 q = session.query(SimulationEnvironment).filter( SimulationEnvironment.name == simulation.environment_name) if not q.first(): return Error(code=400, message="Simulation environment '%s' not found" % simulation.environment_name), 400 model.from_swagger_model(simulation, user=user) model.environment_id = q.first().uid session.commit() # Return a fresh copy from the DB q = session.query(Simulation).filter(Simulation.uid == model.uid) return q.first().to_swagger_model_detailed(user=user), 200 except Exception as e: return handle_exception(e)
def dequeue_task_inner(worker_name, tasks, labels, user=None): """Take a task from the queue # noqa: E501 :param worker_name: Name of the worker trying to acquire a task :type worker_name: str :param tasks: Tasks that the worker can do (any or a list of tasks) :type tasks: str :param labels: Labels the worker wants to do :type labels: str :rtype: TaskDetailed """ session = Database.get_session() # First find already assigned not finished tasks q = session.query(Task) # type: Query q = q.filter(Task.assigned_to == worker_name)\ .filter(Task.state < TaskState.Finished)\ .order_by(Task.priority.desc()).limit(1) if q.count(): return q.first().to_swagger_model_detailed(user=user) # Get a list of all tasks that can be done by this worker q = session.query(Task) # type: Query q = q.filter(Task.assigned_to == "")\ .filter(Task.state == TaskState.Queued)\ .order_by(Task.priority.desc()).limit(5) # TODO: Filter label and tasks possible_tasks = [] for possible_task in q: possible_tasks.append(possible_task) for task in possible_tasks: success = Task.task_assignment_query(session, task.uid, worker_name) if success: session.commit() q = session.query(Task).filter(Task.uid == task.uid) return q.first().to_swagger_model_detailed(user=user) return Error(code=204, message="No tasks in the queue"), 204
def new_task(task, user=None): """Create a new task # noqa: E501 :param task: The task :type task: dict | bytes :rtype: TaskDetailed """ try: if connexion.request.is_json: task = TaskDetailed.from_dict( connexion.request.get_json()) # type: TaskDetailed session = Database.get_session() hash = Task.calculate_hash(task.config) q = session.query(Task)\ .filter(Task.state < TaskState.Finished)\ .filter(Task.task == task.task)\ .filter(Task.task_hash == hash) duplicate_task = q.first() if duplicate_task: return Error(code=409, message="Duplicate task, %d, queued" % duplicate_task.uid), 409 model = Task() model.log = "" model.result = {} model.task_hash = hash model.from_swagger_model(task, user=user) model.uid = None session.add(model) session.commit() # Return a fresh copy from the DB q = session.query(Task).filter(Task.uid == model.uid) return q.first().to_swagger_model_detailed(user=user), 200 except Exception as e: return handle_exception(e)
def patch_task(task_identifier, task, user=None): # noqa: E501 """Partial update of task (this only supports a few fields) # noqa: E501 :param task_identifier: :type task_identifier: str :param task: Fields to update :type task: :rtype: TaskDetailed """ session = Database.get_session() try: identifier = int(task_identifier) except ValueError: return Error(code=400, message="Invalid task identifier"), 400 try: q = session.query(Task).filter( Task.uid == int(identifier)) # type: Query model = q.first() if model: changed = False if 'log_append' in task and isinstance(task['log_append'], str): model.log += task['log_append'] changed = True if changed: session.commit() return model.to_swagger_model_detailed(user=user) else: return Error(code=404, message="Task not found"), 404 except Exception as e: return handle_exception(e)
def new_simulation(simulation, trigger=None, user=None): # noqa: E501 """New simulation # noqa: E501 :param simulation: Simulation :type simulation: dict | bytes :rtype: SimulationDetailed """ try: if connexion.request.is_json: simulation = SimulationDetailed.from_dict( connexion.request.get_json()) # noqa: E501 session = Database.get_session() q = session.query(SimulationEnvironment).filter( SimulationEnvironment.name == simulation.environment_name) if not q.first(): return Error(code=400, message="Simulation environment '%s' not found" % simulation.environment_name), 400 model = Simulation() model.from_swagger_model(simulation, user=user) model.environment_id = q.first().uid model.uid = None session.add(model) session.commit() # Return a fresh copy from the DB q = session.query(Simulation).filter(Simulation.uid == model.uid) m = NewSimulationHook.trigger(q.first(), session, trigger, user) return m.to_swagger_model_detailed(user=user), 200 except Exception as e: return handle_exception(e)
def list_simulation_runs(sim_identifier, user=None): # noqa: E501 """List simulation runs # noqa: E501 :param sim_identifier: :type sim_identifier: int :rtype: List[SimulationRunSummary] """ try: session = Database.get_session() q = session.query(Simulation).filter( Simulation.uid == sim_identifier) # type: Query model = q.first() if model: return [p.to_swagger_model_summary(user=user) for p in model.runs] else: return Error(code=404, message="Simulation not found"), 404 except Exception as e: return handle_exception(e)
def list_simulations(limit=None, offset=None, ordering=None, user=None): # noqa: E501 """List simulations # noqa: E501 :rtype: List[SimulationSummary] """ try: session = Database.get_session() q = session.query(Simulation) #type: Query q = db_helper.query_pagination_ordering(q, offset, limit, ordering, { 'created': Simulation.created, 'identifier': Simulation.uid }) return [p.to_swagger_model_summary(user=user) for p in q] except Exception as e: return handle_exception(e)
def get_simulation_environment(env_name, user=None): # noqa: E501 """Get simulation environment # noqa: E501 :param env_name: Name of the simulation environment :type env_name: str :rtype: SimulationEnvironmentDetailed """ try: session = Database.get_session() q = session.query(SimulationEnvironment).filter( SimulationEnvironment.name == env_name) # type: Query model = q.first() if model: return model.to_swagger_model_detailed(user=user) else: return Error(code=404, message="Simulation environment not found"), 404 except Exception as e: return handle_exception(e)