[6/7] incubator-ariatosca git commit: ARIA-21 reorder repository sturcutre
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/653365da/aria/orchestrator/workflows/api/task_graph.py -- diff --git a/aria/orchestrator/workflows/api/task_graph.py b/aria/orchestrator/workflows/api/task_graph.py new file mode 100644 index 000..c88d343 --- /dev/null +++ b/aria/orchestrator/workflows/api/task_graph.py @@ -0,0 +1,290 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Task graph. Used by users to build workflows +""" + +from uuid import uuid4 +from collections import Iterable + +from networkx import DiGraph, topological_sort + +from . import task as api_task + + +class TaskNotInGraphError(Exception): +""" +An error representing a scenario where a given task is not in the graph as expected +""" +pass + + +def _filter_out_empty_tasks(func=None): +if func is None: +return lambda f: _filter_out_empty_tasks(func=f) + +def _wrapper(task, *tasks, **kwargs): +return func(*(t for t in [task] + list(tasks) if t), **kwargs) +return _wrapper + + +class TaskGraph(object): +""" +A tasks graph builder. +Build an operations flow graph +""" + +def __init__(self, name): +self.name = name +self._id = str(uuid4()) +self._graph = DiGraph() + +def __repr__(self): +return '{name}(id={self._id}, name={self.name}, graph={self._graph!r})'.format( +name=self.__class__.__name__, self=self) + +@property +def id(self): +""" +Represents the id of the graph +:return: graph id +""" +return self._id + +# graph traversal methods + +@property +def tasks(self): +""" +An iterator on tasks added to the graph +:yields: Iterator over all tasks in the graph +""" +for _, data in self._graph.nodes_iter(data=True): +yield data['task'] + +def topological_order(self, reverse=False): +""" +Returns topological sort on the graph +:param reverse: whether to reverse the sort +:return: a list which represents the topological sort +""" +for task_id in topological_sort(self._graph, reverse=reverse): +yield self.get_task(task_id) + +def get_dependencies(self, dependent_task): +""" +Iterates over the task's dependencies +:param BaseTask dependent_task: The task whose dependencies are requested +:yields: Iterator over all tasks which dependency_task depends on +:raise: TaskNotInGraphError if dependent_task is not in the graph +""" +if not self.has_tasks(dependent_task): +raise TaskNotInGraphError('Task id: {0}'.format(dependent_task.id)) +for _, dependency_id in self._graph.out_edges_iter(dependent_task.id): +yield self.get_task(dependency_id) + +def get_dependents(self, dependency_task): +""" +Iterates over the task's dependents +:param BaseTask dependency_task: The task whose dependents are requested +:yields: Iterator over all tasks which depend on dependency_task +:raise: TaskNotInGraphError if dependency_task is not in the graph +""" +if not self.has_tasks(dependency_task): +raise TaskNotInGraphError('Task id: {0}'.format(dependency_task.id)) +for dependent_id, _ in self._graph.in_edges_iter(dependency_task.id): +yield self.get_task(dependent_id) + +# task methods + +def get_task(self, task_id): +""" +Get a task instance that's been inserted to the graph by the task's id +:param basestring task_id: The task's id +:return: Requested task +:rtype: BaseTask +:raise: TaskNotInGraphError if no task found in the graph with the given id +""" +if not self._graph.has_node(task_id): +raise TaskNotInGraphError('Task id: {0}'.format(task_id)) +data = self._graph.node[task_id] +return data['task'] + +@_filter_out_empty_tasks +def add_tasks(self, *tasks): +""" +Add a task to the graph +:param BaseTask task: The task +
[6/7] incubator-ariatosca git commit: ARIA-21 reorder repository sturcutre
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/653365da/aria/orchestrator/workflows/api/task_graph.py -- diff --git a/aria/orchestrator/workflows/api/task_graph.py b/aria/orchestrator/workflows/api/task_graph.py new file mode 100644 index 000..c88d343 --- /dev/null +++ b/aria/orchestrator/workflows/api/task_graph.py @@ -0,0 +1,290 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Task graph. Used by users to build workflows +""" + +from uuid import uuid4 +from collections import Iterable + +from networkx import DiGraph, topological_sort + +from . import task as api_task + + +class TaskNotInGraphError(Exception): +""" +An error representing a scenario where a given task is not in the graph as expected +""" +pass + + +def _filter_out_empty_tasks(func=None): +if func is None: +return lambda f: _filter_out_empty_tasks(func=f) + +def _wrapper(task, *tasks, **kwargs): +return func(*(t for t in [task] + list(tasks) if t), **kwargs) +return _wrapper + + +class TaskGraph(object): +""" +A tasks graph builder. +Build an operations flow graph +""" + +def __init__(self, name): +self.name = name +self._id = str(uuid4()) +self._graph = DiGraph() + +def __repr__(self): +return '{name}(id={self._id}, name={self.name}, graph={self._graph!r})'.format( +name=self.__class__.__name__, self=self) + +@property +def id(self): +""" +Represents the id of the graph +:return: graph id +""" +return self._id + +# graph traversal methods + +@property +def tasks(self): +""" +An iterator on tasks added to the graph +:yields: Iterator over all tasks in the graph +""" +for _, data in self._graph.nodes_iter(data=True): +yield data['task'] + +def topological_order(self, reverse=False): +""" +Returns topological sort on the graph +:param reverse: whether to reverse the sort +:return: a list which represents the topological sort +""" +for task_id in topological_sort(self._graph, reverse=reverse): +yield self.get_task(task_id) + +def get_dependencies(self, dependent_task): +""" +Iterates over the task's dependencies +:param BaseTask dependent_task: The task whose dependencies are requested +:yields: Iterator over all tasks which dependency_task depends on +:raise: TaskNotInGraphError if dependent_task is not in the graph +""" +if not self.has_tasks(dependent_task): +raise TaskNotInGraphError('Task id: {0}'.format(dependent_task.id)) +for _, dependency_id in self._graph.out_edges_iter(dependent_task.id): +yield self.get_task(dependency_id) + +def get_dependents(self, dependency_task): +""" +Iterates over the task's dependents +:param BaseTask dependency_task: The task whose dependents are requested +:yields: Iterator over all tasks which depend on dependency_task +:raise: TaskNotInGraphError if dependency_task is not in the graph +""" +if not self.has_tasks(dependency_task): +raise TaskNotInGraphError('Task id: {0}'.format(dependency_task.id)) +for dependent_id, _ in self._graph.in_edges_iter(dependency_task.id): +yield self.get_task(dependent_id) + +# task methods + +def get_task(self, task_id): +""" +Get a task instance that's been inserted to the graph by the task's id +:param basestring task_id: The task's id +:return: Requested task +:rtype: BaseTask +:raise: TaskNotInGraphError if no task found in the graph with the given id +""" +if not self._graph.has_node(task_id): +raise TaskNotInGraphError('Task id: {0}'.format(task_id)) +data = self._graph.node[task_id] +return data['task'] + +@_filter_out_empty_tasks +def add_tasks(self, *tasks): +""" +Add a task to the graph +:param BaseTask task: The task +
[6/7] incubator-ariatosca git commit: Aria 21 reorder repository sturcutre
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b1de02ca/aria/orchestrator/workflows/api/task_graph.py -- diff --git a/aria/orchestrator/workflows/api/task_graph.py b/aria/orchestrator/workflows/api/task_graph.py new file mode 100644 index 000..c88d343 --- /dev/null +++ b/aria/orchestrator/workflows/api/task_graph.py @@ -0,0 +1,290 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Task graph. Used by users to build workflows +""" + +from uuid import uuid4 +from collections import Iterable + +from networkx import DiGraph, topological_sort + +from . import task as api_task + + +class TaskNotInGraphError(Exception): +""" +An error representing a scenario where a given task is not in the graph as expected +""" +pass + + +def _filter_out_empty_tasks(func=None): +if func is None: +return lambda f: _filter_out_empty_tasks(func=f) + +def _wrapper(task, *tasks, **kwargs): +return func(*(t for t in [task] + list(tasks) if t), **kwargs) +return _wrapper + + +class TaskGraph(object): +""" +A tasks graph builder. +Build an operations flow graph +""" + +def __init__(self, name): +self.name = name +self._id = str(uuid4()) +self._graph = DiGraph() + +def __repr__(self): +return '{name}(id={self._id}, name={self.name}, graph={self._graph!r})'.format( +name=self.__class__.__name__, self=self) + +@property +def id(self): +""" +Represents the id of the graph +:return: graph id +""" +return self._id + +# graph traversal methods + +@property +def tasks(self): +""" +An iterator on tasks added to the graph +:yields: Iterator over all tasks in the graph +""" +for _, data in self._graph.nodes_iter(data=True): +yield data['task'] + +def topological_order(self, reverse=False): +""" +Returns topological sort on the graph +:param reverse: whether to reverse the sort +:return: a list which represents the topological sort +""" +for task_id in topological_sort(self._graph, reverse=reverse): +yield self.get_task(task_id) + +def get_dependencies(self, dependent_task): +""" +Iterates over the task's dependencies +:param BaseTask dependent_task: The task whose dependencies are requested +:yields: Iterator over all tasks which dependency_task depends on +:raise: TaskNotInGraphError if dependent_task is not in the graph +""" +if not self.has_tasks(dependent_task): +raise TaskNotInGraphError('Task id: {0}'.format(dependent_task.id)) +for _, dependency_id in self._graph.out_edges_iter(dependent_task.id): +yield self.get_task(dependency_id) + +def get_dependents(self, dependency_task): +""" +Iterates over the task's dependents +:param BaseTask dependency_task: The task whose dependents are requested +:yields: Iterator over all tasks which depend on dependency_task +:raise: TaskNotInGraphError if dependency_task is not in the graph +""" +if not self.has_tasks(dependency_task): +raise TaskNotInGraphError('Task id: {0}'.format(dependency_task.id)) +for dependent_id, _ in self._graph.in_edges_iter(dependency_task.id): +yield self.get_task(dependent_id) + +# task methods + +def get_task(self, task_id): +""" +Get a task instance that's been inserted to the graph by the task's id +:param basestring task_id: The task's id +:return: Requested task +:rtype: BaseTask +:raise: TaskNotInGraphError if no task found in the graph with the given id +""" +if not self._graph.has_node(task_id): +raise TaskNotInGraphError('Task id: {0}'.format(task_id)) +data = self._graph.node[task_id] +return data['task'] + +@_filter_out_empty_tasks +def add_tasks(self, *tasks): +""" +Add a task to the graph +:param BaseTask task: The task +
[6/7] incubator-ariatosca git commit: Aria 21 reorder repository sturcutre
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/17510b02/aria/orchestrator/workflows/api/task_graph.py -- diff --git a/aria/orchestrator/workflows/api/task_graph.py b/aria/orchestrator/workflows/api/task_graph.py new file mode 100644 index 000..c88d343 --- /dev/null +++ b/aria/orchestrator/workflows/api/task_graph.py @@ -0,0 +1,290 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +Task graph. Used by users to build workflows +""" + +from uuid import uuid4 +from collections import Iterable + +from networkx import DiGraph, topological_sort + +from . import task as api_task + + +class TaskNotInGraphError(Exception): +""" +An error representing a scenario where a given task is not in the graph as expected +""" +pass + + +def _filter_out_empty_tasks(func=None): +if func is None: +return lambda f: _filter_out_empty_tasks(func=f) + +def _wrapper(task, *tasks, **kwargs): +return func(*(t for t in [task] + list(tasks) if t), **kwargs) +return _wrapper + + +class TaskGraph(object): +""" +A tasks graph builder. +Build an operations flow graph +""" + +def __init__(self, name): +self.name = name +self._id = str(uuid4()) +self._graph = DiGraph() + +def __repr__(self): +return '{name}(id={self._id}, name={self.name}, graph={self._graph!r})'.format( +name=self.__class__.__name__, self=self) + +@property +def id(self): +""" +Represents the id of the graph +:return: graph id +""" +return self._id + +# graph traversal methods + +@property +def tasks(self): +""" +An iterator on tasks added to the graph +:yields: Iterator over all tasks in the graph +""" +for _, data in self._graph.nodes_iter(data=True): +yield data['task'] + +def topological_order(self, reverse=False): +""" +Returns topological sort on the graph +:param reverse: whether to reverse the sort +:return: a list which represents the topological sort +""" +for task_id in topological_sort(self._graph, reverse=reverse): +yield self.get_task(task_id) + +def get_dependencies(self, dependent_task): +""" +Iterates over the task's dependencies +:param BaseTask dependent_task: The task whose dependencies are requested +:yields: Iterator over all tasks which dependency_task depends on +:raise: TaskNotInGraphError if dependent_task is not in the graph +""" +if not self.has_tasks(dependent_task): +raise TaskNotInGraphError('Task id: {0}'.format(dependent_task.id)) +for _, dependency_id in self._graph.out_edges_iter(dependent_task.id): +yield self.get_task(dependency_id) + +def get_dependents(self, dependency_task): +""" +Iterates over the task's dependents +:param BaseTask dependency_task: The task whose dependents are requested +:yields: Iterator over all tasks which depend on dependency_task +:raise: TaskNotInGraphError if dependency_task is not in the graph +""" +if not self.has_tasks(dependency_task): +raise TaskNotInGraphError('Task id: {0}'.format(dependency_task.id)) +for dependent_id, _ in self._graph.in_edges_iter(dependency_task.id): +yield self.get_task(dependent_id) + +# task methods + +def get_task(self, task_id): +""" +Get a task instance that's been inserted to the graph by the task's id +:param basestring task_id: The task's id +:return: Requested task +:rtype: BaseTask +:raise: TaskNotInGraphError if no task found in the graph with the given id +""" +if not self._graph.has_node(task_id): +raise TaskNotInGraphError('Task id: {0}'.format(task_id)) +data = self._graph.node[task_id] +return data['task'] + +@_filter_out_empty_tasks +def add_tasks(self, *tasks): +""" +Add a task to the graph +:param BaseTask task: The task +