|
@@ -18,9 +18,9 @@ from .._entity._entity_ids import _EntityIds
|
|
|
from .._manager._manager import _Manager
|
|
|
from .._version._version_mixin import _VersionMixin
|
|
|
from ..common._utils import _Subscriber
|
|
|
-from ..common.reason import Reason
|
|
|
from ..common.warn_if_inputs_not_ready import _warn_if_inputs_not_ready
|
|
|
from ..exceptions.exceptions import (
|
|
|
+ InvalidSequence,
|
|
|
InvalidSequenceId,
|
|
|
ModelNotFound,
|
|
|
NonExistingSequence,
|
|
@@ -31,6 +31,8 @@ from ..job._job_manager_factory import _JobManagerFactory
|
|
|
from ..job.job import Job
|
|
|
from ..notification import Event, EventEntityType, EventOperation, Notifier
|
|
|
from ..notification.event import _make_event
|
|
|
+from ..reason._reason_factory import _build_not_submittable_entity_reason
|
|
|
+from ..reason.reason import Reasons
|
|
|
from ..scenario._scenario_manager_factory import _ScenarioManagerFactory
|
|
|
from ..scenario.scenario import Scenario
|
|
|
from ..scenario.scenario_id import ScenarioId
|
|
@@ -48,7 +50,7 @@ class _SequenceManager(_Manager[Sequence], _VersionMixin):
|
|
|
_model_name = "sequences"
|
|
|
|
|
|
@classmethod
|
|
|
- def _delete(cls, sequence_id: SequenceId):
|
|
|
+ def _delete(cls, sequence_id: SequenceId) -> None:
|
|
|
"""
|
|
|
Deletes a Sequence by id.
|
|
|
"""
|
|
@@ -63,7 +65,7 @@ class _SequenceManager(_Manager[Sequence], _VersionMixin):
|
|
|
raise ModelNotFound(cls._model_name, sequence_id)
|
|
|
|
|
|
@classmethod
|
|
|
- def _delete_all(cls):
|
|
|
+ def _delete_all(cls) -> None:
|
|
|
"""
|
|
|
Deletes all Sequences.
|
|
|
"""
|
|
@@ -74,7 +76,7 @@ class _SequenceManager(_Manager[Sequence], _VersionMixin):
|
|
|
Notifier.publish(Event(cls._EVENT_ENTITY_TYPE, EventOperation.DELETION, metadata={"delete_all": True}))
|
|
|
|
|
|
@classmethod
|
|
|
- def _delete_many(cls, sequence_ids: Iterable[str]):
|
|
|
+ def _delete_many(cls, sequence_ids: Iterable[SequenceId]) -> None:
|
|
|
"""
|
|
|
Deletes Sequence entities by a list of Sequence ids.
|
|
|
"""
|
|
@@ -103,7 +105,7 @@ class _SequenceManager(_Manager[Sequence], _VersionMixin):
|
|
|
raise ModelNotFound(cls._model_name, sequence_id) from None
|
|
|
|
|
|
@classmethod
|
|
|
- def _delete_by_version(cls, version_number: str):
|
|
|
+ def _delete_by_version(cls, version_number: str) -> None:
|
|
|
"""
|
|
|
Deletes Sequences by version number.
|
|
|
"""
|
|
@@ -111,14 +113,14 @@ class _SequenceManager(_Manager[Sequence], _VersionMixin):
|
|
|
cls._delete_many(scenario.sequences.values())
|
|
|
|
|
|
@classmethod
|
|
|
- def _hard_delete(cls, sequence_id: SequenceId):
|
|
|
+ def _hard_delete(cls, sequence_id: SequenceId) -> None:
|
|
|
sequence = cls._get(sequence_id)
|
|
|
entity_ids_to_delete = cls._get_children_entity_ids(sequence)
|
|
|
entity_ids_to_delete.sequence_ids.add(sequence.id)
|
|
|
cls._delete_entities_of_multiple_types(entity_ids_to_delete)
|
|
|
|
|
|
@classmethod
|
|
|
- def _set(cls, sequence: Sequence):
|
|
|
+ def _set(cls, sequence: Sequence) -> None:
|
|
|
"""
|
|
|
Save or update a Sequence.
|
|
|
"""
|
|
@@ -137,18 +139,8 @@ class _SequenceManager(_Manager[Sequence], _VersionMixin):
|
|
|
cls._logger.error(f"Sequence {sequence.id} belongs to a non-existing Scenario {scenario_id}.")
|
|
|
raise SequenceBelongsToNonExistingScenario(sequence.id, scenario_id)
|
|
|
|
|
|
- @classmethod
|
|
|
- def _create(
|
|
|
- cls,
|
|
|
- sequence_name: str,
|
|
|
- tasks: Union[List[Task], List[TaskId]],
|
|
|
- subscribers: Optional[List[_Subscriber]] = None,
|
|
|
- properties: Optional[Dict] = None,
|
|
|
- scenario_id: Optional[ScenarioId] = None,
|
|
|
- version: Optional[str] = None,
|
|
|
- ) -> Sequence:
|
|
|
- sequence_id = Sequence._new_id(sequence_name, scenario_id)
|
|
|
-
|
|
|
+ @staticmethod
|
|
|
+ def __get_sequence_tasks(tasks: Union[List[Task], List[TaskId]]) -> List[Task]:
|
|
|
task_manager = _TaskManagerFactory._build_manager()
|
|
|
_tasks: List[Task] = []
|
|
|
for task in tasks:
|
|
@@ -158,11 +150,24 @@ class _SequenceManager(_Manager[Sequence], _VersionMixin):
|
|
|
_tasks.append(_task)
|
|
|
else:
|
|
|
raise NonExistingTask(task)
|
|
|
+ return _tasks
|
|
|
|
|
|
+ @classmethod
|
|
|
+ def _build_sequence(
|
|
|
+ cls,
|
|
|
+ sequence_name: str,
|
|
|
+ tasks: Union[List[Task], List[TaskId]],
|
|
|
+ subscribers: Optional[List[_Subscriber]] = None,
|
|
|
+ properties: Optional[Dict] = None,
|
|
|
+ scenario_id: Optional[ScenarioId] = None,
|
|
|
+ version: Optional[str] = None,
|
|
|
+ ) -> Sequence:
|
|
|
+ sequence_id = Sequence._new_id(sequence_name, scenario_id)
|
|
|
+ _tasks = cls.__get_sequence_tasks(tasks)
|
|
|
properties = properties if properties else {}
|
|
|
properties["name"] = sequence_name
|
|
|
version = version if version else cls._get_latest_version()
|
|
|
- sequence = Sequence(
|
|
|
+ return Sequence(
|
|
|
properties=properties,
|
|
|
tasks=_tasks,
|
|
|
sequence_id=sequence_id,
|
|
@@ -171,10 +176,52 @@ class _SequenceManager(_Manager[Sequence], _VersionMixin):
|
|
|
subscribers=subscribers,
|
|
|
version=version,
|
|
|
)
|
|
|
+
|
|
|
+ @classmethod
|
|
|
+ def _bulk_create_from_scenario(cls, scenario: Scenario) -> Dict[str, Sequence]:
|
|
|
+ _sequences: Dict[str, Sequence] = {}
|
|
|
+
|
|
|
+ for sequence_name, sequence_data in scenario._sequences.items():
|
|
|
+ sequence = cls._create(
|
|
|
+ sequence_name,
|
|
|
+ sequence_data.get(scenario._SEQUENCE_TASKS_KEY, []),
|
|
|
+ sequence_data.get(scenario._SEQUENCE_SUBSCRIBERS_KEY, []),
|
|
|
+ sequence_data.get(scenario._SEQUENCE_PROPERTIES_KEY, {}),
|
|
|
+ scenario.id,
|
|
|
+ scenario.version,
|
|
|
+ )
|
|
|
+ if not isinstance(sequence, Sequence):
|
|
|
+ raise NonExistingSequence(sequence_name, scenario.id)
|
|
|
+ _sequences[sequence_name] = sequence
|
|
|
+
|
|
|
+ Notifier.publish(_make_event(sequence, EventOperation.CREATION))
|
|
|
+
|
|
|
+ return _sequences
|
|
|
+
|
|
|
+ @classmethod
|
|
|
+ def _create(
|
|
|
+ cls,
|
|
|
+ sequence_name: str,
|
|
|
+ tasks: Union[List[Task], List[TaskId]],
|
|
|
+ subscribers: Optional[List[_Subscriber]] = None,
|
|
|
+ properties: Optional[Dict] = None,
|
|
|
+ scenario_id: Optional[ScenarioId] = None,
|
|
|
+ version: Optional[str] = None,
|
|
|
+ ) -> Sequence:
|
|
|
+ task_manager = _TaskManagerFactory._build_manager()
|
|
|
+ _tasks = cls.__get_sequence_tasks(tasks)
|
|
|
+
|
|
|
+ sequence = cls._build_sequence(sequence_name, _tasks, subscribers, properties, scenario_id, version)
|
|
|
+ sequence_id = sequence.id
|
|
|
+
|
|
|
for task in _tasks:
|
|
|
if sequence_id not in task._parent_ids:
|
|
|
task._parent_ids.update([sequence_id])
|
|
|
task_manager._set(task)
|
|
|
+
|
|
|
+ if not sequence._is_consistent():
|
|
|
+ raise InvalidSequence(sequence_id)
|
|
|
+
|
|
|
return sequence
|
|
|
|
|
|
@classmethod
|
|
@@ -264,7 +311,7 @@ class _SequenceManager(_Manager[Sequence], _VersionMixin):
|
|
|
callback: Callable[[Sequence, Job], None],
|
|
|
params: Optional[List[Any]] = None,
|
|
|
sequence: Optional[Sequence] = None,
|
|
|
- ):
|
|
|
+ ) -> None:
|
|
|
if sequence is None:
|
|
|
sequences = cls._get_all()
|
|
|
for pln in sequences:
|
|
@@ -278,7 +325,7 @@ class _SequenceManager(_Manager[Sequence], _VersionMixin):
|
|
|
callback: Callable[[Sequence, Job], None],
|
|
|
params: Optional[List[Any]] = None,
|
|
|
sequence: Optional[Sequence] = None,
|
|
|
- ):
|
|
|
+ ) -> None:
|
|
|
if sequence is None:
|
|
|
sequences = cls._get_all()
|
|
|
for pln in sequences:
|
|
@@ -297,14 +344,14 @@ class _SequenceManager(_Manager[Sequence], _VersionMixin):
|
|
|
Notifier.publish(_make_event(sequence, EventOperation.UPDATE, attribute_name="subscribers"))
|
|
|
|
|
|
@classmethod
|
|
|
- def _is_submittable(cls, sequence: Union[Sequence, SequenceId]) -> Reason:
|
|
|
+ def _is_submittable(cls, sequence: Union[Sequence, SequenceId]) -> Reasons:
|
|
|
if isinstance(sequence, str):
|
|
|
sequence = cls._get(sequence)
|
|
|
|
|
|
if not isinstance(sequence, Sequence):
|
|
|
sequence = str(sequence)
|
|
|
- reason = Reason(sequence)
|
|
|
- reason._add_reason(sequence, cls._build_not_submittable_entity_reason(sequence))
|
|
|
+ reason = Reasons(sequence)
|
|
|
+ reason._add_reason(sequence, _build_not_submittable_entity_reason(sequence))
|
|
|
return reason
|
|
|
|
|
|
return sequence.is_ready_to_run()
|
|
@@ -352,7 +399,7 @@ class _SequenceManager(_Manager[Sequence], _VersionMixin):
|
|
|
return True if cls._get(entity_id) else False
|
|
|
|
|
|
@classmethod
|
|
|
- def _export(cls, id: str, folder_path: Union[str, pathlib.Path], **kwargs):
|
|
|
+ def _export(cls, id: str, folder_path: Union[str, pathlib.Path], **kwargs) -> None:
|
|
|
"""
|
|
|
Export a Sequence entity.
|
|
|
"""
|